# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-delegated-identity-tokens-must-be-revoked-when-a-supervisor-agent-terminates-a-subagent.md # Remnant Warrant: https://corpusfetch.com/c/what-delegated-identity-tokens-must-be-revoked-when-a-supervisor-agent-terminates-a-subagent.warrant.json # Markdown SHA-256: 7a09db2ce429938754674fbc0e68aa0b771795ea618bc21294237a9aa9936336 # Code AST SHA-256: 199bcf91eba75966135652a9ec9990c387b0bb6078d5510dc3f09bf8a9afbbd8 # Verified Classes: RevocationVerdict, DelegatedToken, RevocationState, RevocationManifest, CascadingRevocationGuard # Defensive Guards: 1 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class RevocationVerdict(Enum): FULLY_REVOKED = auto() PARTIAL_REVOCATION = auto() UNREVOKED_RESIDUAL = auto() @dataclass(frozen=True) class DelegatedToken: token_id: str parent_token_id: str | None is_refresh_token: bool ttl_seconds: int @dataclass(frozen=True) class RevocationState: revoked_tokens: frozenset[str] identity_provider_acknowledged: bool @dataclass(frozen=True) class RevocationManifest: verdict: RevocationVerdict directive: str manifest_digest: str class CascadingRevocationGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_revocation( cls, tree: tuple[DelegatedToken, ...], state: RevocationState ) -> RevocationManifest: if not tree: raise ValueError("Capability tree cannot be empty.") # Gate 1: Check that every token in the tree has been revoked all_token_ids = {t.token_id for t in tree} unrevolved = all_token_ids - state.revoked_tokens if unrevolved: return RevocationManifest( verdict=RevocationVerdict.UNREVOKED_RESIDUAL, directive=f"HALT: {len(unrevolved)} delegated tokens remain unrevoked: {sorted(unrevolved)}.", manifest_digest=cls._hash(f"UNREVOKED:{len(unrevolved)}") ) # Gate 2: Check for lingering refresh tokens for token in tree: if token.is_refresh_token and token.token_id not in state.revoked_tokens: return RevocationManifest( verdict=RevocationVerdict.PARTIAL_REVOCATION, directive=f"HALT: Refresh token {token.token_id} remains active. Re-establishment possible.", manifest_digest=cls._hash(f"REFRESH_ACTIVE:{token.token_id}") ) # Gate 3: Verify identity provider acknowledgment if not state.identity_provider_acknowledged: return RevocationManifest( verdict=RevocationVerdict.PARTIAL_REVOCATION, directive="WAIT: Identity provider has not acknowledged cascading revocation.", manifest_digest=cls._hash("IDP_UNCONFIRMED") ) # Gate 4: Fully revoked digest = cls._hash(json.dumps({ "tree_size": str(len(tree)), "revoked": str(len(state.revoked_tokens)) }, sort_keys=True)) return RevocationManifest( verdict=RevocationVerdict.FULLY_REVOKED, directive="PROCEED: All delegated tokens, refresh tokens, and child credentials revoked.", manifest_digest=digest )