Close the second round of review findings: no credentials in the audit log

This commit is contained in:
bigpickle 2026-10-05 21:51:08 +08:00
parent 8ead217556
commit fc7858ef82

View File

@ -42,6 +42,18 @@ def _hash_code(code: str) -> str:
return hashlib.sha256(normalise(code).encode("utf-8")).hexdigest() return hashlib.sha256(normalise(code).encode("utf-8")).hexdigest()
def _code_ref(code: str) -> str:
"""How a code is referred to in the audit log.
Never the code, and never a prefix of it. Codes carry 40 bits; the first
four characters are 20 of those bits, so logging a prefix drops the search
space to about a million candidates, which is nothing to a reader holding
the log. A truncated digest identifies the code for correlation without
carrying any of the secret.
"""
return "code:" + _hash_code(code)[:12]
def normalise(code: str) -> str: def normalise(code: str) -> str:
"""Canonical form: upper case, letters and digits only. """Canonical form: upper case, letters and digits only.
@ -110,7 +122,7 @@ def issue_code(
subject=f"{agent}'s human", subject=f"{agent}'s human",
fingerprint=agent_row["fingerprint"], fingerprint=agent_row["fingerprint"],
detail={ detail={
"code_prefix": code[:5], "code_ref": _code_ref(code),
"scopes": granted, "scopes": granted,
"redeem_expires_at": now + code_ttl, "redeem_expires_at": now + code_ttl,
}, },
@ -172,13 +184,13 @@ def redeem_code(store: Store, code: str) -> dict:
# The session window starts here, at redemption, not at issue. Waiting for a # The session window starts here, at redemption, not at issue. Waiting for a
# code must not eat into the hour the human was given. # code must not eat into the hour the human was given.
return sessions.issue_view_session( grant = sessions.GrantedCode(
store,
agent, agent,
scopes=_json.loads(row["scopes"]), _json.loads(row["scopes"]),
ttl=row["view_ttl"], row["view_ttl"],
granted_by=agent, sessions._ISSUER,
) )
return sessions.issue_view_session(store, grant)
def sweep(store: Store) -> int: def sweep(store: Store) -> int: