← Research Library

R-16 · 35 min · Technical Paper

Passports for Agents

Published Oct 7, 2026 · last revised Oct 8, 2026

Abstract

Proposals for an agent standard usually start from identification: agents should declare themselves so services can treat them differently from people. Identification tells a service who is calling. It does not tell the service whether to do what the agent asks, which depends on whom the agent acts for, under which rules, on which facts and with whose approval. This paper treats that decision as the problem to standardize. It describes NOMOS-SPEC-007 (chain-of-trust key certificates) and NOMOS-SPEC-008 (Act Binding): an agent presents an Act, a self-verifying package that binds one exact change to sealed institutional rules, signed facts from witnesses certified for those facts, and consents from approvers certified for the required role, and the system that would make the change verifies it locally and commits exactly that change or nothing. We give the threat model, the security properties and their arguments, including a proof that withholding facts cannot produce an authorization. We compare the design with trust management, proof-carrying authorization, XACML and capability tokens, and report an evaluation across two implementations: 29 conformance vectors, 729 derived mutants on which the implementations agree exactly, seven defects found by building a second implementation or by testing the stated properties against the reference, all now fixed, and verification latency of about 1 ms per Act.

R-15 · Engineering Case Study

The Authority Handshake, Built →

The engineering report on NOMOS-SPEC-007, checked against the decomposition R-08 proposed.

R-08 · Position Paper

Bounded Contextual Authority: A Framework for Portable, Machine-Verifiable Authority in Autonomous Systems →

The paper that decomposed the authority handshake and named the missing link SPEC-007 supplies.

R-09 · Design Note

Root Legitimacy for Machine-Executable Institutional Authority →

Who should operate the roots a relying party pins: the open problem in §10.1.

R-13 · Engineering Case Study

Conserved-State Authority, Built →

The budget ledger that acts as a SPEC-008 relying party in production (§9.5).

Concept

1. Introduction

A recent and widely shared argument holds that the most important technology problem of the next five years is a broadly accepted standard for agents to identify themselves to service providers, so that providers can treat agent traffic differently from human traffic. Until such a standard exists, the argument continues, agents will evade detection to stay useful, and that cat-and-mouse game is a stopgap rather than the terminal state.

We agree with the diagnosis and disagree with the target. Identification answers who is calling. A service deciding whether to approve a loan, release a payment or amend a record needs answers to different questions: on whose behalf the agent acts, whether that principal authorized this change, under which rules, on which facts, and with whose approval. Those are questions about authority. A perfectly identified agent can still ask for something its principal never permitted, and a perfectly anonymous one can carry a valid authorization.

The international passport system is a useful reference design. A passport does not prove that its holder is a person. It proves that a recognized issuer vouches for the holder, in a form a stranger can verify offline. The decision to admit the holder is then made at the border, under the border's own rules, on the facts of the case. Vouching, verification and decision are separate, and the system works because they are kept separate (§3).

This paper describes a design with the same separations for autonomous agents acting for institutions. It consists of two specifications. NOMOS-SPEC-007 lets a relying party recognize, offline and against a root it pins itself, the key that issued a set of rules, and the keys certified to state particular facts or to consent in particular roles. NOMOS-SPEC-008 defines the Act: one exact change, together with the sealed rules, the certificates, signed testimony for the facts the rules read, and consents signed over the Act itself. The relying party, meaning the system of record that would apply the change, verifies the Act and commits exactly the change it verified or nothing.

The contributions are:

  • A system model that separates three kinds of authority, namely issuing rules, stating facts and approving acts, and gives each its own key purpose and scope under one certificate system (§4, §5).
  • Per-input fact provenance declared inside the sealed rules, so the institution, not the presenter, decides which party may supply each fact (§6.3).
  • A partial-information semantics for rule evaluation, with a proof that an Act cannot gain an authorization by withholding facts, and the two refinements it depends on in practice: absence decides only where it is authoritative, and a comparison on a value of the wrong kind is undecided rather than false (§6.4, §7.2).
  • Consent bound to a digest over the exact action, rules, facts, audience and nonce (§6.5).
  • Order-independent path resolution for certificate sets that are trees rather than paths (§5.3).
  • An evaluation methodology, cross-implementation conformance vectors plus systematic mutants, and an account of the seven defects it found (§9).

Two questions sit outside the design by construction: root governance, meaning who should operate the roots relying parties pin, and the truthfulness of witnesses. §10 sets out both, with the other boundaries of the design.

2. Why identification is not enough

Suppose every agent declared itself perfectly: each request carries a signature from the operator that runs the agent, as HTTP Message Signatures [6] and the IETF Web Bot Auth work [7] make possible. The service learns that the caller is software and which operator stands behind it. That is useful for traffic management: rate limits, choosing an API over a page, knowing whom to contact. It is not sufficient for consequential actions, for three reasons.

First, the operator is rarely the principal. An agent built by one company may act for a bank, a hospital or an individual. The relevant question is what the principal authorized, and the operator's signature says nothing about it. This is the confused deputy problem [22] at internet scale: a deputy with its own identity and broad access, acting on instructions whose authority it cannot itself establish.

Second, authorization of an action depends on facts that the agent should not be trusted to report. Whether a loan may be approved depends on the applicant's debt-to-income ratio, which a credit bureau knows, and on the applicant's existing obligations, which the lender's own ledger knows. A protocol that lets the agent state those facts evaluates the agent's account of the world rather than the world.

