Skip to main content

Signed Authorization Verdicts for Agent-Initiated Payments
draft-dias-agent-payment-verdicts-00

Document Type Active Internet-Draft (individual)
Author Ithelia Dias
Last updated 2026-10-09
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-dias-agent-payment-verdicts-00
Network Working Group                                            I. Dias
Internet-Draft                                               Saifuro LLC
Intended status: Informational                            9 October 2026
Expires: 12 April 2027

       Signed Authorization Verdicts for Agent-Initiated Payments
                  draft-dias-agent-payment-verdicts-00

Abstract

   When a software agent initiates a payment on behalf of an
   organization, the party that settles the payment usually cannot see
   the policy under which it was permitted.  This document describes a
   signed authorization verdict: a JSON Web Token, signed with ES256,
   that records the outcome of evaluating one payment request, including
   its amount, currency, and recipient, against a spending policy that
   the organization configured.  A party holding the issuer's published
   public key can verify a verdict without contacting the issuer.

   The document describes the claim set, key publication and rotation,
   and a verification procedure, and states what a verdict does not
   assert.  It describes the format as one implementation issues it,
   including the points where it departs from JSON Web Token Best
   Current Practices (RFC 8725).  It is offered as input to IETF
   discussion of authorization records for agent-initiated actions and
   is not a proposal for standardization.

Discussion Venues

   This note is to be removed before publishing as an RFC.

   Comments are welcome by email to the author.  Whether signed
   authorization decisions are in scope for the work proposed for a
   potential AUDIT BoF can be discussed on the audit@ietf.org list
   [AUDIT].

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

Dias                      Expires 12 April 2027                 [Page 1]
Internet-Draft           Agent Payment Verdicts             October 2026

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 12 April 2027.

Copyright Notice

   Copyright (c) 2026 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.  Code Components
   extracted from this document must include Revised BSD License text as
   described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Revised BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
     1.1.  Scope . . . . . . . . . . . . . . . . . . . . . . . . . .   4
     1.2.  Requirements Language . . . . . . . . . . . . . . . . . .   5
     1.3.  Terminology . . . . . . . . . . . . . . . . . . . . . . .   5
   2.  Related Work  . . . . . . . . . . . . . . . . . . . . . . . .   6
   3.  Overview  . . . . . . . . . . . . . . . . . . . . . . . . . .   8
   4.  Verdict Format  . . . . . . . . . . . . . . . . . . . . . . .  11
     4.1.  Serialization, Header, and Signature  . . . . . . . . . .  11
     4.2.  Claims  . . . . . . . . . . . . . . . . . . . . . . . . .  11
     4.3.  The request Claim . . . . . . . . . . . . . . . . . . . .  13
     4.4.  Presence by Verdict Code  . . . . . . . . . . . . . . . .  14
     4.5.  Verdict Codes . . . . . . . . . . . . . . . . . . . . . .  15
     4.6.  Amounts . . . . . . . . . . . . . . . . . . . . . . . . .  16
     4.7.  What the Token Does Not Contain . . . . . . . . . . . . .  17
   5.  Key Publication . . . . . . . . . . . . . . . . . . . . . . .  17
     5.1.  JWK Set . . . . . . . . . . . . . . . . . . . . . . . . .  17
     5.2.  Locating the JWK Set  . . . . . . . . . . . . . . . . . .  17
     5.3.  Test and Production Keys  . . . . . . . . . . . . . . . .  18
     5.4.  Caching and Unknown Key Identifiers . . . . . . . . . . .  18
     5.5.  Rotation  . . . . . . . . . . . . . . . . . . . . . . . .  18
   6.  Verification Procedure  . . . . . . . . . . . . . . . . . . .  19
     6.1.  Matched, Contradicted, and Unsupported  . . . . . . . . .  23
     6.2.  Checking a Stored Verdict . . . . . . . . . . . . . . . .  23
   7.  What a Verdict Asserts  . . . . . . . . . . . . . . . . . . .  24
   8.  Versioning and Extensibility  . . . . . . . . . . . . . . . .  25

Dias                      Expires 12 April 2027                 [Page 2]
Internet-Draft           Agent Payment Verdicts             October 2026

   9.  Implementation Status . . . . . . . . . . . . . . . . . . . .  25
     9.1.  Saifuro . . . . . . . . . . . . . . . . . . . . . . . . .  26
   10. Security Considerations . . . . . . . . . . . . . . . . . . .  27
     10.1.  Trust in the Issuer and Its Key Set  . . . . . . . . . .  27
     10.2.  Who Stands Behind a Verdict  . . . . . . . . . . . . . .  28
     10.3.  Payee Substitution . . . . . . . . . . . . . . . . . . .  28
     10.4.  Bearer Tokens  . . . . . . . . . . . . . . . . . . . . .  29
     10.5.  Algorithms and Signatures  . . . . . . . . . . . . . . .  29
     10.6.  Cross-JWT Confusion and Explicit Typing  . . . . . . . .  29
     10.7.  Audience . . . . . . . . . . . . . . . . . . . . . . . .  30
     10.8.  Replay and Signature Malleability  . . . . . . . . . . .  30
     10.9.  Clock Skew . . . . . . . . . . . . . . . . . . . . . . .  31
     10.10. Key Compromise . . . . . . . . . . . . . . . . . . . . .  31
     10.11. Amounts and Parsing  . . . . . . . . . . . . . . . . . .  31
     10.12. Approval of Held Requests  . . . . . . . . . . . . . . .  32
     10.13. Aggregate Limits . . . . . . . . . . . . . . . . . . . .  32
     10.14. Event Tokens . . . . . . . . . . . . . . . . . . . . . .  33
   11. Privacy Considerations  . . . . . . . . . . . . . . . . . . .  33
   12. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  34
   13. References  . . . . . . . . . . . . . . . . . . . . . . . . .  34
     13.1.  Normative References . . . . . . . . . . . . . . . . . .  34
     13.2.  Informative References . . . . . . . . . . . . . . . . .  35
   Appendix A.  Example  . . . . . . . . . . . . . . . . . . . . . .  38
     A.1.  Example Key . . . . . . . . . . . . . . . . . . . . . . .  38
     A.2.  Verdict . . . . . . . . . . . . . . . . . . . . . . . . .  39
     A.3.  Checking the Example  . . . . . . . . . . . . . . . . . .  39
   Appendix B.  Open Issues  . . . . . . . . . . . . . . . . . . . .  40
   Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .  41
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  42

1.  Introduction

   Three properties of an agent-initiated payment can be checked
   separately: which agent initiated it, whether it was within the
   authority the agent was given, and whether value moved.  The first
   and third are the subject of active protocol work (Section 2).  The
   second is usually decided inside the operator's own systems or a
   provider's, and the decision does not travel with the payment.

Dias                      Expires 12 April 2027                 [Page 3]
Internet-Draft           Agent Payment Verdicts             October 2026

   This document describes a verdict: a signed statement, valid for a
   short time, that names the request it was made about, the mandate it
   was checked against, if any, and the outcome of the check.  A party
   asked to settle the payment can check a verdict without contacting
   the issuer, using the issuer's published keys, its own record of the
   payment, a record of the verdicts it has already accepted, and, where
   the payment draws on a particular operator's funds, the mandate
   identifiers and amount unit agreed with that operator (Section 6).
   Refusals produced by policy evaluation are signed in the same way as
   approvals; an operator's refusal of a request held for review
   produces no verdict (Section 4.5).

   This document is descriptive.  It records the format that one
   implementation issues (Section 9), including the points where the
   format departs from [RFC8725] and other properties the author
   considers weaknesses (Section 10, Appendix B).  It is offered as
   input to IETF discussion of authorization records for agent actions,
   such as the discussion on the audit mailing list [AUDIT] of a
   potential AUDIT BoF and working group charter; in particular,
   Section 6.1 and Section 7 state, for one deployed format, what a
   successful check establishes and what it does not.  The author does
   not ask for this format to be adopted; a standard format in this area
   would need to resolve the issues in Appendix B and might not be
   compatible with this one.

   The author is the founder of Saifuro LLC, which operates the
   implementation described here, and has a commercial interest in this
   area.

1.1.  Scope

   In scope are the verdict format (Section 4), the publication of
   verification keys (Section 5), and the procedure a relying party
   follows before it relies on a verdict (Section 6).

   Out of scope are: the language in which spending policy is expressed;
   how an agent authenticates to the issuer; user consent; how a payment
   is executed or settled; how a verdict is carried inside a particular
   payment protocol; and the identity of an agent beyond an identifier
   assigned by its operator.  The issuer described here does not hold or
   move funds, and a verdict is not a payment instrument.

Dias                      Expires 12 April 2027                 [Page 4]
Internet-Draft           Agent Payment Verdicts             October 2026

1.2.  Requirements Language

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in
   BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

   In this document, BCP 14 key words state what a relying party has to
   do to rely safely on verdicts in this format.  In Table 2, and where
   Section 4.3 says that members are REQUIRED, they state what a verdict
   contains: a verifier rejects a token in which a required claim or
   member is absent (Section 6, steps 4 and 6).  Section 5.5,
   Section 10.4, and Section 11 also address operators and others that
   carry or keep verdicts.  The key words do not define requirements for
   other issuers or formats.

1.3.  Terminology

   Operator:  The organization that runs an agent and configures the
      authority it has to spend.

   Agent:  Software that proposes payments on an operator's behalf.

   Mandate:  An operator-configured policy object at the issuer that
      limits what one agent may spend.  In the deployed implementation
      it holds a per-transaction limit and an optional rolling 30-day
      limit in one currency, a list of allowed categories, an expiry
      date, an optional review threshold, and the name of the principal
      expected to approve reviews (Section 10.12).  It does not restrict
      recipients.  Mandates are not edited, only revoked and replaced.
      A mandate in this sense is not the same object as the mandates of
      [AP2], and it is not a credential signed by a user.

   Environment:  One of the issuer's separately keyed instances, test
      ("sandbox") or production.  Each operator has its own agents and
      mandates in each.

   Issuer:  The service that evaluates a payment request against the
      operator's mandates and signs the result; in the terminology of
      [AUTHZEN], a policy decision point.

   Verdict:  The signed token defined in Section 4.  "Verdict code"
      means the value of its verdict claim.

   Relying party:  The party that is about to settle, ship, or release
      funds on the strength of a verdict: for example a seller, a
      payment service provider, or an escrow release process.

Dias                      Expires 12 April 2027                 [Page 5]
Internet-Draft           Agent Payment Verdicts             October 2026

   Verifier:  The component of a relying party that performs Section 6.

   Payment record:  The relying party's own record of the payment it is
      about to settle: amount, currency, and recipient.  It comes from
      the relying party's systems, never from the token.

   Names of claims, members of request, and header parameters that this
   format or its event tokens (Section 10.14) use are written without
   quotation marks (iss, request.amount, kid); values, and names that
   the format does not use, are written in quotation marks ("ES256",
   "allow", "aud").

2.  Related Work

   Several specifications address agent-initiated payments, or
   authorization decisions in general, at different points: when a user
   authorizes a purchase or delegates authority to an agent ([AP2]),
   when a payment credential is handed to a merchant's payment service
   provider ([ACP]), on individual requests ([RFC9421], [TAP], [X402]),
   and when authorization is requested or decided ([RFC9396],
   [AUTHZEN]).  Not all of them define a signed object.  The
   descriptions below are based on the cited public specifications as
   accessed on 7 October 2026, and on 9 October 2026 for
   [I-D.laxsharma-pact].

   OAuth 2.0 Rich Authorization Requests [RFC9396]:
      A client requests fine-grained authorization, for example to
      initiate a single payment, from an authorization server, usually
      with the resource owner's consent, and presents the resulting
      access token to a resource server that trusts that authorization
      server.  A verdict is not an access token: it records the outcome
      of a policy evaluation, including refusals, and is meant to be
      checked by a relying party whose only relationship with the issuer
      is holding its public keys.

   Transaction Tokens [I-D.ietf-oauth-transaction-tokens]:
      Carry user identity, workload identity, and authorization context
      between workloads within a single trust domain.  A verdict is
      meant to be verified outside the issuing organization, by a party
      that does not share its trust domain.

   OpenID AuthZEN Authorization API 1.0 [AUTHZEN]:
      Defines how a policy enforcement point asks a policy decision
      point for a decision, which is returned as JSON.  It permits a
      decision point to sign its response (Section 11.6 of [AUTHZEN])
      but does not define a signed response format.  A verdict can be
      read as a signed decision about a payment, meant to be verified
      further downstream than the enforcement point that requested it.

Dias                      Expires 12 April 2027                 [Page 6]
Internet-Draft           Agent Payment Verdicts             October 2026

   Agent Payments Protocol [AP2]:
      Carries the user's authorization as signed mandates that the
      merchant, the credential provider, and the payment network verify.
      A verdict instead carries the result of an evaluation performed by
      the issuer against the operator's policy, without disclosing the
      policy.  It carries no user consent and can accompany such
      mandates without replacing them.

   Agentic Commerce Protocol [ACP]:
      In its delegated payment specification, the agent platform sends a
      payment credential to the merchant's payment service provider with
      a single-use allowance (a maximum amount, a currency, a checkout
      session, a merchant, and an expiry), and the provider restricts
      the resulting token to that allowance.  A verdict is a separate
      token that the relying party verifies itself before settlement.

   x402 [X402]:
      The client signs a scheme-specific payment authorization, and the
      resource server verifies and settles the payment, either itself or
      through a facilitator.  That signature is the payer's
      authorization of the transfer.  A verdict authorizes no transfer;
      it is a statement by a third party about a policy evaluation,
      signed by neither the payer nor the payee.

   HTTP Message Signatures [RFC9421], Web Bot Auth
   [I-D.ietf-webbotauth-httpsig-protocol], and Trusted Agent Protocol
   [TAP]:
      Let a server authenticate an automated client's HTTP requests.
      [TAP] profiles HTTP Message Signatures so that a merchant can
      recognize an agent's requests using public keys that the payment
      network publishes, and adds signed objects that identify the
      consumer and carry payment data.  A verdict identifies neither the
      agent's software nor the consumer; it states the outcome of a
      policy evaluation.

   Auditing and transparency:
      [I-D.kuehlewind-audit-architecture] describes an architecture for
      auditing agent delegation and interactions; a verdict is one kind
      of record such an architecture could carry or reference.
      [RFC9943] describes registering signed statements with a
      transparency service that issues receipts, using COSE rather than
      JOSE.  It addresses long-term verification, which this format
      leaves to each party that stores its own copy of the JWK Set
      (Section 5.5, Section 10.1).

   PACT [I-D.laxsharma-pact]:
      Uses the term "Verdict" for a different object: a signed record in
      which an evaluator judges whether work an agent delivered under a

Dias                      Expires 12 April 2027                 [Page 7]
Internet-Draft           Agent Payment Verdicts             October 2026

      task contract passes or fails.  PACT does not address payments or
      their authorization, and the two formats are unrelated apart from
      the term.

3.  Overview

     Agent               Issuer               Relying Party
       |                   |                        |
       | (1) request       |                        |
       |------------------>|                        |
       |                   | (2) evaluate against   |
       |                   |     the mandates       |
       | (3) verdict (JWS) |                        |
       |<------------------|                        |
       |                   |                        |
       | (4) payment, verdict attached              |
       |------------------------------------------->|
       |                   | (5) JWK Set (cached)   |
       |                   |<-----------------------|
       |                   |----------------------->|
       |                   |                        | (6) verify,
       |                   |                        |     compare with
       |                   |                        |     payment record

                  Figure 1: Issuing and checking a verdict

   1.  The agent sends a payment request, stating amount, currency,
       recipient, and category, to the issuer.

   2.  The issuer evaluates the request against the agent's mandates and
       records the decision.

   3.  The issuer returns the decision, including a verdict.  A verdict
       is issued for every evaluated request, whatever the outcome.

   4.  The agent, or a component acting for the operator, presents the
       verdict to the relying party together with the payment.

   5.  The relying party obtains the issuer's JWK Set, normally from its
       cache.

   6.  The relying party verifies the verdict and compares it with its
       payment record (Section 6).

Dias                      Expires 12 April 2027                 [Page 8]
Internet-Draft           Agent Payment Verdicts             October 2026

   The relying party needs no account with the issuer and sends it no
   request about individual verdicts: from the issuer it needs only the
   published JWK Set. It also needs its own payment record, its store of
   accepted nonces, and, for step 8 of Section 6, the mandate
   identifiers and the amount unit it has agreed with the operator.

   Table 1 collects the values that this document refers to: those of
   the deployed implementation, and those this document sets for
   verifiers.

Dias                      Expires 12 April 2027                 [Page 9]
Internet-Draft           Agent Payment Verdicts             October 2026

    +==============================+==================================+
    | Value                        | Setting                          |
    +==============================+==================================+
    | Verdict lifetime (exp - iat) | 300 seconds                      |
    +------------------------------+----------------------------------+
    | Clock skew allowed to        | at most 60 seconds               |
    | verifiers                    |                                  |
    +------------------------------+----------------------------------+
    | Review expiry                | 24 hours                         |
    +------------------------------+----------------------------------+
    | Frequency rule               | 10 decisions per agent in 60     |
    |                              | seconds                          |
    +------------------------------+----------------------------------+
    | Window of the rolling limit  | 30 days                          |
    +------------------------------+----------------------------------+
    | JWK Set cache lifetime (max- | 300 seconds                      |
    | age)                         |                                  |
    +------------------------------+----------------------------------+
    | Refetches on unknown kid     | at most one per 30 seconds       |
    |                              | (recommended)                    |
    +------------------------------+----------------------------------+
    | Pre-publication of a new key | at least 1 hour                  |
    +------------------------------+----------------------------------+
    | Retention of a retired key   | at least 25 hours after its last |
    |                              | token                            |
    +------------------------------+----------------------------------+
    | Redelivery of event tokens   | last retry due 24 hours after    |
    |                              | creation                         |
    +------------------------------+----------------------------------+
    | Identifier prefixes          | "dec_", "mnd_", "n_", "agt_",    |
    |                              | "evt_"                           |
    +------------------------------+----------------------------------+
    | Nonce                        | 64 random bits                   |
    +------------------------------+----------------------------------+
    | Amount                       | greater than 0, less than 10^15, |
    |                              | at most 6 fractional digits      |
    +------------------------------+----------------------------------+
    | Idempotency-Key retention    | 24 hours                         |
    +------------------------------+----------------------------------+
    | API request body limit       | 64 KB                            |
    +------------------------------+----------------------------------+
    | Length of recipient; of      | at most 1,024 characters; at     |
    | category and currency        | most 128 characters each         |
    +------------------------------+----------------------------------+

                Table 1: Values referred to in this document

Dias                      Expires 12 April 2027                [Page 10]
Internet-Draft           Agent Payment Verdicts             October 2026

4.  Verdict Format

4.1.  Serialization, Header, and Signature

   A verdict is a JSON Web Token (JWT) [RFC7519] in JWS Compact
   Serialization [RFC7515]: three base64url segments without padding,
   separated by periods.

   The issuer emits exactly three header parameters: alg, with the value
   "ES256" (ECDSA using P-256 and SHA-256, Section 3.4 of [RFC7518]);
   typ, with the value "JWT"; and kid, naming the signing key in the
   issuer's JWK Set (Section 5).  It does not emit "crit", "jku", "jwk",
   "x5u", "x5c", "x5t", "cty", or any other header parameter.  The typ
   value does not distinguish a verdict from other tokens signed with
   the same key (Section 10.6).

   The signature is the 64-byte concatenation of R and S, each 32 bytes,
   big-endian, as Section 3.4 of [RFC7518] requires, not an ASN.1 DER
   encoding.  The issuer uses randomized ECDSA (Section 10.5) and does
   not normalize S (Section 10.8).

   The payload is a JSON object [RFC8259] encoded in UTF-8 [RFC3629].
   The issuer writes it without insignificant whitespace and in the
   member order of Table 2.  Verifiers MUST NOT depend on member order,
   whitespace, or string escaping.

4.2.  Claims

    +================+=========+==========+==========================+
    | Claim          | Type    | Presence | Meaning                  |
    +================+=========+==========+==========================+
    | iss            | string  | REQUIRED | Issuer identifier.       |
    +----------------+---------+----------+--------------------------+
    | jti            | string  | REQUIRED | Identifier the issuer    |
    |                |         |          | assigns to the decision. |
    |                |         |          | Unique per verdict.      |
    +----------------+---------+----------+--------------------------+
    | iat            | integer | REQUIRED | Time of the decision;    |
    |                |         |          | for an "allow" that      |
    |                |         |          | approves a review, the   |
    |                |         |          | time of the approval.    |
    +----------------+---------+----------+--------------------------+
    | exp            | integer | REQUIRED | Expiry, on every verdict |
    |                |         |          | whatever its code.       |
    +----------------+---------+----------+--------------------------+
    | verdict        | string  | REQUIRED | Verdict code             |
    |                |         |          | (Section 4.5).           |
    +----------------+---------+----------+--------------------------+

Dias                      Expires 12 April 2027                [Page 11]
Internet-Draft           Agent Payment Verdicts             October 2026

    | mandate        | string  | see      | Identifier of the        |
    |                |         | Section  | mandate whose evaluation |
    |                |         | 4.4      | produced the verdict.    |
    +----------------+---------+----------+--------------------------+
    | policy_version | string  | REQUIRED | Per-operator label;      |
    |                |         |          | opaque to verifiers.     |
    +----------------+---------+----------+--------------------------+
    | nonce          | string  | REQUIRED | Random value generated   |
    |                |         |          | for each verdict; the    |
    |                |         |          | replay key (Section 6,   |
    |                |         |          | step 12).                |
    +----------------+---------+----------+--------------------------+
    | request        | object  | REQUIRED | The payment request that |
    |                |         |          | was evaluated            |
    |                |         |          | (Section 4.3).           |
    +----------------+---------+----------+--------------------------+
    | supersedes     | string  | see      | The jti of the "review"  |
    |                |         | Section  | verdict that this        |
    |                |         | 4.4      | "allow" resolves.        |
    +----------------+---------+----------+--------------------------+

                         Table 2: Verdict claims

   In Table 2 and in step 6 of Section 6, "integer" means a JSON number
   whose value is an integer; the issuer writes such values with no
   fraction or exponent part.  This narrows NumericDate (Section 2 of
   [RFC7519]), which also allows non-integer values.

   In the deployed implementation, policy_version is assigned once per
   operator and is not updated when mandates change; despite its name,
   it does not identify the rules that were applied.  Because mandates
   are not edited, the mandate claim identifies the limits that were
   evaluated.  Verifiers MUST treat policy_version as an opaque string.
   The nonce is 64 random bits in the deployed implementation; jti is
   enforced unique by the issuer.

Dias                      Expires 12 April 2027                [Page 12]
Internet-Draft           Agent Payment Verdicts             October 2026

   The claims iss, jti, iat, and exp are used with their registered
   meanings (Section 4.1 of [RFC7519]).  The claim nonce is registered
   in the IANA "JSON Web Token Claims" registry by [OIDC-CORE];
   Section 12.7.1 of [RFC9449] updated the registration to state that it
   may also be used for nonce values in other applications of JWTs, and
   it is used here in that sense, as a non-repeating value used to
   detect replay.  Unlike the nonce of [OIDC-CORE] and [RFC9449], which
   is supplied by the party that later checks the token, this nonce is
   chosen by the issuer, so it gives the relying party no assurance of
   freshness beyond exp.  The claims verdict, mandate, policy_version,
   request, and supersedes are Private Claim Names (Section 4.3 of
   [RFC7519]) and can collide with other uses of the same names
   (Appendix B).

   Apart from the "sandbox-" prefix of kid (step 3 of Section 6) and the
   "evt_" prefix of jti (step 6), verifiers SHOULD treat identifiers as
   opaque strings.

   Verifiers MUST ignore private claims, and members of request, that
   they do not understand (Section 8).  Registered claims that verdicts
   do not carry are processed as [RFC7519] specifies: a verdict carrying
   "aud" is rejected unless the verifier identifies itself with one of
   its values (Section 4.1.3 of [RFC7519]), and one carrying "nbf" is
   rejected before that time (Section 4.1.5 of [RFC7519]).

4.3.  The request Claim

         +===========+========+==================================+
         | Member    | Type   | Meaning                          |
         +===========+========+==================================+
         | agent     | string | Identifier of the agent, unique  |
         |           |        | among one operator's agents in   |
         |           |        | one environment.                 |
         +-----------+--------+----------------------------------+
         | amount    | number | Amount evaluated (Section 4.6).  |
         +-----------+--------+----------------------------------+
         | currency  | string | Currency or asset code, exactly  |
         |           |        | as the request stated it.  When  |
         |           |        | the mandate claim is present, it |
         |           |        | equals that mandate's currency.  |
         +-----------+--------+----------------------------------+
         | recipient | string | Payee identifier, exactly as     |
         |           |        | sent in the request.             |
         +-----------+--------+----------------------------------+
         | category  | string | Spending category, exactly as    |
         |           |        | sent in the request.             |
         +-----------+--------+----------------------------------+

Dias                      Expires 12 April 2027                [Page 13]
Internet-Draft           Agent Payment Verdicts             October 2026

                   Table 3: Members of the request claim

   All five members are REQUIRED.

   The issuer matches currency against the mandate's currency by exact,
   case-sensitive comparison, and does not normalize the value or
   restrict it to a list of codes.  The issuer's documentation uses
   uppercase ISO 4217 codes such as "USD", and "USDC" for an asset that
   has no ISO 4217 code.  Other specifications use other forms, for
   example lowercase codes and integer minor units in [ACP]; a relying
   party that holds its payment record in another form converts the
   currency code to this form, and the amount to the unit agreed with
   the operator (Section 4.6; Section 6, step 8), before steps 9 and 10
   of Section 6; that conversion is part of its own code.

   The format of recipient is agreed between the operator and the
   relying party; examples are "vendor:acme_saas" and a wallet address.
   The issuer does not check it against the identity of any party
   (Section 10.3).

   In the deployed implementation's test environment, creating an escrow
   is also evaluated.  Such a verdict carries the escrow's seller as
   recipient and the fixed category "escrow", and the evaluation skips
   the category check.

4.4.  Presence by Verdict Code

   +===========================================+=========+============+
   | Verdict code                              | mandate | supersedes |
   +===========================================+=========+============+
   | allow, from an evaluation                 | present | absent     |
   +-------------------------------------------+---------+------------+
   | allow, from approving a review            | present | present    |
   +-------------------------------------------+---------+------------+
   | review                                    | present | absent     |
   +-------------------------------------------+---------+------------+
   | deny_limit, deny_velocity, deny_category, | present | absent     |
   | deny_expired, deny_revoked                |         |            |
   +-------------------------------------------+---------+------------+
   | deny_no_mandate                           | absent  | absent     |
   +-------------------------------------------+---------+------------+

                       Table 4: Conditional claims

Dias                      Expires 12 April 2027                [Page 14]
Internet-Draft           Agent Payment Verdicts             October 2026

4.5.  Verdict Codes

    +=================+===============================================+
    | Code            | Meaning                                       |
    +=================+===============================================+
    | allow           | The request passed every check in this table, |
    |                 | or it was held for review and the operator    |
    |                 | approved it (Section 10.12).  The only code   |
    |                 | on which a relying party may settle.          |
    +-----------------+-----------------------------------------------+
    | review          | The amount is above the mandate's review      |
    |                 | threshold, and the operator must approve or   |
    |                 | deny the request.  Not an approval.           |
    +-----------------+-----------------------------------------------+
    | deny_limit      | The amount exceeds the per-transaction limit, |
    |                 | or, together with the amounts allowed under   |
    |                 | the same mandate in the previous 30 days, the |
    |                 | rolling 30-day limit.                         |
    +-----------------+-----------------------------------------------+
    | deny_velocity   | The agent already had 10 or more decisions in |
    |                 | the previous 60 seconds.                      |
    +-----------------+-----------------------------------------------+
    | deny_category   | The category is not one of the mandate's      |
    |                 | allowed categories.                           |
    +-----------------+-----------------------------------------------+
    | deny_expired    | The mandate is past its expiry date.          |
    +-----------------+-----------------------------------------------+
    | deny_revoked    | The mandate has been revoked.                 |
    +-----------------+-----------------------------------------------+
    | deny_no_mandate | The agent is not active, holds no mandate, or |
    |                 | holds no mandate in the requested currency.   |
    +-----------------+-----------------------------------------------+

                           Table 5: Verdict codes

   For each of the agent's mandates in the requested currency, the
   checks run in this order: revoked, expired, category, per-transaction
   limit, rolling 30-day limit, frequency rule, review threshold.  When
   the agent holds several such mandates, they are evaluated in order of
   creation, and the verdict is the first "allow", otherwise the first
   "review", otherwise the result for the oldest mandate.  These checks
   are the whole of the evaluation; in particular, a mandate does not
   restrict the recipient (Section 10.3).

   A relying party MUST treat every code other than "allow", including
   codes this document does not define, as "do not settle".

Dias                      Expires 12 April 2027                [Page 15]
Internet-Draft           Agent Payment Verdicts             October 2026

   When the operator approves a review, the issuer issues a new verdict
   with the code "allow", its own nonce and expiry, and a supersedes
   claim naming the "review" verdict (Section 10.12).  The "review"
   verdict is not modified.  A review that the operator denies, or that
   expires, produces no verdict.

   An operator records, per environment, a mode of "observe" or
   "enforce", which tells its own systems whether to block payments that
   are not allowed; the issuer blocks nothing in either mode.  In the
   deployed implementation, a production environment is in observe mode
   until the operator changes it.  The issuer evaluates, records, and
   signs the same verdicts in either mode, and the mode is not in the
   token, so a signed refusal does not show that a payment was blocked.

4.6.  Amounts

   request.amount is a JSON number in the same units as the mandate's
   limits.  The issuer does not interpret or convert units; its
   documentation uses major units, so that 340 with currency "USD" means
   340 US dollars, not 340 cents.  The amount is greater than zero and
   less than 10^15, and has at most six fractional digits.  The issuer
   writes it in minimal fixed-point form: an integral amount has no
   decimal point (340, never 340.00), other amounts have no trailing
   zeros (340.5, never 340.50), and the issuer never uses exponent
   notation or leading zeros other than the single 0 before the decimal
   point of an amount below 1 (0.5).

   Amounts can therefore carry up to 21 significant digits, more than an
   IEEE 754 binary64 number holds.  This departs from Section 2.2 of
   [RFC7493], which says that I-JSON messages should not include such
   numbers and recommends JSON strings for them.  Many JSON parsers,
   including those inside common JWT libraries, read every number as
   binary64, and from 2^33 (about 8.6 x 10^9) upward two amounts that
   differ in the sixth fractional digit can map to the same binary64
   value; 8589934592.000001 and 8589934592.000002 do.  A verifier
   therefore compares amounts by decimal value (Section 6, step 9).

   Nothing in the token states the unit.  An operator that configures a
   mandate in minor units obtains verdicts whose amounts are in minor
   units, and a relying party that compares them with a payment record
   in major units (Section 6, step 9) would match a verdict evaluated
   for 340 cents against a payment of 340 US dollars.  Step 8 of
   Section 6 therefore includes agreeing the unit with the operator.

Dias                      Expires 12 April 2027                [Page 16]
Internet-Draft           Agent Payment Verdicts             October 2026

4.7.  What the Token Does Not Contain

   The issuer keeps information about each decision that is not in the
   token and is therefore not signed.  The decision record it returns to
   the operator contains the enforcement mode (Section 4.5), a human-
   readable reason, operator metadata such as order references, and, for
   a "review" verdict, the review identifier and the principal it waits
   for.  The issuer also stores, but neither signs nor returns in the
   decision record, the payment protocol named in the request.  A
   verdict is therefore not bound to an order, and a verdict evaluated
   for one payment protocol can be presented on another.

   The token has no "aud", "sub", "nbf", or "cnf" claim, and no claim
   that identifies the operator (Section 10.2, Section 10.4,
   Section 10.7).

5.  Key Publication

5.1.  JWK Set

   The issuer publishes its public keys as a JWK Set (Section 5 of
   [RFC7517]).  Each key has "kty" "EC", "crv" "P-256", "x", "y", "use"
   "sig", "alg" "ES256", and a "kid".  The deployed implementation
   serves the set over HTTPS with "Cache-Control: public, max-age=300"
   [RFC9111] and "Access-Control-Allow-Origin: *", with the media type
   "application/json" rather than "application/jwk-set+json"
   (Section 8.5 of [RFC7517]).

5.2.  Locating the JWK Set

   The deployed implementation publishes its JWK Set at the path
   "/.well-known/jwks.json" under its issuer identifier,
   https://verdicts.saifuro.com (Section 9), and keeps an older location
   that permanently redirects to it.  The suffix "jwks.json" is widely
   used but is not registered in the Well-Known URIs registry; serving
   the set under it departs from Section 3 of [RFC8615], which requires
   registration, and this document does not register it (Appendix B).

   A relying party MUST take the list of issuers it accepts, and the JWK
   Set location for each, from its own configuration, and MUST fetch
   each set over HTTPS with certificate validation.  It MUST NOT fetch
   keys from a location derived from a token.  Otherwise any party can
   mint verdicts that verify against keys it publishes itself.  A
   verifier SHOULD NOT follow HTTP redirects when fetching a JWK Set,
   since a redirect moves the source of its keys to a location that is
   not in its configuration, and SHOULD bound the size of the response
   and the time it waits for it.

Dias                      Expires 12 April 2027                [Page 17]
Internet-Draft           Agent Payment Verdicts             October 2026

5.3.  Test and Production Keys

   The deployed implementation operates a test environment and a
   production environment.  Each has its own signing key, and both keys
   are published in the same JWK Set. The kid of a test key begins with
   "sandbox-"; the kid of a production key does not.  The issuer
   identifier, the claim set, and the token shape are otherwise
   identical.  Anyone with access to the test environment can obtain a
   correctly signed test "allow" for any recipient and amount, so a
   verifier rejects tokens whose kid begins with "sandbox-" unless it is
   used only for testing (Section 6, step 3; Section 10.6).

5.4.  Caching and Unknown Key Identifiers

   Verifiers SHOULD cache each JWK Set and refresh it when it is older
   than the max-age it was served with.  If a refresh fails, a verifier
   MAY keep using the last copy it fetched successfully, SHOULD raise an
   alert, and SHOULD stop accepting verdicts once that copy is older
   than a bound it chooses: the longer it uses a stale copy, the longer
   a key the issuer has removed stays trusted (Section 10.10).

   The kid is untrusted input, used only as a lookup key, never in a
   file path, query, or URL (Section 3.10 of [RFC8725]).  On a kid that
   is absent from the cached set, a verifier fetches the set again once
   and looks again.  Because anyone can send a token with any kid, these
   refetches MUST be rate-limited; an interval of at least 30 seconds
   between refetches triggered by unknown kids is RECOMMENDED, and
   scheduled refreshes SHOULD NOT count against that limit.  Because the
   refetch is rate-limited, a stream of tokens with made-up kids can
   delay acceptance of a verdict signed with a key the verifier has not
   yet fetched; pre-publication (Section 5.5) avoids that for verifiers
   that refresh on schedule.

   Pinning a single key in code is NOT RECOMMENDED: an integration that
   does so rejects valid verdicts after the next rotation.

5.5.  Rotation

   The issuer's rotation procedure extends the approach of
   Section 10.1.1 of [OIDC-CORE], in which a verifier refetches the set
   on an unfamiliar kid, with a period of pre-publication:

   1.  The issuer publishes the new key in the set at least one hour
       before it signs anything with it, so that every verifier that
       refreshes on schedule holds the key before the first token signed
       with it.

   2.  It switches signing to the new kid.

Dias                      Expires 12 April 2027                [Page 18]
Internet-Draft           Agent Payment Verdicts             October 2026

   3.  It keeps the previous key in the set for at least 360 seconds
       after the last verdict that key signed (the 300-second lifetime
       of a verdict plus the 60-second maximum clock skew allowed in
       Section 6), and for as long as any event token it signed can
       still be delivered (Section 10.14).  The deployed
       implementation's procedure keeps it for at least 25 hours after
       the last token of either kind.

   4.  It removes the previous key.

   The deployed implementation has not yet rotated a key (Section 9), so
   this procedure has not been exercised.

   The set carries only keys that are about to be used, in use, or
   recently retired.  A party that keeps verdicts as records, for audit
   or disputes, SHOULD store a copy of the JWK Set with them, so that
   the signatures can be checked after the key has been removed
   (Section 6.2).

6.  Verification Procedure

   The inputs to verification are the token; the configured list of
   accepted issuers with the JWK Set of each; the current time from a
   synchronized clock; the payment record; a store of nonces from
   verdicts already accepted; whether the verifier is used only for
   testing; where step 8 requires them, the mandate identifiers agreed
   with the operator and the unit its mandates use; and, for the check
   of Section 10.12, a store of the supersedes values of verdicts
   already accepted.

   A relying party MUST apply every step below before it relies on a
   verdict, and MUST reject the token if any step fails.  It MAY perform
   the steps in a different order, provided that it verifies the
   signature (step 5) before it relies on any claim, and records the
   nonce (step 12) only after every other step has passed.  Every check
   MUST use values taken from the payload bytes whose signature step 5
   verified.  A verifier that parses those bytes more than once, for
   example with a JWT library for steps 4 and 7 and with a decimal-
   preserving parser for step 9, MUST reject a header or payload that
   contains duplicate member names at any depth, so that the parses
   cannot disagree about which member they read.

   1.   Parse.  Bound the size of the token before decoding it (verdicts
        that the deployed implementation issues are shorter than 11,000
        characters; Section 10.11), and bound the nesting depth of JSON
        that is parsed before the signature is verified.  Split the
        token into exactly three segments.  Decode each as base64url
        without padding (Section 2 of [RFC7515]), rejecting padding,

Dias                      Expires 12 April 2027                [Page 19]
Internet-Draft           Agent Payment Verdicts             October 2026

        whitespace, any character outside the base64url alphabet, and a
        segment whose length is 1 modulo 4; many base64 decoders accept
        these, so a verifier that uses one checks the segments itself.
        A verifier MAY reject a segment whose unused trailing bits are
        not zero.  Decode the header and payload as UTF-8, rejecting
        invalid UTF-8 (Section 3.7 of [RFC8725]).  Each MUST parse as a
        JSON object.  Header parameter and claim names MUST be unique: a
        verifier MUST either reject a header or payload with duplicate
        member names or use a parser that keeps only the lexically last
        one (Section 4 of [RFC7515], Section 4 of [RFC7519]), and SHOULD
        reject duplicates at any depth.

   2.   Header.  The alg value MUST be exactly "ES256", compared case-
        sensitively (Section 4.1.1 of [RFC7515]).  The accepted
        algorithms MUST come from the verifier's configuration for the
        issuer, never from the token, and the key selected in step 4
        MUST be one the verifier uses only with ES256 (Section 3.1 of
        [RFC8725]).  Reject a token that has a "crit" parameter
        (Section 4.1.11 of [RFC7515]).  The kid value MUST be a non-
        empty string.  Keys MUST NOT be taken from "jku", "jwk", "x5u",
        or "x5c", and verifiers SHOULD reject tokens that carry them.
        Verifiers do not use typ to identify a verdict (Section 10.6).

   3.   Environment.  Unless the verifier is used only for testing,
        reject a token whose kid begins with "sandbox-" (Section 5.3).

   4.   Issuer and key.  The iss claim MUST equal, exactly, the
        identifier of an issuer in the verifier's configuration,
        compared as a case-sensitive string with no transformations or
        canonicalizations (Section 2 of [RFC7519]).  Find the key with
        the token's kid in that issuer's JWK Set, and only there: a
        verifier that accepts more than one issuer MUST NOT look up the
        kid in the union of their key sets.  This is the binding of keys
        to an issuer that Section 3.8 of [RFC8725] requires; iss is read
        before the signature is verified and is authenticated by step 5.
        The key MUST have "kty" "EC" and "crv" "P-256"; if it has "alg",
        the value MUST be "ES256"; if it has "use", the value MUST be
        "sig".  If the kid is absent, refetch the set once under the
        rate limit of Section 5.4; reject the token if the rate limit
        does not permit a refetch, if the kid is still absent, or if it
        appears more than once.

   5.   Signature.  Verify the signature as ES256 (Section 3.4 of
        [RFC7518]).  The signature MUST be exactly 64 bytes.  The
        verifier MUST reject a signature in which R or S is not an
        integer in the interval [1, n-1], where n is the order of the
        P-256 group (Section 4.1.4 of [SEC1]); an implementation that
        omitted this check accepted an all-zero signature for any

Dias                      Expires 12 April 2027                [Page 20]
Internet-Draft           Agent Payment Verdicts             October 2026

        message (CVE-2022-21449; [PSYCHIC]).  Verifiers MUST NOT require
        S to be in the lower half of the group order: the issuer does
        not normalize S, and such a check rejects about half of genuine
        verdicts.  Use an implementation that validates that the public
        key is a point on P-256 (Section 3.4 of [RFC8725]).

   6.   Token kind and structure.  Reject a token whose payload has a
        type claim or whose jti begins with "evt_": it is an event token
        signed with the same key (Section 10.14).  The jti claim MUST be
        a non-empty string.  The iat and exp claims MUST be integers
        with exp greater than iat; a verifier MAY reject a token whose
        exp minus iat exceeds 300.  The verdict claim, policy_version,
        and nonce MUST be non-empty strings.  The request claim MUST be
        an object whose agent, currency, recipient, and category are
        non-empty strings and whose amount is a number greater than
        zero.  The mandate and supersedes claims, when present, MUST be
        non-empty strings.  If the verdict claim is "allow", mandate
        MUST be present.  If supersedes is present, the verdict claim
        MUST be "allow".  Reject a token that carries an "aud" claim
        unless the verifier identifies itself with one of its values
        (Section 4.2).

   7.   Time.  With a clock skew allowance L of at most 60 seconds,
        reject the token if the current time is at or after exp + L
        (Section 4.1.4 of [RFC7519]), or if iat is later than the
        current time + L.  If the token carries an "nbf" claim, reject
        it while the current time + L is before the time in "nbf".
        Expiry does not change a verdict's code: an expired verdict is
        rejected whatever its code.

   8.   Decision and operator.  Reject the token unless the verdict
        claim is "allow".  If the payment draws on funds, credit, or an
        account of a particular operator, also reject it unless mandate
        is one of the identifiers that operator has agreed with the
        relying party (Section 10.2).  Without this check, a verdict
        that passes every other step shows only that some operator
        configured a mandate that allows the payment, and any operator
        can do that for any recipient and amount.  The relying party
        also agrees with that operator the unit in which its mandates
        state amounts (Section 4.6); where no particular operator is
        involved, nothing establishes the unit (Section 7).

   9.   Amount.  Compare request.amount with the amount in the payment
        record, expressed in the unit agreed in step 8, if any, by
        decimal value: 340 equals 340.00, and 340 does not equal 340.5.
        Read the amount from the verified payload bytes with a JSON
        parser that preserves the literal number or yields a decimal
        type; most JWT libraries return claims in which numbers are

Dias                      Expires 12 April 2027                [Page 21]
Internet-Draft           Agent Payment Verdicts             October 2026

        already binary64.  The issuer never writes an amount with an
        exponent, more than 15 digits before the decimal point, or more
        than 6 after it; a verifier SHOULD reject such an amount before
        converting it to a decimal type, wherever it first converts it
        (step 6 compares it with zero), since some decimal
        implementations take time or memory proportional to the
        exponent.  Verifiers MUST NOT compare amounts as binary
        floating-point numbers, except that a verifier MAY compare
        binary64 values when both amounts are below 2^30 (about 1.07 x
        10^9) and both have at most six fractional digits: in that
        range, distinct amounts with at most six fractional digits map
        to distinct binary64 values.

   10.  Currency.  The member request.currency MUST equal the currency
        code in the payment record exactly, compared case-sensitively.

   11.  Recipient.  The member request.recipient MUST equal the payee
        identifier in the payment record, compared code point for code
        point, with no Unicode normalization, case folding, or trimming.
        It names the payee, not the verifier, and binds the verdict to
        the relying party only when the relying party is the payee
        (Section 10.7).

   12.  Replay.  Reject the token if the pair of iss and nonce is in the
        store of accepted nonces.  Otherwise record the pair in the same
        atomic operation that accepts the token, and keep it at least
        until exp + L.  All verifier instances that could accept the
        same token MUST share the store, and a verifier that cannot read
        or write the store MUST reject the token.  The replay key is a
        claim value, never the token string (Section 10.8); jti is also
        unique per verdict, so recording jti instead of nonce gives the
        same protection.  A relying party that applies Section 10.12
        checks and records the pair of iss and supersedes in the same
        atomic operation.

   JWT libraries perform most of steps 1, 2, 4, and 5, and the exp and
   "nbf" checks of step 7, when they are configured with the algorithm
   list ["ES256"], the accepted issuer, and a clock tolerance of at most
   60 seconds.  Some libraries, such as jose, check "aud" only when an
   audience is configured.  Implementers need to check what their
   library leaves out: a library that is handed a key object cannot
   check that key's "alg" and "use" members or whether its kid appears
   twice in the set, and some libraries accept padded or whitespace-
   broken segments.  Steps 3, 6, 8, 9, 10, 11, and 12 are the relying
   party's own code, and so is the iat check of step 7 where the library
   does not perform it.

Dias                      Expires 12 April 2027                [Page 22]
Internet-Draft           Agent Payment Verdicts             October 2026

6.1.  Matched, Contradicted, and Unsupported

   For each property of the payment record that the relying party relies
   on, verification has one of three outcomes:

   Matched:  a signed claim covers the property and agrees with the
      payment record.

   Contradicted:  a signed claim covers the property and disagrees with
      the payment record.

   Unsupported:  no signed claim covers the property.

   A contradicted property causes rejection, by steps 9 to 11.  An
   unsupported property is neither evidence of a problem nor evidence of
   correctness: the relying party has to establish it independently.  In
   this format, amount, currency, and recipient can be matched or
   contradicted.  The members request.agent and request.category are
   signed, but the payment record has no corresponding property, so they
   can be neither matched nor contradicted.  The operator behind the
   verdict is unsupported unless the relying party maps the mandate
   claim to an operator through identifiers agreed out of band
   (Section 10.2); the order, the payment protocol, and the identity of
   an intermediary relying party are always unsupported.  A relying
   party SHOULD record which properties it took from its own records
   rather than from the signature, so that a later audit can tell the
   two apart.

6.2.  Checking a Stored Verdict

   A party that checks a verdict as a record rather than to settle a
   payment, such as an auditor examining a refusal, applies steps 1, 2,
   4, 5, and 6 using a copy of the JWK Set that contains the key
   (Section 5.5), and step 3 if it needs to distinguish test verdicts.
   It evaluates step 7 against the time at which the verdict was
   received if that time was recorded, and otherwise does not apply step
   7; it does not apply steps 8 to 12.  It does not refetch a key set
   for a stored verdict: a kid missing from the stored copy is a
   failure.  Verdicts that the deployed implementation issued before
   09:12 UTC on 9 October 2026 may lack request.currency, may contain
   Unicode noncharacters, and may be up to about 94,000 characters long;
   a party checking one of them as a record applies step 6 without the
   currency requirement, and step 1 with a size bound that admits them.
   Unless the party obtained the copy of the JWK Set itself, a
   successful check shows only that the verdict matches the key set that
   the record keeper stored (Section 10.1).

Dias                      Expires 12 April 2027                [Page 23]
Internet-Draft           Agent Payment Verdicts             October 2026

7.  What a Verdict Asserts

   A verdict that passes steps 1 to 6 of Section 6 is a statement,
   signed by the holder of the signing key, that it evaluated a payment
   request with the stated agent, amount, currency, recipient, and
   category against the named mandate (none, for "deny_no_mandate") and
   reached the stated verdict code.  For a verdict without supersedes,
   iat is the time of that evaluation; for an "allow" that carries
   supersedes, the evaluation took place when the superseded "review"
   verdict was issued, some of its checks were repeated at approval, and
   iat is the time of the operator's approval (Section 10.12).  The
   signature shows that the statement was made, not that it is correct
   (Section 10.1).  In the terms used on the audit mailing list [AUDIT],
   a verdict is an attestation, not a record that a relying party can
   recompute: neither the mandate's limits nor the history behind the
   rolling 30-day limit is in it.  A verdict does not show:

   *  that an end user consented: no user key is involved;

   *  that the operator or the agent authorized the payment: neither
      signs the token, so it is not evidence of either's authorization;

   *  that the operator approved the recipient (Section 10.3);

   *  that the category describes what is being bought: it is a label
      supplied with the request, and the relying party has nothing to
      compare it with;

   *  the unit of request.amount: the issuer does not interpret it, and
      an operator's mandates can use a different unit from the relying
      party's payment record (Section 4.6);

   *  that the named agent made the request: in the deployed
      implementation, a request made with an operator-wide credential
      names the agent in its body;

   *  which operator requested it, or that the operator is the party
      paying the relying party (Section 10.2);

   *  that the payment was made, settled, or delivered, or that funds
      exist;

   *  which payment protocol or order it was evaluated for
      (Section 4.7);

   *  whether the operator's systems block payments that are not allowed
      (Section 4.5);

Dias                      Expires 12 April 2027                [Page 24]
Internet-Draft           Agent Payment Verdicts             October 2026

   *  that the mandate is still in force when the verdict is verified:
      an "allow" remains valid until exp even if the mandate is revoked
      after it was issued, and the relying party has no way to learn of
      the revocation from the issuer;

   *  that the payment is not one of several, each within the per-
      transaction limit and below the review threshold, that together
      make up a larger purchase;

   *  that a collection of verdicts is complete: verdicts are returned
      only to the operator that requested them, through its API keys and
      webhook endpoints, and an operator's denial of a review produces
      no verdict.

8.  Versioning and Extensibility

   The token carries no version number, and the format has no mechanism
   for signalling a change.  Verifiers detect features by the presence
   of claims.  An issuer can add private claims and members of request,
   which verifiers ignore if they do not understand them (Section 4.2),
   and verdict codes, which verifiers treat as "do not settle"
   (Section 4.5).

   Because verifiers ignore private claims they do not understand, a new
   private claim that narrows when a verdict may be relied on constrains
   only verifiers updated to check it; until every relying party checks
   it, a verdict carrying it is accepted where it was not meant to be.
   Adding "aud" is incompatible in the other direction: verifiers that
   apply Section 4.1.3 of [RFC7519] without a configured audience reject
   every verdict that carries it.  Adding either kind of claim is
   therefore an incompatible change, as are removing a claim and
   changing a claim's type or meaning.  Explicit typing alone would not
   make such a version fail at verifiers built to this document, which
   do not check typ (Section 6, step 2); a new issuer identifier would
   (step 4).  The deployed implementation announces changes that
   verifiers have to act on in its documentation [SAIFURO-VERIFY], with
   the date from which they apply.

9.  Implementation Status

   This section is to be removed before publishing as an RFC.

   This section records the status of known implementations of the
   format described in this document at the time of posting of this
   Internet-Draft, and is based on a proposal described in [RFC7942].
   The description of implementations in this section is intended to
   assist the IETF in its decision processes in progressing drafts to
   RFCs.  Please note that the listing of any individual implementation

Dias                      Expires 12 April 2027                [Page 25]
Internet-Draft           Agent Payment Verdicts             October 2026

   here does not imply endorsement by the IETF.  Furthermore, no effort
   has been spent to verify the information presented here that was
   supplied by IETF contributors.  This is not intended as, and must not
   be construed to be, a catalog of available implementations or their
   features.  Readers are advised to note that other implementations may
   exist.

   According to [RFC7942], "this will allow reviewers and working groups
   to assign due consideration to documents that have the benefit of
   running code, which may serve as evidence of valuable experimentation
   and feedback that have made the implemented protocols more mature.
   It is up to the individual working groups to use this information as
   they see fit".

   Note to the RFC Editor: please also remove the reference to
   [RFC7942].

9.1.  Saifuro

   Organization:  Saifuro LLC.  The author is its founder and chief
      executive.

   Description:  An authorization service for agent-initiated payments.
      It issues a verdict in the format of Section 4 for every evaluated
      request, in a test environment and a production environment.

   Issuer and keys:  Issuer identifier https://verdicts.saifuro.com; JWK
      Set at https://verdicts.saifuro.com/.well-known/jwks.json, served
      through a content delivery network and holding one production key
      and one test key.

   Coverage:  Section 4 and Section 5, with the departures from
      [RFC8725], [RFC7493], and [RFC8615] stated in this document.

   Version compatibility:  This document (-00).  Verdicts issued since
      09:12 UTC on 9 October 2026 carry request.currency; verdicts
      issued before then may lack it, and all of them have expired.

   Implementation experience:  Limits are enforced atomically
      (Section 10.13).  Approving a review repeats the checks described
      in Section 10.12.  No key rotation has taken place yet.  The event
      tokens of Section 10.14 resemble Security Event Tokens [RFC8417]
      but do not follow that specification.

   Level of maturity:  Early deployment; in service since September
      2026.  Issuing verdicts requires an account with Saifuro.
      Verifying them requires no account.

Dias                      Expires 12 April 2027                [Page 26]
Internet-Draft           Agent Payment Verdicts             October 2026

   Licensing:  Proprietary service.  Verification uses unmodified open-
      source JOSE libraries.  The public documentation [SAIFURO-VERIFY]
      gives starting examples for jose (JavaScript), PyJWT (Python), and
      jwx (Go); they do not implement every step of Section 6, and the
      documentation lists the main checks they leave to the relying
      party.

   Documentation:  [SAIFURO-VERIFY], [SAIFURO-LIMITS].

   Test vectors:  [SAIFURO-VECTORS]: 138 tokens with their expected
      results, covering each step of Section 6 and Section 6.2, signed
      with the example key of Appendix A and further published test
      keys.

   Contact:  Ithelia Dias, ithelia.dias@saifuro.com.

   Last updated:  9 October 2026.

10.  Security Considerations

   The security considerations of [RFC7515], [RFC7519], and [RFC8725]
   apply.  [I-D.ietf-oauth-rfc8725bis], which would obsolete [RFC8725],
   states that a typ value of "JWT" is not effective explicit typing
   (Section 3.11 of [I-D.ietf-oauth-rfc8725bis]) and extends the
   audience requirement to issuers that may issue JWTs for more than one
   relying party in the future (Section 3.9 of
   [I-D.ietf-oauth-rfc8725bis]); both widen the departures described in
   Section 10.6 and Section 10.7.

10.1.  Trust in the Issuer and Its Key Set

   A verdict proves that the issuer made a statement, not that the
   statement is correct.  An issuer that is compromised, misconfigured,
   or acting in bad faith can sign approvals for requests outside any
   mandate.  How a relying party decides to accept an issuer is outside
   the scope of this document.

   The JWK Set is not signed.  Whoever can change what is served at its
   configured location, including through control of the domain, its
   DNS, certificate issuance, or a TLS-terminating intermediary such as
   a content delivery network in front of the server, can add a key and
   mint verdicts that every verifier accepts.  Protecting that endpoint
   is equivalent to protecting the signing keys.  A copy of the JWK Set
   kept with stored verdicts (Section 5.5) is the relying party's own
   record; it is not evidence to a third party that a key belonged to
   the issuer, because the deployed implementation neither signs its JWK
   Set nor publishes a history of retired keys.

Dias                      Expires 12 April 2027                [Page 27]
Internet-Draft           Agent Payment Verdicts             October 2026

10.2.  Who Stands Behind a Verdict

   A verdict is evidence about one operator's policy, not about the
   payer.  The token names no operator, and any operator that the issuer
   serves can configure a mandate that allows any recipient and amount,
   and then obtain a valid "allow" under it.  A relying party that needs
   to know which operator stands behind a payment agrees the mandate
   identifiers with that operator out of band and accepts only verdicts
   whose mandate claim is one of them (Section 6, step 8).  In the
   deployed implementation, mandate identifiers are assigned by the
   issuer and are not reused.

   The policy_version claim is the same on every verdict of one operator
   and is shared only with operators whose accounts were created on the
   same day.  It links verdicts to an operator without reliably
   identifying one, and relying parties MUST NOT use it as an operator
   identifier.

   The member request.agent is unique only among one operator's agents
   in one environment, and in the deployed implementation it is "agt_"
   followed by a name the operator chooses, so any operator can obtain
   verdicts that name the same agent identifier as another operator.
   Relying parties MUST NOT use request.agent to identify an operator or
   a payer; step 8 of Section 6 uses the mandate claim for that.

10.3.  Payee Substitution

   Mandates in the deployed implementation do not restrict recipients.
   An agent that is compromised or misled, or anyone holding its
   credentials, can obtain an "allow" for a recipient of its choosing
   within the mandate's limits, and a relying party controlled by that
   recipient finds that every step of Section 6 passes.  Verdicts
   therefore do not defend against payee substitution; an operator that
   needs that defence applies its own controls to the recipients its
   agents request.  Restricting recipients in mandates is an open issue
   (Appendix B).

   The issuer accepts as recipient (up to 1,024 characters) or category
   (up to 128) any non-empty string of Unicode characters other than
   noncharacters, including characters that render invisibly, reorder
   text, or resemble other characters, and an operator approving a
   review is shown the strings as the agent supplied them.  An approval
   can therefore be obtained for a recipient that looks like another.
   Step 11 of Section 6 does not help: it compares exactly, and the
   recipient that benefits is the one the token names.

Dias                      Expires 12 April 2027                [Page 28]
Internet-Draft           Agent Payment Verdicts             October 2026

10.4.  Bearer Tokens

   A verdict is a bearer token.  It is not bound to a key held by the
   agent or the operator, it has no "cnf" claim [RFC7800], and nothing
   in it identifies the party presenting it, the payer, or the order.
   Anyone who obtains an unused "allow" before it expires, such as the
   agent's runtime, an intermediary between the agent and the relying
   party, anyone who can read a log that recorded it, or a receiver of
   an event token that carries it (Section 10.14), can present it first,
   with a payment of the same amount and currency to the same recipient;
   the legitimate presentation then fails step 12 of Section 6.  A
   relying party that releases goods, services, or funds on a verdict
   has to bind the order to the payer by its own means.  Verdicts SHOULD
   be carried only over authenticated, confidential channels.  Agents,
   operators, and relying parties SHOULD NOT log unexpired "allow"
   verdicts in full; jti or nonce identifies a verdict in a log without
   making it presentable.  Proof of possession is an open issue
   (Appendix B).

10.5.  Algorithms and Signatures

   Only ES256 is used and accepted.  Verifiers pin it in configuration
   and reject "none", every HMAC algorithm, including when a public key
   is offered as the HMAC secret, and any spelling that differs in case
   (Section 4.1.1 of [RFC7515], Section 2.1 of [RFC8725], Section 3.1 of
   [RFC8725]).  Every key in the set is published with "alg" "ES256".

   Section 3.2 of [RFC8725] says that JWT libraries should implement
   ECDSA using the deterministic approach of [RFC6979].  The deployed
   issuer does not: it signs through OpenSSL 3.0, which derives the per-
   signature value from fresh random bytes mixed with the private key
   and the message digest.  Its signatures are therefore not
   deterministic and do not reproduce the test vectors of [RFC6979]; the
   mixing is intended to keep a failure of the random number generator
   from exposing the key.  Verifiers are unaffected: deterministic and
   randomized signatures verify identically.

10.6.  Cross-JWT Confusion and Explicit Typing

   Verdicts and event tokens share the key, the issuer identifier, and
   the typ value "JWT", so Section 2.8 of [RFC8725] requires a
   mitigation.  This format uses the second strategy listed in
   Section 3.12 of [RFC8725], different required claims: a verdict
   requires exp, verdict, nonce, and request, which event tokens lack,
   and step 6 of Section 6 rejects tokens that carry a type claim or an
   "evt_" jti.  That step is the mutually exclusive validation rule that
   Section 3.12 of [RFC8725] requires for verdict verifiers; it rests on
   claims rather than on the header.  Event receivers that require type

Dias                      Expires 12 April 2027                [Page 29]
Internet-Draft           Agent Payment Verdicts             October 2026

   and data, which verdicts lack, complete the mutual exclusion.

   The format does not use explicit typing, which Section 3.11 of
   [RFC8725] recommends for new kinds of JWT.  With explicit typing, the
   distinction would rest on the header rather than on each verifier
   implementing step 6.  Adopting it is an open issue (Appendix B).

   Test and production verdicts are the same kind of JWT from different
   environments, and differ only in the signing key.  The only rule that
   excludes test verdicts is step 3 of Section 6, which reads a prefix
   of kid.  JOSE leaves the structure of kid unspecified (Section 4.1.4
   of [RFC7515]), so no generic JWT library applies this rule, and a
   relying party that omits step 3 accepts test verdicts.  A verifier
   used only for testing does not reject production verdicts.  A
   separate issuer identifier and JWK Set for test verdicts is an open
   issue (Appendix B).

10.7.  Audience

   Verdicts have no "aud" claim.  Section 3.9 of [RFC8725] requires one
   when an issuer issues JWTs intended for more than one relying party,
   which is the case here; this format does not meet that requirement.
   The same section requires a relying party to reject a JWT that has no
   audience value; a relying party that follows Section 6 accepts
   verdicts without one, and so departs from that requirement as well.
   The member request.recipient is not an audience in the sense of
   Section 4.1.3 of [RFC7519]: it names the payee, which the agent
   chooses and the issuer does not check.  When the relying party is the
   payee, step 11 of Section 6 rejects a verdict presented for any other
   payee.  When the relying party is an intermediary acting for the
   payee, such as a payment service provider or an escrow release
   process, nothing in the token names it, and two intermediaries
   settling for the same payee run separate nonce stores and could each
   accept the same verdict within its lifetime.  A relying party SHOULD
   make sure that the identifier it compares against is specific to it
   and not shared with other parties.  Adding an audience claim is an
   open issue (Appendix B).

10.8.  Replay and Signature Malleability

   A verdict is valid for 300 seconds, and a relying party accepts its
   nonce only once (Section 6, step 12); relying parties that do not
   share a nonce store can each accept it (Section 10.7).

   ECDSA signatures are malleable: if (R, S) is a valid signature, so is
   (R, n - S), where n is the order of the P-256 group.  A verifier
   whose base64url decoder ignores unused trailing bits also accepts
   several spellings of the same signature segment.  The same signed

Dias                      Expires 12 April 2027                [Page 30]
Internet-Draft           Agent Payment Verdicts             October 2026

   claims can therefore appear in more than one token string, and
   verifiers MUST NOT use the token string, or a hash of it, as the
   replay key.

   A verifier that recorded the nonce before comparing the verdict with
   its payment record would let anyone with a copy of a verdict burn it
   by presenting a mismatched payment; this is why step 12 comes last.

   The deployed implementation supports idempotent retries: an operator
   that retries an authorization request with the same Idempotency-Key,
   the same request body, and the same API credential within 24 hours
   receives the stored response, with the identical token and nonce, so
   a retry does not produce a second approval.  A retry after 24 hours
   is a new evaluation with a new nonce, and each "allow" counts toward
   the mandate's rolling 30-day limit.

10.9.  Clock Skew

   With a 300-second lifetime and a 60-second skew allowance, a verifier
   accepts a verdict until its own clock reads iat + 360, and rejects an
   iat more than 60 seconds ahead of its clock.  Step 7 of Section 6
   assumes a synchronized clock.

10.10.  Key Compromise

   There is no per-token revocation.  The short lifetime of a verdict
   bounds the use of a stolen verdict, and removal from the JWK Set is
   the response to a stolen key.  A verifier that refreshes on schedule
   stops trusting a removed key within the max-age of the set; one that
   pinned the key, or that keeps using a stale copy, keeps trusting it
   for as long as it does so.  A party holding a compromised signing key
   can mint verdicts with current timestamps until the key is removed,
   and after a compromise, verdicts signed with that key, including
   those kept as records, can no longer be told apart from forgeries.
   How the issuer protects its signing keys is outside the scope of this
   document.

   A verifier that cannot obtain a key for a verdict MUST reject the
   verdict rather than accept it unverified.

10.11.  Amounts and Parsing

   JSON leaves numeric range and precision to implementations, and
   Section 6 of [RFC8259] notes that good interoperability can be
   achieved by implementations that expect no more precision or range
   than binary64 provides; this is why amounts are compared by decimal
   value (Section 4.6; Section 6, step 9).  Step 1 of Section 6 bounds
   the size of tokens; the deployed implementation limits recipient to

Dias                      Expires 12 April 2027                [Page 31]
Internet-Draft           Agent Payment Verdicts             October 2026

   1,024 characters and category and currency to 128 characters each, so
   the verdicts it has issued since 09:12 UTC on 9 October 2026 are
   shorter than 11,000 characters.  Its earlier verdicts could reach
   about 94,000 characters.  Event tokens (Section 10.14) are not
   bounded in this way: an event token that carries a decision also
   carries that decision's verdict and is longer than it.

10.12.  Approval of Held Requests

   An "allow" that carries supersedes records an operator's approval of
   a request held for review.  The format does not state whether the
   mandate was evaluated again at approval time, and nothing in the
   token prevents an issuer from issuing more than one "allow" that
   supersedes the same "review" verdict; such verdicts have different
   nonces, so the replay check in Section 6 does not detect them.  A
   relying party that must not settle against a revoked or expired
   mandate needs to learn of revocations from the operator.  A relying
   party SHOULD record the supersedes value of each "allow" it accepts,
   keep it at least for the review expiry plus the verdict lifetime and
   skew allowance (24 hours and 360 seconds in the deployed
   implementation), and reject a second "allow" that supersedes the same
   verdict.

   In the deployed implementation, approving a review repeats three
   checks whose outcome can have changed since the review: that the
   agent is active, that the mandate is neither revoked nor expired, and
   that the amount, added to every "allow" issued under the mandate in
   the 30 days before the approval, is within the rolling 30-day limit.
   It does not repeat the frequency rule; the category and the per-
   transaction limit cannot have changed, because mandates are not
   edited.  An approval that fails these checks is refused and issues no
   verdict, and a review yields at most one "allow".  Any holder of an
   operator-wide credential can approve a review; the principal named on
   the mandate is recorded but not authenticated.

10.13.  Aggregate Limits

   A verdict records the outcome of one evaluation.  Whether an issuer
   enforces aggregate limits, such as the rolling 30-day limit and the
   frequency rule, across concurrent evaluations is a property of the
   issuer and is not visible in the token.  The deployed implementation
   reads the limits and records each decision in a single database
   transaction.

Dias                      Expires 12 April 2027                [Page 32]
Internet-Draft           Agent Payment Verdicts             October 2026

10.14.  Event Tokens

   The deployed implementation notifies operators of events, such as a
   pending or resolved review, by webhook.  Each event is a JWT with the
   same header, signed with the same key as the verdicts of its
   environment, under the same iss.  Its claims are iss, jti (beginning
   "evt_"), iat, type, and data; it has no exp and no audience, and the
   issuer adds no claim that names the operator; only a "ping" event
   names the endpoint, by the webhook identifier in its data.  A
   "decision.resolved" event carries, inside data, either the decision
   that approves a review, whose verdict member is "allow", together
   with that decision's verdict token, or the review object of a review
   that was denied or expired.  A failed delivery is retried with the
   identical token; the last retry falls due 24 hours after the event is
   created.

   Because all operators' events in one environment are signed with the
   same key under the same iss, a genuine event issued to one operator
   also verifies at another operator's endpoint, at any later time: any
   operator served by the issuer can forward a "decision.resolved" event
   from its own endpoint, carrying an "allow" for a recipient it chose,
   to another operator's endpoint.  Signature checks and deduplication
   on jti do not stop this.  A receiver therefore confirms, through its
   own authenticated access to the issuer or against identifiers from
   its own responses, that an object named in an event is its own before
   acting on it, and bounds how old an event it accepts.  A verdict
   verifier rejects event tokens by step 6 of Section 6 and MUST NOT
   accept one as a verdict.

11.  Privacy Considerations

   Verdicts are signed, not encrypted.  Anyone who sees a token can read
   the agent identifier, which in the deployed implementation contains a
   name the operator chose for the agent; the amount, currency,
   recipient, and category; the mandate identifier; the time of the
   decision; and policy_version, which in the deployed implementation
   contains the date on which the operator's account was created.

   A token does not contain the operator's name or identifier, the end
   user's identity, payment credentials, the operator's metadata, or the
   reason text.  The agent and mandate identifiers are stable across
   verdicts, and policy_version is the same for all of an operator's
   agents, so relying parties that compare the tokens they received can
   link payments made by the same agent, under the same mandate, or by
   different agents of the same operator.

Dias                      Expires 12 April 2027                [Page 33]
Internet-Draft           Agent Payment Verdicts             October 2026

   The token travels through the agent and any intermediary between the
   agent and the relying party.  Operators SHOULD NOT put personal data
   in category, or in recipient beyond what identifies the payee; when
   the payee is a natural person, the recipient identifier is personal
   data and is visible to every party that handles the token.  Relying
   parties SHOULD protect retained verdicts as they protect the payment
   records to which the verdicts relate.

12.  IANA Considerations

   This document has no IANA actions.

   A later version might request registration of the private claim names
   in Section 4.2, of a media type for explicit typing, and of a well-
   known URI suffix for the JWK Set (Appendix B).

13.  References

13.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC3629]  Yergeau, F., "UTF-8, a transformation format of ISO
              10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
              2003, <https://www.rfc-editor.org/info/rfc3629>.

   [RFC7515]  Jones, M., Bradley, J., and N. Sakimura, "JSON Web
              Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May
              2015, <https://www.rfc-editor.org/info/rfc7515>.

   [RFC7517]  Jones, M., "JSON Web Key (JWK)", RFC 7517,
              DOI 10.17487/RFC7517, May 2015,
              <https://www.rfc-editor.org/info/rfc7517>.

   [RFC7518]  Jones, M., "JSON Web Algorithms (JWA)", RFC 7518,
              DOI 10.17487/RFC7518, May 2015,
              <https://www.rfc-editor.org/info/rfc7518>.

   [RFC7519]  Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token
              (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015,
              <https://www.rfc-editor.org/info/rfc7519>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

Dias                      Expires 12 April 2027                [Page 34]
Internet-Draft           Agent Payment Verdicts             October 2026

   [RFC8259]  Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
              Interchange Format", STD 90, RFC 8259,
              DOI 10.17487/RFC8259, December 2017,
              <https://www.rfc-editor.org/info/rfc8259>.

   [RFC8725]  Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token Best
              Current Practices", BCP 225, RFC 8725,
              DOI 10.17487/RFC8725, February 2020,
              <https://www.rfc-editor.org/info/rfc8725>.

   [SEC1]     Certicom Research, "SEC 1: Elliptic Curve Cryptography",
              Standards for Efficient Cryptography, Version 2.0, May
              2009, <https://www.secg.org/sec1-v2.pdf>.

13.2.  Informative References

   [ACP]      OpenAI and Stripe, "Agentic Commerce Protocol: Delegate
              Payment API, version 2026-04-17", April 2026,
              <https://github.com/agentic-commerce-protocol/agentic-
              commerce-
              protocol/blob/17adf494cf8b4bcb41967a0386188b8103316d2f/
              spec/2026-04-17/openapi/openapi.delegate_payment.yaml>.

   [AP2]      Google, "Agent Payments Protocol (AP2) Specification,
              version 0.2", accessed 7 October 2026,
              <https://ap2-protocol.org/ap2/specification/>.

   [AUDIT]    IETF, "audit: discussion of a potential Agent Use of
              Delegation and Interaction Traceability (AUDIT) BoF",
              <https://mailarchive.ietf.org/arch/browse/audit/>.

   [AUTHZEN]  Gazitt, O., Ed., Brossard, D., Ed., and A. Tulshibagwale,
              Ed., "Authorization API 1.0", OpenID Foundation Final
              Specification, 11 January 2026,
              <https://openid.net/specs/authorization-api-1_0.html>.

   [I-D.ietf-oauth-rfc8725bis]
              Sheffer, Y., Hardt, D., and M. B. Jones, "JSON Web Token
              Best Current Practices", Work in Progress, Internet-Draft,
              draft-ietf-oauth-rfc8725bis-10, 21 August 2026,
              <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-
              rfc8725bis-10>.

Dias                      Expires 12 April 2027                [Page 35]
Internet-Draft           Agent Payment Verdicts             October 2026

   [I-D.ietf-oauth-transaction-tokens]
              Tulshibagwale, A., Fletcher, G., and P. Kasselman,
              "Transaction Tokens", Work in Progress, Internet-Draft,
              draft-ietf-oauth-transaction-tokens-11, 30 July 2026,
              <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-
              transaction-tokens-11>.

   [I-D.ietf-webbotauth-httpsig-protocol]
              Meunier, T. and S. Major, "HTTP Message Signatures for
              automated traffic", Work in Progress, Internet-Draft,
              draft-ietf-webbotauth-httpsig-protocol-00, 1 September
              2026, <https://datatracker.ietf.org/doc/html/draft-ietf-
              webbotauth-httpsig-protocol-00>.

   [I-D.kuehlewind-audit-architecture]
              Kühlewind, M. and H. Birkholz, "An Architecture for
              Auditing Agent Delegation and Interactions", Work in
              Progress, Internet-Draft, draft-kuehlewind-audit-
              architecture-01, 7 September 2026,
              <https://datatracker.ietf.org/doc/html/draft-kuehlewind-
              audit-architecture-01>.

   [I-D.laxsharma-pact]
              Sharma, L., "PACT: Co-Signed Task Contracts, Delivery and
              Verdict Records, and Outcome Records for Autonomous
              Agents", Work in Progress, Internet-Draft, draft-
              laxsharma-pact-02, 17 September 2026,
              <https://datatracker.ietf.org/doc/html/draft-laxsharma-
              pact-02>.

   [OIDC-CORE]
              Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and
              C. Mortimore, "OpenID Connect Core 1.0 incorporating
              errata set 2", OpenID Foundation, December 2023,
              <https://openid.net/specs/openid-connect-core-1_0.html>.

   [PSYCHIC]  Madden, N., "CVE-2022-21449: Psychic Signatures in Java",
              19 April 2022, <https://neilmadden.blog/2022/04/19/
              psychic-signatures-in-java/>.

   [RFC2606]  Eastlake 3rd, D. and A. Panitz, "Reserved Top Level DNS
              Names", BCP 32, RFC 2606, DOI 10.17487/RFC2606, June 1999,
              <https://www.rfc-editor.org/info/rfc2606>.

   [RFC6979]  Pornin, T., "Deterministic Usage of the Digital Signature
              Algorithm (DSA) and Elliptic Curve Digital Signature
              Algorithm (ECDSA)", RFC 6979, DOI 10.17487/RFC6979, August
              2013, <https://www.rfc-editor.org/info/rfc6979>.

Dias                      Expires 12 April 2027                [Page 36]
Internet-Draft           Agent Payment Verdicts             October 2026

   [RFC7493]  Bray, T., Ed., "The I-JSON Message Format", RFC 7493,
              DOI 10.17487/RFC7493, March 2015,
              <https://www.rfc-editor.org/info/rfc7493>.

   [RFC7800]  Jones, M., Bradley, J., and H. Tschofenig, "Proof-of-
              Possession Key Semantics for JSON Web Tokens (JWTs)",
              RFC 7800, DOI 10.17487/RFC7800, April 2016,
              <https://www.rfc-editor.org/info/rfc7800>.

   [RFC7942]  Sheffer, Y. and A. Farrel, "Improving Awareness of Running
              Code: The Implementation Status Section", BCP 205,
              RFC 7942, DOI 10.17487/RFC7942, July 2016,
              <https://www.rfc-editor.org/info/rfc7942>.

   [RFC8417]  Hunt, P., Ed., Jones, M., Denniss, W., and M. Ansari,
              "Security Event Token (SET)", RFC 8417,
              DOI 10.17487/RFC8417, July 2018,
              <https://www.rfc-editor.org/info/rfc8417>.

   [RFC8615]  Nottingham, M., "Well-Known Uniform Resource Identifiers
              (URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019,
              <https://www.rfc-editor.org/info/rfc8615>.

   [RFC9111]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
              Ed., "HTTP Caching", STD 98, RFC 9111,
              DOI 10.17487/RFC9111, June 2022,
              <https://www.rfc-editor.org/info/rfc9111>.

   [RFC9396]  Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0
              Rich Authorization Requests", RFC 9396,
              DOI 10.17487/RFC9396, May 2023,
              <https://www.rfc-editor.org/info/rfc9396>.

   [RFC9421]  Backman, A., Ed., Richer, J., Ed., and M. Sporny, "HTTP
              Message Signatures", RFC 9421, DOI 10.17487/RFC9421,
              February 2024, <https://www.rfc-editor.org/info/rfc9421>.

   [RFC9449]  Fett, D., Campbell, B., Bradley, J., Lodderstedt, T.,
              Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of
              Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449,
              September 2023, <https://www.rfc-editor.org/info/rfc9449>.

   [RFC9943]  Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande,
              Y., and S. Lasker, "An Architecture for Trustworthy and
              Transparent Digital Supply Chains", RFC 9943,
              DOI 10.17487/RFC9943, June 2026,
              <https://www.rfc-editor.org/info/rfc9943>.

Dias                      Expires 12 April 2027                [Page 37]
Internet-Draft           Agent Payment Verdicts             October 2026

   [SAIFURO-LIMITS]
              Saifuro LLC, "Limits of a signed verdict", accessed 9
              October 2026,
              <https://docs.saifuro.com/reference/verdict-limits>.

   [SAIFURO-VECTORS]
              Saifuro LLC, "Verdict test vectors", accessed 9 October
              2026,
              <https://docs.saifuro.com/reference/verdict-test-vectors>.

   [SAIFURO-VERIFY]
              Saifuro LLC, "Verifying a verdict", accessed 9 October
              2026,
              <https://docs.saifuro.com/reference/verify-a-verdict>.

   [TAP]      Visa, "Trusted Agent Protocol Specifications", accessed 7
              October 2026, <https://developer.visa.com/capabilities/
              trusted-agent-protocol/trusted-agent-protocol-
              specifications>.

   [X402]     x402 Foundation, "x402 Protocol Specification, Protocol
              Version 2", accessed 7 October 2026, <https://github.com/
              x402-foundation/x402/blob/
              e187dda1ef0c69c85416625342e5bb7c4b857dac/specs/x402-
              specification-v2.md>.

Appendix A.  Example

   This appendix contains a verdict signed with an example key.  The
   private key is published here so that anyone can reproduce and extend
   the example.  It is not a key of any issuer, a token signed with it
   proves nothing, and it MUST NOT be added to a verifier that protects
   real payments.  The issuer identifier is a reserved example domain
   [RFC2606].

A.1.  Example Key

   {
     "kty": "EC",
     "crv": "P-256",
     "x": "50tYIab3ytEcPnb_fuZCPc4cM87aNhpYhOYb9LmSseA",
     "y": "iZho4NBfqRZnM7AgedlHkvEMRU030NPOYGoTv7s2Ls0",
     "d": "34KI9Rx04_gEp_Ljm4-dGFq7O75vEFednnvRwcDdvUc",
     "use": "sig",
     "alg": "ES256",
     "kid": "example-1"
   }

Dias                      Expires 12 April 2027                [Page 38]
Internet-Draft           Agent Payment Verdicts             October 2026

A.2.  Verdict

   The token, with line breaks for display purposes only:

   eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImV4YW1wbGUtMSJ9.eyJ
   pc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwianRpIjoiZGVjXzViMmU5YzQ
   xIiwiaWF0IjoxNzkxMzc0NDAwLCJleHAiOjE3OTEzNzQ3MDAsInZlcmRpY3QiOiJ
   hbGxvdyIsIm1hbmRhdGUiOiJtbmRfN2YzYTBkMTIiLCJwb2xpY3lfdmVyc2lvbiI
   6InBvbF8yMDI2LTA5LTAyLjEiLCJub25jZSI6Im5fOWQwMmM2ZTQxYTdmM2I4NSI
   sInJlcXVlc3QiOnsiYWdlbnQiOiJhZ3RfcHJvY3VyZW1lbnRfMDEiLCJhbW91bnQ
   iOjM0MCwiY3VycmVuY3kiOiJVU0QiLCJyZWNpcGllbnQiOiJ2ZW5kb3I6YWNtZV9
   zYWFzIiwiY2F0ZWdvcnkiOiJzYWFzIn19.5NLM85wfRPdBIBaW_fY_gmgfml5w-0
   KZlVbDj0YUVxa03wiYmqXamfLynH_S_DUkk2j_HTAlorcS3tHdtNvwYA

   Decoded JOSE Header:

   {"alg":"ES256","typ":"JWT","kid":"example-1"}

   Decoded claims, with whitespace added:

   {
     "iss": "https://issuer.example",
     "jti": "dec_5b2e9c41",
     "iat": 1791374400,
     "exp": 1791374700,
     "verdict": "allow",
     "mandate": "mnd_7f3a0d12",
     "policy_version": "pol_2026-09-02.1",
     "nonce": "n_9d02c6e41a7f3b85",
     "request": {
       "agent": "agt_procurement_01",
       "amount": 340,
       "currency": "USD",
       "recipient": "vendor:acme_saas",
       "category": "saas"
     }
   }

A.3.  Checking the Example

   The verdict was issued at 2026-10-07T12:00:00Z and expired at
   12:05:00Z.  A verifier configured with the example key, the issuer
   identifier https://issuer.example, and a payment record of 340.00 USD
   to "vendor:acme_saas", with its clock pinned to 2026-10-07T12:02:00Z
   (Unix time 1791374520), accepts it; for step 8, the mandate
   identifier agreed with the operator is "mnd_7f3a0d12" and the agreed
   unit is major units (US dollars).  With the clock unpinned, it
   rejects the token at step 7 of Section 6, as intended.  A production

Dias                      Expires 12 April 2027                [Page 39]
Internet-Draft           Agent Payment Verdicts             October 2026

   verifier never pins its clock.

   The S component of the example signature is in the upper half of the
   group order, so a verifier that enforces low-S signatures, contrary
   to step 5, rejects this example.

Appendix B.  Open Issues

   1.   Explicit typing.  Use a dedicated typ value for verdicts, such
        as "verdict+jwt", as Section 3.11 of [RFC8725] recommends, and
        register the corresponding media type.

   2.   Audience.  Add an "aud" claim naming the relying party or the
        settlement endpoint, so that the format meets Section 3.9 of
        [RFC8725], and define how the agent learns the value before
        evaluation.

   3.   Proof of possession.  Bind a verdict to a key held by the agent,
        for example with a confirmation claim [RFC7800], so that a copy
        cannot be used by another presenter.

   4.   Environment separation.  Use a separate issuer identifier and
        JWK Set for test verdicts, instead of a kid prefix.

   5.   Operator binding.  Decide whether a verdict should identify the
        operator, and how a relying party would use that identifier.

   6.   Recipient restrictions.  Let a mandate restrict the recipients
        for which an "allow" can be issued.

   7.   Policy identification.  Remove policy_version, or make it, or a
        new claim such as a digest of the mandate as evaluated, identify
        the rules that were applied.

   8.   Claim names.  Register the private claims in the "JSON Web Token
        Claims" registry, or use collision-resistant names.

   9.   Replay identifier. jti is the unique token identifier of
        Section 4.1.7 of [RFC7519], which notes that it can be used to
        prevent replay; the separate nonce claim could be removed.

   10.  Amount representation.  Choose between JSON numbers in a
        constrained decimal form, decimal strings as [RFC7493]
        recommends, and integers in minor units.

   11.  Asset codes.  Define identifiers for assets that have no ISO
        4217 code.

Dias                      Expires 12 April 2027                [Page 40]
Internet-Draft           Agent Payment Verdicts             October 2026

   12.  Enforcement mode.  Decide whether a verdict should state whether
        the issuing environment was enforcing.

   13.  Event tokens.  Profile event tokens as Security Event Tokens
        [RFC8417], with typ "secevent+jwt", an "events" claim, and an
        "aud" naming the operator's endpoint.  [RFC8417] recommends
        against exp in such tokens, and the absence of exp is one of the
        properties that makes an event token fail step 6 of Section 6.

   14.  Deterministic signatures.  Sign with [RFC6979].

   15.  Key set integrity.  Sign the JWK Set or publish a history of
        retired keys, for example through a transparency service
        [RFC9943], so that stored verdicts remain verifiable to third
        parties.

   16.  Amount unit.  State the unit of request.amount in the token, or
        fix it, so that a relying party does not need to agree it out of
        band (Section 4.6).

   17.  JWK Set location.  Register a well-known URI suffix for the JWK
        Set (Section 3 of [RFC8615]), or let relying parties take the
        location from issuer metadata, instead of the unregistered
        "jwks.json".

   18.  Revocation status.  Decide whether relying parties need a way to
        learn that a mandate was revoked after an "allow" was issued
        (Section 7).

   19.  Transport.  Define how a verdict accompanies a payment in HTTP
        and in agent payment protocols such as [X402], [ACP], and [AP2].

   20.  Related formats.  Determine whether a verdict can be expressed
        as a signed form of an [AUTHZEN] evaluation response, or its
        request claim as an "authorization_details" object ([RFC9396],
        which registers that claim in Section 14.2) of a payment type.

Acknowledgments

   The author thanks Nicholas Templeman, whose messages on the audit
   mailing list [AUDIT] set out the distinction between an unsupported
   association and a contradicted one, which Section 6.1 adopts, and the
   binding problem that Section 10.7 describes.

Dias                      Expires 12 April 2027                [Page 41]
Internet-Draft           Agent Payment Verdicts             October 2026

   The author also thanks Nancy Sahu and Gareth Wong, whose proposal on
   the same list, that the charter state, for each verification
   mechanism, what a successful check establishes, under what
   assumptions, and whether an omitted record would be detectable, poses
   the question that Section 7 answers for this format.

   The text of this document was drafted with an AI system (Claude, by
   Anthropic) from the implementation's source code and documentation
   and from the cited specifications, and was checked against them in
   further AI-assisted reviews.  The author has reviewed the whole
   document and is responsible for its content.

Author's Address

   Ithelia Dias
   Saifuro LLC
   Sheridan, WY
   United States of America
   Email: ithelia.dias@saifuro.com
   URI:   https://saifuro.com

Dias                      Expires 12 April 2027                [Page 42]