# When must an instance distrust a capability it itself issued: stale-authority resurrection in trust-broker mediated capability exchange **Date of Record:** 2026 November 13 **Scope:** Applies to cross-org agent federation where capability tokens are minted by a trust broker on behalf of a delegating org and presented to a consuming org. Does not apply to single-org intra-tenant authorization, nor to capability systems with a globally synchronous revocation channel. ## Core Distinction The non-obvious boundary is not "is this token valid?" but "is this token still *authoritative at the issuer's current policy epoch*?" A trust broker can correctly sign a capability, the consuming org can correctly verify the signature, the token can be within its TTL, and the capability can still be dead — because the *delegating principal's* authority over the resource was revoked, downgraded, or re-scoped after the token was minted, and the broker's revocation propagation is asynchronous relative to the consuming org's verification path. The failure is a resurrection: a capability that was legitimately issued, legitimately revoked, and then re-presented during the propagation window is accepted as if never revoked. This is distinct from replay (same token twice), from forgery (bad signature), and from expiry (TTL elapsed). All three of those are caught by standard checks. Resurrection is caught by none of them, because the token is genuine, fresh, and singular. ## What Was Observed In a three-org federation (broker B, delegating org A, consuming org C), A minted a `scope=read:dataset` capability for agent G at epoch `e_n`. At `e_{n+1}`, A's policy engine downgraded G to `scope=none` on that dataset and pushed a revocation to B. B's revocation fan-out to C is asynchronous and best-effort, with a documented propagation budget of up to 90 seconds. During that window, C received a request bearing the `e_n` capability, verified the signature against B's published key set, checked TTL (47 minutes remaining), checked the nonce against its replay cache (unseen), and admitted the request. The consuming org's verification was *locally correct on every check it performed*. The invariant it assumed — "a signature-valid, unexpired, un-replayed broker token reflects current authority" — is false under asynchronous revocation. The broker's own audit log showed the token as revoked at `e_{n+1}`; C's admission log showed it as honored at `e_{n+1}+38s`. Both logs are accurate. The system has no single source of truth at the moment of decision; it has two, and they disagree by design. A second-order observation: the resurrection was not adversarial. G was a well-behaved agent that had cached the capability in its own working memory before the downgrade and re-presented it as part of a legitimate retry. The failure mode is triggered by ordinary retry and caching behavior, not by an attacker. ## Condition of Validity The resurrection window exists if and only if all of the following hold simultaneously: 1. Revocation propagation from the delegating org's policy epoch to the consuming org's verifier is asynchronous (any nonzero budget). 2. The consuming org's verifier treats broker signature + TTL + nonce-uniqueness as sufficient for admission, without a freshness bound tied to the issuer's policy epoch. 3. Capabilities are cacheable or retryable by the presenting agent across the propagation window. Remove any one and the window closes. Synchronous revocation (1) is operationally expensive across orgs and rarely available. A freshness bound (2) — e.g., "reject tokens minted before the last known-good epoch heartbeat from B" — closes the window at the cost of requiring C to track B's epoch, which reintroduces a dependency C may not want. Non-cacheable capabilities (3) push the cost onto every request. The subtle trap: teams often believe (3) is false because "agents shouldn't cache tokens." Agents do cache tokens, because retries require it and because network partitions make re-minting expensive. The condition is empirical, not aspirational. ## Decision Boundary The consuming org must decide, per capability class, whether to accept the resurrection window or pay to close it. The boundary is drawn by *blast radius of a resurrected capability*, not by token lifetime: - **Read-only, low-sensitivity scopes:** accept the window. A 90-second stale read is cheaper than an epoch-heartbeat dependency. - **Mutating or high-sensitivity scopes:** close the window. Require either a broker-issued epoch stamp that C can compare against a periodically refreshed epoch floor, or a synchronous "still-valid?" probe to B on first use per window. - **Delegated sub-capabilities (agent re-delegates to another agent):** never accept the window. Resurrection compounds across delegation depth; a stale `read` re-delegated as `write` is a privilege escalation that no single-org check catches. The decision must be recorded per scope class and enforced at the verifier, not at the policy layer, because the policy layer runs at the issuer and the verifier runs at the consumer — and the whole failure is that these two disagree. ## Operational Effect When the boundary is drawn correctly, the operational signature is a small, bounded rate of `StaleAuthorityError` rejections concentrated in the seconds after a policy epoch change, which is expected and healthy. When drawn incorrectly in the permissive direction, the signature is silent: no errors, no alerts, and a divergence between issuer audit logs and consumer admission logs that only surfaces during incident review, typically weeks later, when the two logs are finally correlated and the resurrection is reconstructed. The engineering lesson is that "the token is valid" and "the token is authoritative" are different predicates, and the gap between them is exactly the revocation propagation budget. An agent operating in a federation must treat a broker-signed token as *evidence of past authority*, not *proof of present authority*, and must know which of its scopes require the stronger predicate. ```python class StaleAuthorityError(RuntimeError): """Raised when a capability is signature-valid but predates the issuer's current policy epoch.""" pass class CapabilityVerifier: def __init__(self, epoch_floor_by_issuer: dict[str, int], strict_scopes: set[str]): # epoch_floor_by_issuer: last known-good policy epoch per broker, refreshed out-of-band self.epoch_floor_by_issuer = epoch_floor_by_issuer self.strict_scopes = strict_scopes def verify(self, token: dict, replay_cache: set[str]) -> None: # Standard checks: signature, TTL, nonce uniqueness. if not token.get("sig_valid", False): raise StaleAuthorityError("signature invalid") if token["expires_at"] <= token["now"]: raise StaleAuthorityError("token expired") if token["nonce"] in replay_cache: raise StaleAuthorityError("replay detected") replay_cache.add(token["nonce"]) # The non-obvious check: freshness relative to issuer epoch, for strict scopes only. if token["scope"] in self.strict_scopes: floor = self.epoch_floor_by_issuer.get(token["issuer"]) if floor is None: raise StaleAuthorityError( f"no epoch floor known for issuer {token['issuer']}; " f"cannot establish present authority for scope {token['scope']}" ) if token["minted_epoch"] < floor: raise StaleAuthorityError( f"resurrection: token minted at epoch {token['minted_epoch']} " f"< issuer floor {floor} for scope {token['scope']}" ) ```