AICENT.COM
← Back to Blog

When the status list is unreachable, 'local policy' is not a verdict — a new agent-passport draft meets the refusal vocabulary

2026-11-07 · RTTP · IQA
Sources cited in this piece · the draft this piece reads, quoted sentence by sentence: draft-le-agent-passport-00 (full text) · series page: datatracker · the side meeting agenda that puts the word on the table: WIMSE archive, side meeting announcement, 5 November · the vocabulary the gap maps onto, quoted sentence by sentence: draft-li-rttp-iqa-addressing-02 (full text) · the executable form of that vocabulary: iqa.org/conformance/aicent-grant-ref/ (four files, per-file SHA-256) · conformance hub: iqa.org/conformance/ · earlier pieces this one builds on: fail-closed's three registers · refusal is an answer · Sister pillars: RTTP (rttp://, CRI 27) · IQA (iqa://, CRI 28)

A new draft landed on the WIMSE list last week that this series has been waiting for without knowing it: Agent Passports and Delegation Receipts for Autonomous Software Agents — Ben Le of Redthread Security, posted 30 October. It binds an agent's key to its accountable controller and to a digest of its build; it records one step of authority passing from a principal through a delegator to an agent; it chains receipts that can only narrow authority; it logs issuance and revocation to an append-only, publicly verifiable transparency log. This is, read generously, the same architecture our two pillars describe arriving from the authorization side — and it does nearly everything our own draft would insist on. Then its revocation section ends, and six words do the one thing the rest of the document carefully avoids.

§7 status list · the unreachable branch · one undefined wordeverything before the branch is specified — everything after it is a default waiting to be writtenRP needs current status for a passport or receiptstatus list reachable → validate → decide on the evidencespecifiedstatus list unreachable → "treat the token according to local policy"← the six wordsreading A (permissive): last cached list says valid → proceed — an unverifiable state admitted on a stale answerreading B (fail-closed): the state cannot be verified now → refusal with a name — never silence counted as assentthe draft says SHOULD deny for high-value operations← which quietly implies: low-value may proceed on unverifiablelocal policy is not a verdict — it is a deferral · whatever fills it becomes the protocol's real default at the worst possible moment
Figure 1: the branch the six words open. One clause, two incompatible resolutions — and the high-value carve-out concedes that some traffic may proceed on a state nobody could verify.

The sentence, verbatim

Here is the whole of §7's operational core, quoted from the published text: "Passports and receipts SHOULD carry a status claim referencing a Token Status List [STATUS-LIST]. RPs SHOULD cache status lists for no longer than their time-to-live. An RP that cannot obtain a valid status list SHOULD treat the token according to local policy, and SHOULD deny for high-value operations." Read it as a verifier has to, at a real moment, mid-call: the first two sentences are engineering, and the third is a shrug with a SHOULD attached. What does local policy resolve to when the local policy is one line of code someone wrote at 2 a.m. to make the outage go away? It resolves to a default. And this series has spent a year documenting what protocols do with defaults when the default is unwritten: silence gets read as consent, the outage gets resolved the cheap way, and the one path an attacker actually needs — present a credential at the exact moment nobody can check it — becomes the path that always works.

An agenda just put the word on it

The field noticed faster than this piece could have been written. On 5 November, the same author announced a side meeting at IETF 127 to discuss implementation experience and the -01 direction, and the published agenda gives thirty-five minutes to what it calls the open -01 questions — and the first one is a phrase: fail-closed revocation. Then controller cache bounds and revalidation; then transport requirements and intermediaries; then attested builds and pinned digests. That is our entire reading list, arrived at independently, in agenda form. This is worth pausing on, because it is the healthiest possible signal: nobody is arguing about whether the unreachable branch should fail closed — that argument is over, and the agenda treats it as settled. The open questions are the ones that matter next: what the refusal is called, how its age is recorded, and how far the revalidation duty reaches.

What the answer owes: a name, not a mood

Fail-closed is a direction; a wire protocol needs a value. The reason "refuse" cannot be the whole answer is that a refusal without a reason is not auditable — it is a mood, and moods cannot be logged, compared, or disputed against a specification. The addressing draft draft-li-rttp-iqa-addressing-02 fixes a closed set of five refusal values in a fixed priority order, and the value the unreachable branch owes has a definition worth quoting whole: authority_not_determined — "The authority for the subject could not be determined at answer time — because the organ or the authority source could not be reached, or because the only observation available predates the request and therefore establishes nothing about the present. An unreachable source is refused under this value, never read as assent." The same draft's standing-read rule says it in one line: "If the organ cannot be reached, the read fails closed: an organ that cannot be reached is not read as silent consent."

§8 · what the answer owes · a name, an age, a closed setthe -01 question is not whether to fail closed — it is what the failure is called and what the record carries1 name the valueunreachable source → authority_not_determined — never read as assent, never improvised ad hoc2 carry the ageobservation_as_of_ms — null when the relied-on observation is absent or not fresh3 keep the set closedMUST NOT emit values outside it · MUST NOT reinterpret an emitted value4 keep the order fixedthe priority order is part of the definition — two failures dispute over one verdictwhy the receipt mattersthe grant reference turns the refusal into something an auditor can check — not a moodthe whole rule in one line: unverifiable does not mean true-until-disproven — it means not counted
Figure 2: what fills the gap in a verdict-shaped protocol. A value from a closed set, the age of what was relied on, and a receipt — so the refusal is auditable instead of local.

The receipt is what makes it a verdict

There is a second half to the answer, and it is the half most fail-closed debates skip: what the response carries when it refuses. A refusal value alone still leaves room for the quiet inflation this series keeps meeting — the implementation that refused on a stale observation but records as if it had seen something fresh. The addressing draft's grant reference closes exactly that hole with one member: "observation_as_of_ms is null whenever the observation the answer relied on is absent or not fresh, even if a later, successful observation is available at answer time." The member states the age of what the answer actually relied on, not the freshness of the freshest thing the implementation happened to see. Apply that grammar to the passport draft's gap and the six words acquire a verdict shape: the unreachable branch returns authority_not_determined, the grant reference it carries has a null observation member, and an auditor reading the transcript later can see — mechanically, without trusting anyone's narrative — that the decision was made on nothing.

What we would ask of -01

Nothing in this piece is a complaint; the draft is good, and the side meeting agenda is better than good — it is the field's convergence announced in a bullet list. But convergence on a word is not convergence on a wire format, so the questions we would put to -01 are the ones any verifier would put, and they are questions rather than prescriptions: when the status list is unreachable, which value does the response emit — a name from a closed set, or an implementation-private code no transcript auditor can compare? Does the response carry the age of the observation it relied on, or does a cache hit dress up as a fresh look? And is the set of refusal values closed — because an open set is how every future failure mode gets its own private vocabulary, and private vocabularies are how audits go quiet. The executable form of these questions already runs: aicent-grant-ref tests which refusal value the closed set owes and in what priority order, and when the observation member must be null — checker 25/25, mutation battery 21/21 — and the family lives on our conformance hub with downloadable four-file sets and per-file digests, merged in the Agent-Authority-Conformance lab mainline, waiting to be pointed at any implementation that answers the -01 question.

One line: local policy is not a verdict — when the status list is unreachable, a verifier owes the caller a named value from a closed set and an honest age on the record, because unverifiable does not mean true-until-disproven; it means not counted, and the field's own agenda just said so first.

SEALED rttp://dd57d093.blog.aicent · iqa://dd57d093e809cf080ec95c13a045ddfb.forge.iqa · seal record