Third, even a correct authorization decision is worthless if it is not tied to the action eventually performed. An approval for $4,000 is not an approval for $400,000 unless something binds it to the amount, the subject and the system where it takes effect.

These are the four ways an agent can obtain an unauthorized effect without breaking any cryptography, which SPEC-008 is designed to close:

  • Skip the check: act through an interface that does not demand an authorization.
  • Lie to the check: supply the facts the rules read.
  • Change the action after the check: present a verdict obtained for one change in support of another.
  • Withhold a fact: omit the statement that would have caused a deny rule to fire.

Identification closes none of them. Each is a property of how the authorization is constructed and where it is verified, not of who sends it.

3. The reference design: machine-readable passports

ICAO Doc 9303 [1] specifies the public key infrastructure behind electronic passports. Each issuing state operates a Country Signing Certification Authority (CSCA). The CSCA certifies Document Signers, and a Document Signer signs the Document Security Object on the passport's chip, which contains hashes of the data groups holding the holder's details. An inspection system verifies the chain from the Document Security Object to a CSCA certificate it already holds. CSCA certificates are exchanged bilaterally or through master lists, and the ICAO Public Key Directory distributes Document Signer certificates and revocation lists.

Three properties of this design carry over directly.

  • Verification is local. The inspection system does not contact the issuing state to check a passport.
  • Trust is pinned by the verifier. Each border decides which CSCAs it recognizes; no global root is imposed.
  • Vouching is separated from decision. The passport establishes who vouches for the holder. Admission is decided by the receiving state's rules, using facts the passport does not contain (a visa, the purpose of travel, a watch list), several of which the receiving state holds itself.

A fourth property is the reason the analogy is useful for agents. The system of record for admission is the border itself, and it is also where enforcement happens. A traveller can present any documents they like, but entry is granted only at the point that checks them. SPEC-008 places verification at the corresponding point for an agent: the system whose state the action would change.

Passport systemThis designSpecified in
Country Signing CA, pinned by the borderRoot key, pinned by the relying partySPEC-007 §4.1
Document Signer certificateKey certificate with scope and expirySPEC-007 §3
Document Security ObjectSeal over the institution's rulesSPEC-001 §8
Visa, watch list, declared purposeTestimony, relying-party state, action parametersSPEC-008 §3, §7
Officer's decision under the border's rulesRelying party evaluates the sealed rulesSPEC-008 §6
Entry stampCommit plus receiptSPEC-008 §8, §9

4. System and threat model

4.1 Parties

  • Root: a key a relying party pins as the origin of trust. No default root exists.
  • Issuer: holds a key certified to seal rules (a .nomos artifact, SPEC-001).
  • Witness: holds a key certified, with claim scope, to state particular facts (for example a credit bureau for credit_score and dti_ratio).
  • Approver: holds a key certified, with consent scope, to approve in particular roles.
  • Presenter: assembles and submits the Act, typically an AI agent. It is untrusted.
  • Relying party: the system of record for the state being changed. It pins its root, knows its own identifier and state, keeps a nonce ledger, verifies, and commits.

4.2 Assumptions

  • A1. Ed25519 [5] is existentially unforgeable under chosen-message attack, and SHA-256 is collision-resistant.
  • A2. The private keys of the pinned root and of every key on a path the relying party accepts are not compromised, or, if compromised, have been revoked and the revocation reached the relying party (§10.4).
  • A3. The relying party implements SPEC-008 §6 to §8 correctly and is the only interface through which the state can be changed (complete mediation [23]).
  • A4. The relying party's clock is within a small bound of real time, relative to Act validity windows of at most five minutes.
  • A5. Witnesses state true facts for the claims they are certified for. This is a trust decision by the certifying institution, which the protocol makes explicit but cannot enforce (§10.2).

4.3 Adversary

The adversary controls the presenter completely and the network between the presenter and everyone else. It may construct arbitrary Acts, replay any message it has observed, reorder or drop certificates and statements, choose any action parameters, and submit to any relying party. It may hold its own certified keys of any purpose, including a legitimate witness or approver key for some other claim or role. It cannot forge signatures under keys it does not hold (A1).

4.4 Goals

If the relying party commits an action, then: (G1) the rules evaluated were sealed by a key that chains to the pinned root with scope admitting them; (G2) every fact the rules read came from the channel the rules declare for it and, if testimony, from a key certified for that claim; (G3) no fact the Act omitted could have caused a higher-ranked deny or escalation rule to fire; (G4) if consent was required, the required number of distinct keys certified for the required role signed this exact action, rules, facts, audience and nonce; (G5) the Act was addressed to this relying party, presented inside its window, and is committed at most once; (G6) the verdict does not depend on the order in which certificates were presented; (G7) a third party holding the Act and the receipt can re-run the verification and obtain the same verdict.

5. Recognizing authority: NOMOS-SPEC-007

5.1 Key certificates and scope

A key certificate is a signed statement by a parent key that a child key may sign within a scope until an expiry. The signed payload is the RFC 8785 [4] canonical form of parent_kid, child_kid, child_public_key_pem, scope, issued_at and expires_at. A kid is derived from the public key it names and the verifier checks the derivation, so a kid identifies exactly one key.

Scope is a set of dimension terms. The artifact dimensions (artifact, industry, jurisdiction) constrain which rule sets a key may seal. Revision 1.8.0 adds two statement dimensions: claim, a set of fact names, and consent, a set of role identifiers. A key's effective scope is accumulated along its path, and every hop must narrow or preserve each dimension its parent constrains. A dimension the verifier does not recognize, or that the artifact does not declare, fails closed. Neither statement dimension admits wildcards.

5.2 Purpose separation

A key whose effective scope contains a claim or consent term is a statement key. A statement key cannot seal rules, and a key with no claim term cannot testify to anything, including a key whose scope is otherwise unrestricted. Unrestricted scope means unrestricted authority to issue rules, not authority to state facts. The consequence is structural: compromise of the issuer's key does not let an attacker manufacture the facts the rules read, and compromise of a witness key does not let it change the rules. An institution that is legitimately a source of some facts, such as an HR system attesting leave balances, receives a separate, claim-scoped key for that purpose.

5.3 Target-first resolution

An Act carries one unordered set of certificates covering the issuer and every witness and approver. That set is a tree, not a path. Version 1.7.0 resolved chains root-first, taking at each step the first certificate whose parent matched. On a tree this is order-dependent: with a root certifying both an issuer and a witness, presenting the witness's certificate first led the walk into a branch with no continuation, and the same certificates produced ALLOWED in one order and ISSUER_NOT_RECOGNIZED in the other. This violated the order-independence invariant the specification already stated. We found it by running the SPEC-008 vectors against a second Python verifier, written by the authors from the 1.7.0 text (§9.4).

Revision 1.8.0 resolves target-first, in the manner of certification path building [3]. To resolve key T, the verifier enumerates candidate paths from T toward the pinned root through certificates whose child is the current key, without revisiting a key and abandoning paths longer than 20 certificates. It tries candidates in ascending order of certificate fingerprint, so the first path tried does not depend on presentation order, and validates each candidate root-first with the unchanged per-certificate, scope and revocation checks. The first path that validates resolves T. For a set that forms a single path, the result equals the 1.7.0 walk.

Enumeration is exponential in the worst case. With twenty duplicated certificates the number of failing candidate paths reached 1,024, and re-verifying shared certificates on each path cost about 700 ms on the platform's public verify endpoint. Because the kid derivation check binds each kid to one key, a certificate's validity against its parent is independent of the path it appears on. Memoizing fingerprints and signature results per resolution leaves the paths, their order and the verdict unchanged and reduced that case to about 8 ms.

5.4 Revocation

Revocation is keyed on the revoked key's kid, not on a particular certificate, so a revoked key is rejected on every path a presenter could construct to it. Certificates can also be revoked individually by fingerprint. A verifier with no revocation source of its own can accept freshness staples, short-lived statements signed by each key's certifying parent, and every verdict discloses its revocation confidence (live, staple or unchecked), reporting the weakest value along the path. Artifact revocation, the issuer withdrawing a sealed rule set, is specified separately in NOMOS-SPEC-006.

6. Binding the action: NOMOS-SPEC-008

6.1 The Act

{
  "act_version": "1", "act_id": "act-7f3c", "nonce": "<128+ bits>",
  "issued_at": "2026-10-01T11:59:00Z", "expires_at": "2026-10-01T12:04:00Z",
  "relying_party": "acme-bank:core-ledger",
  "action": { "type": "approve_loan", "subject": "APP-1042",
              "params": { "amount": 75000, "loan_purpose": "home_improvement" } },
  "authority": { "artifact": { /* sealed rules */ }, "key_certs": [ /* one unordered set */ ] },
  "testimony": [ { "claim": "dti_ratio", "value": 0.31, "about": "APP-1042",
                   "as_of": "…", "valid_until": "…", "kid": "<bureau>", "signature": "…" } ],
  "consents":  [ { "binding_digest": "…", "role": "SENIOR_APPROVER", "decision": "approve",
                   "kid": "<approver>", "signature": "…" } ]
}

An Act has no presenter signature. Who assembled it has no bearing on whether it is legitimate, and a relying party must not let presenter identity affect the verdict. This is deliberate: it makes the security argument independent of the presenter, which is the component least worth trusting.

6.2 Verification

The relying party performs nine steps in order and stops at the first failure: envelope and size limits; audience; validity window; nonce; the issuer's chain, seal and scope (SPEC-007); that the authority is not revoked and is the version in force at verification time; every testimony statement's chain, claim scope, signature, freshness and subject; every fact's channel and type; evaluation of the sealed rules over exactly those facts; and, if the rules escalate, consent counting. An invalid testimony or consent statement rejects the whole Act rather than being dropped: a presenter that includes a forged or stale statement has revealed something about itself.

6.3 Fact channels

Every fact the rules read arrives through exactly one of four channels, and the sealed rules declare the permitted channel of each input:

ChannelSourceControlled by
actionthe Act's action parameters and typethe presenter, but they are exactly what gets committed
testimonysigned statements from certified witnesseswitnesses
relying_partythe relying party's own state at verification timethe system of record
presenterfacts the presenter assertsthe presenter alone

A fact arriving through an undeclared channel, through two channels, or for an input with no declared channel rejects the Act. The action channel deserves comment. The presenter chooses the action's parameters, yet those parameters are trustworthy as facts, because they are exactly what will be committed: a rule that reads amount reads the amount that will move. The presenter channel exists for inputs an institution chooses to accept on the agent's word. It is visible in the sealed rules, so a reviewer can find every such input by reading the data contract.

Each sourced input also declares a type, and a present fact whose value does not have that type rejects the Act (§7.1 of the specification). An Act containing a non-finite number is malformed. Both were added in 0.3.0, for the reasons given in §7.2.

6.4 Three-valued evaluation

Rule conditions are evaluated to TRUE, FALSE or UNDECIDED under Kleene's strong three-valued logic [24]. A fact is absent when no channel supplied it or it was supplied as null. Any comparison or predicate that reads an absent fact is UNDECIDED. exists(f) is TRUE when f is present; when f is absent it is FALSE if f's channel is action or relying_party and UNDECIDED otherwise. Those are the two channels where absence is itself information: the action is exactly what will be committed, and the relying party is reading its own state. A missing witness statement, by contrast, says nothing about the world. Finally, a primitive whose operands are present but outside its domain is also UNDECIDED: an ordering comparison needs two numbers or two strings, == needs two values of the same JSON type, between needs a number, matches a string, and a bare field reference a boolean. A value of the wrong kind says nothing decisive about the condition.

Resolution then runs as in SPEC-001 over the conditions that are TRUE: highest priority wins, ties broken by the artifact's tie-breaker, and the artifact's default outcome (block if absent) applies when nothing matches. Let D be the deciding rule, or none. The commit rule is: if the outcome is allow or escalate, and any block or escalate rule that outranks D is UNDECIDED, the verdict is INCOMPLETE, nothing commits, and consents are not counted. The response names the open rules and the facts that would decide them. The remedy is a new Act carrying testimony for those facts; a bureau that knows an applicant has no active bankruptcy says so explicitly.

6.5 Consent and the binding digest

binding_core = { act_version, act_id, nonce, issued_at, expires_at, relying_party, action,
                  artifact_hash: authority.artifact.seal.hash,
                  testimony_digest: SHA-256(JCS(testimony sorted by JCS encoding)) }
binding_digest = hex(SHA-256(JCS(binding_core)))

An approver signs the binding digest together with a role and a decision. A consent therefore approves one combination of change, rules, facts, audience and nonce, and nothing else. Changing any parameter, substituting a fact, swapping the rules or readdressing the Act invalidates every consent. Consents are counted by distinct key, so the same approval presented twice counts once; a consent for a different role is ignored; and a consent that fails its signature, scope or binding check rejects the Act.

6.6 Commit and receipt

On AUTHORIZED, the relying party applies exactly the verified action, records the nonce in the same atomic operation, and re-reads any relying-party facts inside that operation, aborting if they changed. The last step closes the time-of-check to time-of-use gap for the system's own state. It then writes a receipt that records the verdict, the deciding rule, the binding digest, the verification time and the relying-party facts evaluated. Those last two are the only inputs to the verdict that the Act does not carry.

7. Security analysis

We argue each goal of §4.4 under assumptions A1 to A5.

7.1 Authenticity, provenance, binding, freshness and order

G1 (authentic rules). Step 5 resolves the seal's kid to the pinned root through certificates whose signatures verify, checks the seal's hash over the artifact body and its signature under the resolved key, and checks that the effective scope admits the artifact and contains no statement dimension. Under A1 and A2 an adversary cannot produce a passing artifact other than one the certified issuer sealed. Genuine is not enough: step 5a then requires that the artifact is unrevoked and is the version in force at verification time, from the relying party's own record or an issuer-signed in-force statement valid for at most a day. A superseded version remains valid for verifying decisions made under it and cannot authorize a new one.

G2 (fact provenance). Every evaluated fact is placed into the fact set by one of four code paths, each tagged with its channel, and step 7 rejects any fact whose tag differs from the declared channel or that appears twice. Testimony facts are added only after the statement's key resolves, its effective scope contains a claim term naming that fact, its signature verifies, it is inside its validity window, and its subject matches the action's subject. Purpose separation (§5.2) means the issuer cannot be its own witness. The adversary's own witness keys, certified for other claims, fail the scope check.

G4 (consent binding). A consent is counted only if its signature verifies under a key whose effective scope contains a consent term for the required role, and its binding digest equals the digest the relying party computes from the Act it is verifying. Under A1 the adversary cannot produce such a signature for a digest the approver did not sign; under collision resistance it cannot find a different Act with the same digest. Counting by distinct kid, together with the kid derivation check, means n consents require n distinct keys.

G5 (audience, window, single use). Steps 2 to 4 reject an Act addressed elsewhere, outside its window, or whose nonce is already in the ledger; recording the nonce atomically with the commit prevents two concurrent presentations of one Act from both committing.

G6 (order independence). Candidate paths are tried in fingerprint order, which is a function of the certificate set, not its presentation; the result is the first validating path in that order, or the failure of the first path tried.

G7 (reproducibility). The verdict is a deterministic function of the Act, the pinned root, the verification time, the relying-party facts, the nonce ledger and the revocation state. The Act is retained, the receipt records the time and the relying-party facts, and revocation statements are dated, so a third party can reconstruct the revocation state as of the verification time. A receipt for a committed Act implies the nonce was unused at that moment.

7.2 Omission safety

G3 is the least obvious property and the one most easily lost, so we state it precisely.

Definitions. Let F be the facts an Act establishes: a partial assignment of values to the declared inputs. Let O be the set of inputs whose channel is testimony or presenter and which are absent from F; these are the facts a presenter could have supplied or withheld. An extension F′ of F assigns values to any subset of O and agrees with F elsewhere. Order the three truth values by information, U ⊑ T and U ⊑ F.

Proposition (omission safety). If the relying party returns AUTHORIZED for an Act with facts F and deciding rule D, then for every extension F′ of F, no block or escalate rule that outranks D evaluates to TRUE under F′.

Proof. Let X be a block or escalate rule that outranks D. X is not TRUE under F: if it were, resolution would have selected X or a rule outranking it, not D. X is not UNDECIDED under F, or the commit rule would have returned INCOMPLETE. So X is FALSE under F. Every atomic predicate is monotone with respect to ⊑ when F is extended: an atom that reads an absent fact is U under F and may take any value under F′; an atom that reads only present facts has the same value under F′, because F′ agrees with F on them, and this includes atoms that are U because an operand is outside its domain; exists(f) for f in O is U under F; and exists(f) for an action or relying-party input is not affected, because extensions do not assign those inputs. Kleene's strong connectives are monotone with respect to ⊑. Hence a condition that is FALSE under F is FALSE under every F′. ∎

Corollary (stability). Under the same hypothesis, evaluating the rules over any extension F′ yields an allow or escalate outcome, never block and never INCOMPLETE. D remains TRUE by the same monotonicity, so the deciding rule under F′ is D or a rule that outranks it, and every block or escalate rule that could outrank the new decider outranks D and stays FALSE. The verdict therefore does not depend on which of the withheld facts the presenter could have supplied. One protocol-level qualification applies: an Act carrying additional testimony has a different binding digest, so consents obtained for the original Act do not carry over to it.

The proof needs every atom to be monotone. In 0.2.0 one kind of atom was not, and a second problem sat just outside the proposition. We found both while preparing this paper, by testing the proposition against the reference verifier.

  • Monotonicity of exists. In 0.2.0 exists(f) was always decided, FALSE when f was absent. That atom is not monotone: extending F with f turns it from FALSE to TRUE. A block rule written exists(fraud_alert) on a testimony input was therefore defeated by omitting the statement, a direct counterexample to the proposition. Version 0.3.0 makes exists(f) UNDECIDED for inputs in O, which is exactly the monotonicity the proof needs.
  • Vacuous falsity. In 0.2.0 a comparison on a value of the wrong kind was FALSE. That atom is monotone, so the proposition held, but it gave the presenter a different lever: it chooses the action's parameters. Sending "amount": "300000" as a string made amount > 50000 FALSE. Under a policy whose allow rule did not also read the amount, the Act was AUTHORIZED, and a relying party that coerced the string on commit would have applied $300,000. Version 0.3.0 closes this in two layers. A declared type for every sourced input rejects a mismatched value before evaluation. And a primitive whose operands are outside its domain is UNDECIDED rather than FALSE, which also covers a field nested inside an object-typed input that the type check does not inspect: terms.months > 360 on the string "480" was the case we found after the first layer. With the second layer, an atom is FALSE only when its operands are present and of the kind it compares, so a deny rule that evaluates FALSE reflects the actual values: a presenter can make it false only by proposing an action that genuinely does not trigger it. NaN, which compares FALSE with everything, is excluded at step 1. JSON cannot carry it, but common parsers accept it, and the 0.2.0 reference verifier authorized a NaN amount.

These fixes are fail-closed: they can only turn an AUTHORIZED verdict into a rejection or INCOMPLETE, never the reverse. The cost is borne by rule authors and witnesses. A rule that tests a witnessed fact for absence will never be decided by absence, and must be written against an explicit value the witness states.

7.3 What the analysis does not cover

The goals are conditional on the rules being the right rules and the witnesses telling the truth. The protocol guarantees that the institution's stated policy was applied to facts from the parties the institution chose. It does not guarantee that the policy is wise or that the chosen parties are honest. It also assumes complete mediation (A3): a relying party that accepts the same change through another interface has not adopted the protocol for that interface.

8. Related work

Trust management. PolicyMaker [11] and KeyNote [12] introduced the idea that a request carries credentials and a compliance checker decides whether they authorize the action under a local policy. SPKI [13] made authorization certificates with delegation and tag intersection a certificate format. SPEC-007's scoped, monotonically narrowing delegation is in this lineage. What SPEC-008 adds is not delegation but the separation of three kinds of statement, namely rules, facts and consents, with distinct key purposes, and the requirement that the rules themselves declare who may supply each fact.

Logics of authorization and proof-carrying authorization. Lampson, Abadi, Burrows and Wobber [14] gave the speaks-for calculus for reasoning about delegated authority. Appel and Felten [15] proposed that a requester carry a proof of authorization that the server checks, and Bauer, Garriss and Reiter [16] built distributed proving on that idea. An Act is a proof-carrying request in this sense. The verifier, however, does not check a proof in a general logic. It re-runs a deterministic evaluation of a decidable rule language, with bounded certificate sets and fixed verification steps, which keeps verification cost predictable and lets non-specialists audit verdicts.

Attribute-based access control. XACML 3.0 [17] separates the policy enforcement point from the policy decision point, and its decision set includes Indeterminate. Under its deny-overrides family, an Indeterminate that could have been a Deny prevents a Permit, which is close in spirit to SPEC-008's commit rule. The differences are in where facts come from and where the decision runs. In XACML, attributes are fetched by the decision point from information points the deployment trusts, and the decision point is typically a service the enforcement point calls. In SPEC-008 every fact arrives inside the Act through a channel the sealed policy declares, testimony is signed by keys certified for that fact, and the decision runs inside the relying party with no call out. Policy engines such as OPA [26] occupy the decision-point role and could evaluate the rules; they do not address fact provenance or action binding.

Capability tokens. Macaroons [18] support offline attenuation through caveats, and third-party caveats are discharged by statements from another service, a mechanism close to testimony. Biscuit [20] and UCAN [19] provide public-key capability chains with attenuation. These systems represent what the bearer may do. SPEC-008 represents why a specific change is permitted: an institution's rules, evaluated on attested facts, sometimes requiring human consent. The two compose naturally, since a capability can authorize a presenter to submit Acts at all.

Delegated authorization on the web. OAuth 2.0 Token Exchange [8] can express a delegation chain in an act claim, and Rich Authorization Requests [9] and GNAP [10] let a client request fine-grained grants. In these designs an authorization server, online, issues a token that represents a grant. In SPEC-008 no server issues the authorization. The relying party derives it from the rules and facts in the Act. The two can coexist: a token can authenticate the presenter's session while the Act authorizes the change.

Agent identification. HTTP Message Signatures [6] and the IETF Web Bot Auth profile [7] let automated clients sign requests so servers can verify the operator. SPIFFE [27] issues workload identities inside an organization. These address authentication of the caller and are useful alongside SPEC-008 for traffic management and abuse control, which SPEC-008 does not attempt. SPEC-008 deliberately excludes presenter identity from the verdict.

Verifiable credentials. Testimony statements resemble W3C Verifiable Credentials [21] issued by a witness. SPEC-008 uses a deliberately minimal statement format bound to one subject and one fact, so that scope can be checked per fact, and it does not provide selective disclosure of the kind SD-JWT [28] offers (§10.3).

9. Implementation and evaluation

9.1 Implementations

There are two implementations of SPEC-008, both by the authors. The first is a self-contained Python reference verifier in the specification repository (act_verify.py, about 470 lines). The second is the TypeScript verifier in the hosted NOMOS platform (nomos-act.ts), which resolves every key through the platform's own SPEC-007 implementation and canonicalizer. SPEC-007 additionally has a pure TypeScript reference implementation in the specification repository.

9.2 Conformance vectors

SPEC-008 publishes 29 deterministic vectors generated from fixed seeds and a public lending policy. They cover authorization by rule and by dual consent; denial by rule and by default; a presenter asserting a testimony fact; the issuer attempting to testify; a witness outside its claim set; zero, one and duplicated consents; an action altered after consent; an approver claiming a role it lacks; expiry, wrong audience and replay; stale and misdirected testimony; an uncertified issuer; a tree-shaped certificate set presented in reverse; two withheld-fact cases; an action parameter of the wrong type; exists() over a withheld statement; and a wrong-typed field inside an object-typed parameter; a superseded version presented after supersession; a revoked authority; and an in-force statement accepted, stale and absent. Two further cases, a NaN and an infinite amount, cannot be written in a JSON vector file and are built in memory by both test suites. SPEC-007 publishes 14 chain vectors. Both implementations pass all of them.

9.3 Cross-implementation mutants

Vectors test the cases their authors thought of. To test the space around them, we derive mutants from every vector: 125 Acts with exactly one testimony or consent statement removed; 561 with one action parameter, nested parameter field or relying-party fact replaced by a value of another type, its string form, a list, an object or null; and 43 with the in-force statement removed or altered, or the authority revoked. Of the 729, 131 are decided by the in-force step, 413 reach the fact checks or later, and 156 reach rule evaluation. For all 729 the two implementations return identical verdicts and identical normative fields: decision, deciding rule, open rules and facts, consent counts and binding digest. The only difference is a human-readable detail string the platform attaches to chain failures. We inspected by hand the nine mutants that remain AUTHORIZED. Each is correctly authorized: the mutation either left the facts unchanged (a string parameter replaced by the same string), removed a statement the original Act should not have carried (an out-of-scope witness claim), or set to null a fact whose every reading rule was already FALSE through another conjunct, such as is_first_loan == true and … when is_first_loan is false.

9.4 Defects found

Writing two implementations from one text, testing each against the other's vectors, and re-testing the specification against outside challenges found seven defects. All are fixed, and each fix is pinned by a vector or test that fails on the previous behavior.

DefectHow it was foundFix
RFC 8785 key order violated for integer-like keys: JavaScript objects enumerate keys such as "2" and "10" first, so rebuilt-and-stringified objects lost UTF-16 code-unit orderPython and TypeScript canonical forms disagreed on such documentsSerialize directly in all four canonicalizers; a production scan found no stored object affected
Order-dependent chain resolution on tree-shaped certificate sets (§5.3)A second Python verifier, written by the authors from the SPEC-007 1.7.0 text, run on the SPEC-008 vectorsSPEC-007 rev. 1.8.0 target-first resolution
A withheld fact read as false, letting an agent omit the statement that would deny it, including through consentPorting the reference verifierSPEC-008 0.2.0 three-valued evaluation and INCOMPLETE
A comparison on a value of the wrong kind, including a field nested in an object parameter or a NaN, was FALSE, silencing deny rules (§7.2)Testing the omission-safety proposition against the reference, then reviewing its premisesSPEC-008 0.3.0: declared finite types (FACT_TYPE_VIOLATION), out-of-domain operands UNDECIDED, non-finite Acts MALFORMED
exists() decided by absence for witnessed facts (§7.2)SameSPEC-008 0.3.0 authoritative absence
Receipts omitted the verification time and relying-party facts, so the promised re-verification was impossible whenever rules read relying-party stateWriting the reproducibility argument (G7)SPEC-008 0.3.0 §9; the production ledger now records both
A genuine but superseded, unrevoked version of an authority still authorized a new action, and the Act path never checked artifact revocationA reader's response to Computable Authority Lecture 4.4 ("Somewhere for a No to Go") argued that a negative verdict needs force at the verifier; re-testing the lecture's own scenario, in which the policy version changes mid-week, against the specification exposed this separate gapSPEC-008 0.4.0 §5.4: the version in force at verification time, from the relying party's record or an issuer-signed in-force statement; SUPERSEDED, ARTIFACT_REVOKED, VERSION_UNVERIFIED

Three of the seven were found only because a second implementation existed, three only because a property was written down precisely enough to be tested, and one because an outside reader challenged a claim and the discipline re-tested itself. We take this as the strongest argument for publishing the specifications as drafts with vectors and inviting independent implementations, rather than as finished standards.

9.5 Deployment

The platform's conserved-state ledger, which enforces running budgets such as a per-supplier annual limit through reserve, settle and release, acts as a SPEC-008 relying party. Its owner pins an audience identifier and a root; a reservation request may carry an Act instead of a reference to a prior authorization; the ledger reads its own consumed amount as a relying-party fact under a row lock, verifies the Act, enforces nonce uniqueness through a unique index written in the same transaction as the hold, retains the Act and the facts it evaluated, and re-checks the issuer's chain against current revocations at settlement. The TypeScript SDK exposes this as conservedState.reserve() with an Act.

9.6 Cost

On an Apple A18 Pro laptop, verifying the dual-consent vector takes a median of 1.10 ms (p95 1.27 ms) in the TypeScript verifier on Node 24 and 3.35 ms (p95 3.80 ms) in the Python reference on Python 3.9. The Act is about 16 KB and carries twelve Ed25519 signatures: one seal, five certificates, four testimony statements and two consents. Certificate sets are capped at 20 and paths at 20 hops, and per-resolution memoization bounds the worst case measured on the public endpoint at about 8 ms (§5.3).

10. Limitations and open problems

10.1 Root governance. Passports work because states are recognized issuers. The equivalent question for agents, namely who should operate roots and under what governance, is not answered by any mechanism here. R-09 examines it against the record of web PKI, DNSSEC, RPKI and Certificate Transparency [25]. The mechanism works with whatever roots a relying party chooses to pin, which today means bilateral recognition, as with CSCA exchange.

10.2 Witness truthfulness. Certification bounds which facts a key may assert, not whether its assertions are true. An institution chooses its witnesses; the protocol makes the choice explicit, signed, scoped and revocable.

10.3 Privacy. Testimony values are visible to the presenter, which assembles the Act, and to the relying party. The relying party needs them to decide; the presenter does not. Encrypting testimony to the relying party, or selective-disclosure formats, are not specified.

10.4 Revocation latency. A revoked key is rejected once the revocation reaches the relying party. How fast that happens is a distribution problem. Freshness staples cover the issuer's chain; for witness and approver keys the relying party checks revocation against its own source.

10.5 Effects that are not state changes. Sending a message or publishing a statement has no system of record that can refuse it. Those effects need a relying party at an outbound gateway, which inherits every duty of §6 to §8. SPEC-008 does not specify one.

10.6 Legacy systems. A system that cannot run verification itself needs an adapter in front of it. The adapter must then hold the only credential able to change that system, or complete mediation fails.

10.7 Operational cost of fail-closed evaluation. INCOMPLETE is the safe answer and an inconvenient one. Witnesses must state negative facts explicitly, and permissive rules commit nothing until every rule above them is decided. In our vectors this cost appears as one additional testimony statement per negative fact.

10.8 Expressiveness. The rule language compares a field with a value. It cannot compare two fields arithmetically, so a cumulative budget check such as consumed_before + amount ≤ limit is enforced by the ledger, not by the rules. This is a deliberate limit that keeps evaluation decidable and cheap, and it means some constraints live in the relying party.

10.9 Independence. Both SPEC-008 implementations are by the specification's authors. The specifications remain drafts until an independent implementation agrees on the vectors.

11. Conclusion

The useful question at an agent boundary is not what the caller is but whether this change is authorized, by whom, on what facts. Answering it requires keeping three kinds of authority apart, letting the institution's rules say who may supply each fact, treating missing and malformed facts as unknown rather than false, binding approval to the exact change, and verifying all of it where the change would land. NOMOS-SPEC-007 and NOMOS-SPEC-008 specify that, and two implementations agree on all 29 vectors and all 729 mutants we have derived from them.

For consequential actions this changes the incentive behind the cat-and-mouse game. Disguise helps an agent against detection. It does not help against a system that commits only verified Acts, because an unverified request fails there whoever sends it. Once carrying authority earns better treatment than hiding, disclosure stops being a cost for agents and becomes the thing that gets their requests through.

The specifications, vectors and reference verifiers are published at github.com/nomos-spec/spec under CC BY 4.0. We invite independent implementations: if you build agents or the services they call, implement against the vectors and report the result in an issue, or write to allan@nomosprotocol.com.

References

  • [1] ICAO. Doc 9303, Machine Readable Travel Documents, Part 12: Public Key Infrastructure for MRTDs. 8th ed., 2021.
  • [2] D. Cooper et al. RFC 5280, Internet X.509 Public Key Infrastructure Certificate and CRL Profile. 2008.
  • [3] M. Cooper et al. RFC 4158, Internet X.509 Public Key Infrastructure: Certification Path Building. 2005.
  • [4] A. Rundgren, B. Jordan, S. Erdtman. RFC 8785, JSON Canonicalization Scheme (JCS). 2020.
  • [5] S. Josefsson, I. Liusvaara. RFC 8032, Edwards-Curve Digital Signature Algorithm (EdDSA). 2017.
  • [6] A. Backman, J. Richer, M. Sporny. RFC 9421, HTTP Message Signatures. 2024.
  • [7] IETF Web Bot Auth Working Group. HTTP Message Signatures for automated traffic. draft-ietf-webbotauth-httpsig-protocol, work in progress.
  • [8] M. Jones et al. RFC 8693, OAuth 2.0 Token Exchange. 2020.
  • [9] T. Lodderstedt, J. Richer, B. Campbell. RFC 9396, OAuth 2.0 Rich Authorization Requests. 2023.
  • [10] J. Richer (Ed.), F. Imbault. RFC 9635, Grant Negotiation and Authorization Protocol (GNAP). October 2024.
  • [11] M. Blaze, J. Feigenbaum, J. Lacy. Decentralized Trust Management. IEEE Symposium on Security and Privacy, 1996.
  • [12] M. Blaze, J. Feigenbaum, J. Ioannidis, A. Keromytis. RFC 2704, The KeyNote Trust-Management System, Version 2. 1999.
  • [13] C. Ellison et al. RFC 2693, SPKI Certificate Theory. 1999.
  • [14] B. Lampson, M. Abadi, M. Burrows, E. Wobber. Authentication in Distributed Systems: Theory and Practice. ACM Transactions on Computer Systems 10(4), 1992.
  • [15] A. W. Appel, E. W. Felten. Proof-Carrying Authentication. ACM Conference on Computer and Communications Security, 1999.
  • [16] L. Bauer, S. Garriss, M. K. Reiter. Distributed Proving in Access-Control Systems. IEEE Symposium on Security and Privacy, 2005.
  • [17] OASIS. eXtensible Access Control Markup Language (XACML) Version 3.0. OASIS Standard, 2013.
  • [18] A. Birgisson, J. G. Politz, Ú. Erlingsson, A. Taly, M. Vrable, M. Lentczner. Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud. NDSS, 2014.
  • [19] UCAN Working Group. User Controlled Authorization Network (UCAN) Specification.
  • [20] Eclipse Biscuit. Biscuit Authorization Token Specification.
  • [21] W3C. Verifiable Credentials Data Model v2.0. W3C Recommendation, 15 May 2025.
  • [22] N. Hardy. The Confused Deputy (or why capabilities might have been invented). ACM SIGOPS Operating Systems Review 22(4), 1988.
  • [23] J. H. Saltzer, M. D. Schroeder. The Protection of Information in Computer Systems. Proceedings of the IEEE 63(9), 1975.
  • [24] S. C. Kleene. Introduction to Metamathematics. North-Holland, 1952.
  • [25] B. Laurie, A. Langley, E. Kasper. RFC 6962, Certificate Transparency. 2013.
  • [26] Open Policy Agent. CNCF project documentation.
  • [27] SPIFFE. Secure Production Identity Framework for Everyone, specification. CNCF.
  • [28] D. Fett, K. Yasuda, B. Campbell. RFC 9901, Selective Disclosure for JSON Web Tokens (SD-JWT). November 2025.
  • [29] NOMOS-SPEC-001 (amendment 2.2.0), NOMOS-SPEC-006, NOMOS-SPEC-007 (rev. 1.8.0), NOMOS-SPEC-008 (0.4.0), test vectors and reference verifiers. github.com/nomos-spec/spec.

Cite this

This is a field in formation; this page will be revised. Cite the version date below, not the day you happen to be reading this.

Suggested citation

SafeHaven (2026). Passports for Agents. Computable Authority Research Library, version of 2026-10-08. https://www.computableauthority.com/research/passports-for-agents

BibTeX

@misc{computableauthority-passports-for-agents,
  author       = {SafeHaven},
  title        = {Passports for Agents},
  howpublished = {Computable Authority Research Library},
  year         = {2026},
  note         = {Version of 2026-10-08},
  url          = {https://www.computableauthority.com/research/passports-for-agents},
}

Full citation guidance →