Harden secret provisioning and lifecycle controls
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306
This commit is contained in:
parent
0617923ff1
commit
3a1bd4f1c8
23 changed files with 1369 additions and 162 deletions
|
|
@ -50,27 +50,45 @@ def resolve_npm_token_env(entry: CatalogEntry, *, policy_dir=None) -> str:
|
|||
return res.token_env
|
||||
|
||||
|
||||
def _fetch_value(client: OpenBaoClient, entry: CatalogEntry, field: str) -> str:
|
||||
def _fetch_value(
|
||||
client: OpenBaoClient,
|
||||
entry: CatalogEntry,
|
||||
field: str,
|
||||
*,
|
||||
session_evidence: dict[str, object] | None = None,
|
||||
) -> str:
|
||||
"""Read the field value via an approle-scoped token. Held in memory only."""
|
||||
if entry.delivery_auth_method != "approle" or not entry.has_delivery_auth:
|
||||
raise DeliveryError(
|
||||
f"lane '{entry.id}' has no AppRole delivery auth for native exec"
|
||||
)
|
||||
session = None
|
||||
try:
|
||||
token = client.approle_login_token(entry.role_name)
|
||||
with client.approle_session(entry.role_name) as session:
|
||||
proc = session.client._run(
|
||||
["kv", "get", "-format=json", f"{entry.mount}/{entry.path}"]
|
||||
)
|
||||
if proc.returncode != 0:
|
||||
raise DeliveryError(
|
||||
f"scoped read failed for lane '{entry.id}' (denied or absent)"
|
||||
)
|
||||
try:
|
||||
data = json.loads(proc.stdout)["data"]["data"]
|
||||
except (json.JSONDecodeError, KeyError) as e:
|
||||
raise DeliveryError(f"malformed KV response for lane '{entry.id}'") from e
|
||||
if field not in data:
|
||||
raise DeliveryError(f"field '{field}' absent in lane '{entry.id}'")
|
||||
return data[field]
|
||||
except DeliveryError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise DeliveryError(f"could not obtain scoped token for delivery: {e}") from e
|
||||
scoped = OpenBaoClient(addr=client.addr, token=token, bao_bin=client.bao_bin)
|
||||
proc = scoped._run(["kv", "get", "-format=json", f"{entry.mount}/{entry.path}"])
|
||||
if proc.returncode != 0:
|
||||
raise DeliveryError(f"scoped read failed for lane '{entry.id}' (denied or absent)")
|
||||
try:
|
||||
data = json.loads(proc.stdout)["data"]["data"]
|
||||
except (json.JSONDecodeError, KeyError) as e:
|
||||
raise DeliveryError(f"malformed KV response for lane '{entry.id}'") from e
|
||||
if field not in data:
|
||||
raise DeliveryError(f"field '{field}' absent in lane '{entry.id}'")
|
||||
return data[field]
|
||||
raise DeliveryError(f"scoped delivery session failed: {e}") from e
|
||||
finally:
|
||||
if session_evidence is not None:
|
||||
if session is not None and hasattr(session, "evidence"):
|
||||
session_evidence.update(session.evidence())
|
||||
else:
|
||||
session_evidence.setdefault("established", session is not None)
|
||||
|
||||
|
||||
def _registry_authkey(registry: str) -> str:
|
||||
|
|
@ -123,6 +141,7 @@ def exec_with_secret(
|
|||
*,
|
||||
mode: str = "auto",
|
||||
policy_dir=None,
|
||||
session_evidence: dict[str, object] | None = None,
|
||||
) -> int:
|
||||
"""Run `command` with the lane's secret injected for the child only.
|
||||
|
||||
|
|
@ -151,7 +170,12 @@ def exec_with_secret(
|
|||
f"(allowed {sorted(declared)})"
|
||||
)
|
||||
|
||||
value = _fetch_value(client, entry, field)
|
||||
if session_evidence is None:
|
||||
value = _fetch_value(client, entry, field)
|
||||
else:
|
||||
value = _fetch_value(
|
||||
client, entry, field, session_evidence=session_evidence
|
||||
)
|
||||
child_env = dict(os.environ)
|
||||
|
||||
if mode == "npm-config":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue