<?xml version="1.0" encoding="utf-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     docName="draft-fane-opena2a-aap-02"
     ipr="trust200902"
     category="std"
     submissionType="IETF"
     tocInclude="true"
     sortRefs="true"
     symRefs="true"
     version="3">

  <front>
    <title abbrev="AAP">OpenA2A Agent Authorization Protocol (AAP)</title>
    <seriesInfo name="Internet-Draft" value="draft-fane-opena2a-aap-02"/>

    <author fullname="Abdel Fane" initials="A." surname="Fane">
      <organization>OpenA2A</organization>
      <address>
        <postal>
          <country>US</country>
        </postal>
        <email>info@opena2a.org</email>
      </address>
    </author>

    <date year="2026" month="September" day="30"/>

    <area>Security</area>
    <workgroup>Individual Submission</workgroup>
    <keyword>agent authorization</keyword>
    <keyword>AI agents</keyword>
    <keyword>delegation</keyword>
    <keyword>credential isolation</keyword>
    <keyword>behavioral attestation</keyword>

    <abstract>
      <t>This document defines the OpenA2A Agent Authorization Protocol (AAP), a
      protocol for authorization in AI agent systems. AAP provides mechanisms
      for agent identity assertion, scoped capability grants, cross-agent
      delegation, behavioral attestation, cross-organizational federation, and
      revocation propagation. AAP is the authorization complement to agent
      communication protocols such as A2A and the Model Context Protocol, in the
      same way that OAuth 2.0 complements HTTP for web applications.</t>

      <t>AAP has two layers. The token model, defined in this document, specifies
      the AAP credentials and assertions: what they contain, how they are signed,
      and how they are verified. A companion broker and resolution layer
      specifies how an agent obtains and exercises a grant without the credential
      value ever entering the agent's reasoning context. This confinement
      property, that no secret, temporary credential, or backend identifier
      reaches the agent or the model behind it, is the primary design goal of the
      protocol.</t>

      <t>This revision adds a structured, mandatory-to-understand
      "authorization_details" claim with a typed entry registry and a per-type
      attenuation relation for delegation, an "aap_crit" claim naming the
      claims a verifier must understand, a "cnf" claim binding a token to the
      presenter's key, a session label in the behavioral attestation claim, and
      a local grant revocation list.</t>
    </abstract>
  </front>

  <middle>

    <section anchor="introduction">
      <name>Introduction</name>
      <t>AI agent systems present authorization challenges that existing
      protocols such as OAuth 2.0 <xref target="RFC6749"/>, SAML, and OpenID
      Connect were not designed to address. Agents are non-deterministic: the
      same agent with identical permissions can behave differently depending on
      its inputs, conversation history, and model state. Static authorization
      grants cannot account for this behavioral variability.</t>

      <t>A second, agent-specific hazard is credential exposure. An autonomous
      agent that holds a secret in its reasoning context can be induced, through
      prompt injection or tool-output poisoning, to disclose or misuse it. AAP
      therefore treats the confinement of credentials away from the agent's
      reasoning context as a first-class requirement rather than a deployment
      detail.</t>

      <t>AAP introduces six protocol components that together provide
      authorization coverage for agent-to-agent, agent-to-service, and
      human-to-agent interactions:</t>

      <ol spacing="normal">
        <li><t><strong>Agent Identity Token (AIT)</strong>: a cryptographic
        identity assertion.</t></li>
        <li><t><strong>Capability Grant Token (CGT)</strong>: a scoped,
        short-lived authorization.</t></li>
        <li><t><strong>Delegation Assertion (DA)</strong>: cross-agent capability
        delegation.</t></li>
        <li><t><strong>Behavioral Attestation Claim (BAC)</strong>: a real-time
        behavioral state proof.</t></li>
        <li><t><strong>Cross-Organizational Trust Federation</strong>: mutual
        trust between issuing authorities.</t></li>
        <li><t><strong>Revocation Propagation</strong>: federated revocation
        within a bounded interval.</t></li>
      </ol>

      <t>AAP is positioned as the authorization complement to agent
      communication protocols such as A2A <xref target="A2A"/> and the Model
      Context Protocol <xref target="MCP"/>, which convey messages and tool
      invocations but do not themselves define scoped, attested authorization.</t>

      <t>A governing constraint applies to every choice in AAP: the protocol and
      its vocabulary are open, and nothing in AAP requires a vendor, cloud
      provider, or government to surrender control of its own trust root. The
      topology is a trust program of federated, conformant Root Authorities, not
      a single root, the same property that let DNS, TLS, OAuth, and OpenID
      Connect achieve broad deployment.</t>
    </section>

    <section anchor="conventions">
      <name>Conventions and Terminology</name>
      <t>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
      <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
      appear in all capitals, as shown here.</t>

      <t>Some JSON examples in this document carry digest values longer than
      the 72-character line limit; those lines are folded using the single
      backslash strategy of <xref target="RFC8792"/>. The backslash fold
      marker and the leading whitespace of a continuation line are display
      artifacts, not part of the example content.</t>

      <dl spacing="normal">
        <dt>Agent</dt>
        <dd>An AI system that can take actions on behalf of a user or
        organization.</dd>

        <dt>Agent Trust eXtension (ATX)</dt>
        <dd>A signed credential issued by a Registry attesting to an agent's
        identity, code integrity, capabilities, and trust level, as defined in
        <xref target="ATX"/>. The AIT references an ATX by hash.</dd>

        <dt>Agent Security Context (ASC)</dt>
        <dd>Shared state describing an agent's current security posture across
        monitoring components.</dd>

        <dt>Registry / Root Authority</dt>
        <dd>A trust authority that issues ATXs, maintains a transparency log
        <xref target="RFC9162"/>, and computes trust scores. Participants operate
        conformant Root Authorities under the Agent Trust Protocol
        <xref target="ATP"/>.</dd>

        <dt>Broker</dt>
        <dd>A local, operator-controlled component that resolves an abstract
        grant reference to a concrete, scoped action on a resource without
        exposing any credential to the agent, as specified in
        <xref target="AAP-BROKER-PROFILE"/>.</dd>
      </dl>
    </section>

    <section anchor="ait">
      <name>Agent Identity Token (AIT)</name>
      <t>The AIT is a cryptographic assertion of agent identity, analogous to an
      OpenID Connect ID Token. It is presented by an agent to identify itself to
      other agents, services, and infrastructure. An AIT is an identity assertion
      only; it conveys no authorization (see <xref target="sec-trust-authz"/>).</t>

      <t>An AIT is an AAP token in the serialized form of
      <xref target="serialization"/>: a JWT <xref target="RFC7519"/> whose claims
      follow the JWT registry naming convention. The required claims are "iss"
      (the issuing Registry decentralized identifier), "sub" (the agent
      decentralized identifier), "atx_reference" (the SHA-256 of the agent's
      current ATX), "trust_level" (the Registry trust level, an integer from 0 to
      4), "iat" and "exp" (the validity window as NumericDate values, that is,
      seconds since the epoch), and "jti" (a unique token identifier). The
      optional "agent_id", "declared_purpose", and "aap_ver" claims MAY also
      appear.</t>

      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
  "iss": "did:opena2a:authority:opena2a.org",
  "sub": "did:opena2a:agent:acme/orders-reader",
  "agent_id": "aim_orders_reader",
  "atx_reference":
    "sha256:2052879dda15b1ca5e60319e3477a400\
      8412bffdaf3c3566c658795a48cab8fd",
  "declared_purpose": "Reads order records for reporting",
  "trust_level": 4,
  "iat": 1780315200,
  "exp": 1780318800,
  "jti": "1c9f2e8a7b6d5c4e3f2a1b0c9d8e7f6a"
}
]]></sourcecode>

      <t>No reference implementation mints AITs yet; the claim schema and this
      generated example pin the form for implementers.</t>

      <t>AIT verification MUST be local. The verifier checks the signature
      against the issuer's public key, distributed via the trust anchor
      mechanism. No network call to a Registry is required at verification
      time.</t>
    </section>

    <section anchor="cgt">
      <name>Capability Grant Token (CGT)</name>
      <t>The CGT is a short-lived, scoped authorization token, analogous to an
      OAuth 2.0 access token <xref target="RFC6749"/>. It authorizes a specific
      capability exercise under fine-grained authorization constraints. In a
      broker deployment <xref target="AAP-BROKER-PROFILE"/>, the CGT is what the
      broker mints from a verified ATX before exchanging it for a downstream
      credential.</t>

      <t>The CGT claim set is ratified byte-for-byte from the reference broker
      implementation. The required claims are "iss" (the minting broker's issuer
      identifier), "sub" (the agent decentralized identifier, taken from the
      verified ATX and never from agent input), "aud" (the downstream audience or
      resource), "scope" (the downstream authorization scope as a string, for
      example "orders.read"), "trust_class" (the abstract ATX capability
      exercised for this grant, in "class:action" form, for example
      "acme.com/orders:read", a domain-prefixed namespace per AIP Section 4.1 <xref target="AIP"/>),
      "issuer_chain" (the ATX
      issuer chain), "trust_level" (an integer from 0 to 4), "iat" and "exp" (the
      validity window, where "exp" minus "iat" is the policy time-to-live), and
      "jti". The "authorization_details", "aap_crit", and "cnf" claims
      (<xref target="cgt-authz"/>, <xref target="cgt-crit"/>, and
      <xref target="cgt-cnf"/>) are OPTIONAL in form and mandatory to
      understand when present; no known implementation mints them as of the date of
      this revision. The "intent_verified", "max_uses", and "context_required"
      claims are OPTIONAL and are not minted by the v1 reference. The
      "fga_constraints" claim of the previous revisions is deprecated: it is
      replaced by "authorization_details", no known implementation minted it, and it
      remains defined only so that tokens conforming to the previous revisions
      keep validating; a verifier ignores it. As of the date of this revision,
      both aap-conformance <xref target="AAP-CONFORMANCE"/> reference verifiers
      match "trust_class" against "^[a-z0-9_-]+:[a-z0-9_-]+$", a pattern that
      admits no domain prefix; the JSON examples in this document carry the
      unprefixed "orders:read".</t>

      <sourcecode type="json"><![CDATA[
{
  "iss": "https://broker.acme.example",
  "sub": "did:opena2a:agent:acme/orders-reader",
  "aud": "https://api.orders.internal",
  "scope": "orders.read",
  "trust_class": "orders:read",
  "issuer_chain": ["did:opena2a:authority:opena2a.org"],
  "trust_level": 4,
  "iat": 1780315200,
  "exp": 1780315500,
  "jti": "9f8e7d6c5b4a39281706f5e4d3c2b1a0"
}
]]></sourcecode>

      <t>In a broker deployment the CGT is used as the OAuth 2.0 Token Exchange
      <xref target="RFC8693"/> "subject_token" with a "subject_token_type" of
      "urn:ietf:params:oauth:token-type:jwt", so the downstream authorization
      server verifies it as a standard JWT against the broker's published key
      material.</t>

      <t>A CGT has a bounded time-to-live. This document defines three tiers;
      profiles MAY define others:</t>
      <dl spacing="compact">
        <dt>STANDARD</dt><dd>4 hours.</dd>
        <dt>PRIVILEGED</dt><dd>30 minutes.</dd>
        <dt>SUPER_PRIVILEGED</dt><dd>15 minutes, no renewal; human approval
        REQUIRED.</dd>
      </dl>

      <section anchor="cgt-authz">
        <name>Authorization Details</name>
        <t>The "authorization_details" claim is the claim of that name defined
        in <xref target="RFC9396"/>: an array of objects, each with a REQUIRED
        "type" member naming an entry type from the registry below, plus the
        members that type defines. It is the structured, fine-grained form of
        the grant. It is mandatory to understand: whenever it is present it
        MUST be named in "aap_crit" (<xref target="cgt-crit"/>), and a verifier
        that does not implement it MUST reject the token.</t>

        <t>The "scope" and "trust_class" claims stay REQUIRED so that
        verifiers built on <xref target="RFC8693"/> and OpenID Connect, which
        understand only the scope string, keep working. Within one token,
        "authorization_details" MUST fall inside what "scope" and "trust_class"
        permit: every entry's locations and actions MUST be ones the scope
        string already allows, and no entry may name a capability outside the
        trust class. A verifier that understands "authorization_details"
        enforces the intersection; a verifier that understands only "scope"
        enforces "scope"; neither ever grants more than "scope" alone would. A
        producer MUST NOT emit "authorization_details" toward a verifier that
        has not advertised support for every entry type the token carries,
        because a verifier without "aap_crit" support would treat the token as
        an unconstrained baseline token. The advertisement is the set of entry
        types the counterparty understands, with the semantics of the
        "authorization_details_types_supported" metadata of
        <xref target="RFC9396"/>, not a boolean. Both aap-conformance <xref target="AAP-CONFORMANCE"/>
        reference verifiers ("verifiers/python/verify.py",
        "verifiers/node/verify.mjs") implement "aap_crit"; that repository's
        "conformance.json" is the record of what they verify.</t>

        <t>The initial entry type registry has seven types. The wire value of
        "type" is a URI, "https://specs.opena2a.org/aap/types/" followed by the
        short name below; the short name is the registry key and the name used
        in prose. Member names inside an entry are camelCase; "type",
        "locations", "actions", "datatypes", "identifier", and "privileges" are
        the common members of <xref target="RFC9396"/> and keep their
        registered spelling. Every type that can carry data out of a session
        ("mcp_tool", "peer_agent", "model", "network", and "data" with a write
        action) carries an "egressCeiling" member, a set of labels; when absent
        it is the empty set. Every type MAY carry "requiresApproval", a boolean;
        when true, the broker admits the entry only through its escalation hook
        and denies it where no hook exists. Unless a member says otherwise, an
        absent set member means unbounded and an absent identity member is not
        permitted.</t>

        <dl spacing="normal">
          <dt>mcp_tool</dt>
          <dd>"serverId" (a decentralized identifier or a "sha256:" key
          fingerprint), OPTIONAL "serverAtx" (a "sha256:" ATX reference),
          "tools" (an array of tool names), OPTIONAL "argumentConstraints" (an
          object keyed by tool name whose values map argument names to
          constraints), OPTIONAL "schemaHash" (a "sha256:" digest of the pinned
          tool schema), OPTIONAL "egressCeiling". The tool servers and tools
          the agent may call; connecting to a server outside the grant is
          drift.</dd>
          <dt>skill</dt>
          <dd>"identifier", "version", "contentHash" (a "sha256:" digest). A
          skill the agent may load, pinned to a version and content.</dd>
          <dt>peer_agent</dt>
          <dd>"peerDid", "direction" (an array holding one or both of
          "outbound" and "inbound"), "subDelegationDepth" (an integer greater
          than or equal to 0), OPTIONAL "egressCeiling". A peer the agent may
          delegate to or accept delegation from.</dd>
          <dt>model</dt>
          <dd>"endpoint" (the URI or decentralized identifier of the model
          endpoint), OPTIONAL "models" (an array of model identifiers),
          OPTIONAL "egressCeiling". The model endpoints the agent may send
          context to.</dd>
          <dt>network</dt>
          <dd>"destinations" (an array of host or host:port values; a leading
          "*." matches subdomains), "tlsRequired" (a boolean), OPTIONAL
          "egressCeiling". The network destinations the agent may reach.</dd>
          <dt>data</dt>
          <dd>"locations", "actions" (where "read" and "list" are read actions
          and every other action is a write action), OPTIONAL "fieldsAllowed"
          and "fieldsDenied" (arrays of field paths), OPTIONAL "labelCeiling"
          (a set of labels; absent means the empty set), OPTIONAL
          "egressCeiling" (applies when "actions" contains a write action).
          The data the agent may read or write, down to the field, and the
          labels it is cleared for.</dd>
          <dt>budget</dt>
          <dd>At least one of "spend" (an object with a decimal string "amount"
          and an ISO 4217 "currency"), "rate" (an object with an integer "max"
          and an integer "windowSeconds"), "maxUses", "concurrency", and
          "tokenCap" (an object with integer "input" and "output" members,
          either of which MAY be omitted). The resource budget of the grant; a
          budget entry carries no data and has no egress ceiling.</dd>
        </dl>

        <t>A verifier that encounters an entry type it does not implement MUST
        reject the token. New types are added by a revision of this document
        until the registry of <xref target="iana"/> exists.</t>

        <t>The label terms used by this document are defined here; these
        definitions are normative. A label is an opaque string naming a
        sensitivity class. A label set is a set of labels; labels are sets, not levels,
        because two fields can carry incomparable labels and a session that has
        read both must be treated as carrying both. A field with label set L
        is admissible under a ceiling C only if L is a subset of C. The session
        is the agent's context at a broker. The session label is the union of
        the label sets of every field admitted into that context so far; it
        only grows within a session, is keyed by the subject in the agent
        security context, carries across every CGT and DA minted for that
        subject, and is reset only by a deployment-defined context reset that
        is recorded there; a deployment that issues data grants MUST define
        that reset. A CGT lifetime is the minimum session, not its bound. An
        entry with an egress ceiling E admits the session's
        data out only if the session label is a subset of E; the default E is
        the empty set. Residency is a label family, so the rules that govern a
        health record class also govern data that may not leave a region.</t>
      </section>

      <section anchor="cgt-crit">
        <name>Mandatory-to-Understand Claims</name>
        <t>JWT defines a "crit" header parameter for header members but no
        equivalent for claims. The "aap_crit" claim is an array of claim names
        the verifier MUST understand in order to accept the token. A verifier
        that encounters a name in "aap_crit" that it does not implement MUST
        reject the token. A verifier MUST also reject a token whose "aap_crit"
        names a claim that is not present in the token, and a token whose
        "aap_crit" is present but empty. "aap_crit" MUST NOT name the baseline
        claims listed above. "authorization_details" MUST be listed whenever it
        is present. "cnf" MUST be listed whenever it is present, because a
        verifier that ignores "cnf" accepts the token as a bearer token. Every
        other claim is optional to ignore.</t>
      </section>

      <section anchor="cgt-cnf">
        <name>Proof of Possession</name>
        <t>The "cnf" claim <xref target="RFC7800"/> binds a CGT or DA to the
        presenter's key, so that a token seen in transit is not a credential.
        "cnf" carries exactly one of "jwk" (the public key itself, per
        <xref target="RFC7800"/>) or "jkt" (the base64url SHA-256 JWK
        thumbprint of <xref target="RFC7638"/>, as registered as a confirmation
        method by <xref target="RFC9449"/>). The bound key is the key the
        presentation binding step of the broker profile
        <xref target="AAP-BROKER-PROFILE"/> verified: the ATX subject key where
        the credential carries one (a later revision of the ATX format; the
        current ATX 1.1 format carries no subject key), otherwise the key
        registered for the agent's decentralized identifier. The presentation
        proof formats per binding are defined in the broker profile: operating
        system peer credentials on a local socket, an HTTP message signature
        <xref target="RFC9421"/> on HTTP, and a signed challenge on the A2A and
        MCP bindings. The presenter is the agent that presents the token to a
        broker: the "sub" of a CGT, the delegatee of a DA. A CGT the minting
        broker uses as its own assertion toward a downstream (the Assume and
        Exchange modes of the broker profile) is not presented in this sense;
        "cnf" on such a token is not verified by the downstream.</t>

        <t>"cnf" is REQUIRED on every CGT or DA that is presented by an agent to
        any party other than the broker that minted it. On a local socket
        binding, where the token never leaves the minting broker and the
        presenter is bound by operating system peer credentials, "cnf" MAY be
        omitted. A verifier that receives a token with "cnf" MUST verify the
        presenter's proof against the bound key and MUST reject the token
        otherwise. As of the date of this revision no known implementation mints
        "cnf", and the reference broker binds no presentation.</t>
      </section>

      <section anchor="cgt-example">
        <name>Example With Authorization Details</name>
        <t>The following generated claim set carries one "data" entry, one
        "budget" entry, "aap_crit", and "cnf" bound by thumbprint to a
        published presenter test key.</t>

      <sourcecode type="json"><![CDATA[
{
  "iss": "https://broker.acme.example",
  "sub": "did:opena2a:agent:acme/orders-reader",
  "aud": "https://api.orders.internal",
  "scope": "orders.read",
  "trust_class": "orders:read",
  "issuer_chain": ["did:opena2a:authority:opena2a.org"],
  "trust_level": 4,
  "authorization_details": [
    {
      "type": "https://specs.opena2a.org/aap/types/data",
      "locations": ["https://api.orders.internal/orders"],
      "actions": ["read"],
      "fieldsAllowed": ["id", "status", "total"],
      "fieldsDenied": ["customer.email"],
      "labelCeiling": ["internal"]
    },
    {
      "type": "https://specs.opena2a.org/aap/types/budget",
      "maxUses": 100,
      "rate": {"max": 60, "windowSeconds": 60}
    }
  ],
  "aap_crit": ["authorization_details", "cnf"],
  "cnf": {"jkt": "HlHgCcjrhbeyw80VMef51yPwhyRqjiwLdwSLRqo7hSI"},
  "iat": 1780315200,
  "exp": 1780315500,
  "jti": "c3d4e5f6a7b8091a2b3c4d5e6f708192"
}
]]></sourcecode>
      </section>
    </section>

    <section anchor="da">
      <name>Delegation Assertion (DA)</name>
      <t>The DA enables cross-agent capability delegation, analogous to OAuth 2.0
      Token Exchange <xref target="RFC8693"/>. A delegatee's capability scope
      MUST NOT exceed the delegator's scope. The exchange mode of the broker
      profile is a realization of the DA over <xref target="RFC8693"/>.</t>

      <t>A DA is subject to the following constraints:</t>
      <ul spacing="normal">
        <li>A maximum delegation depth limits the length of a delegation
        chain.</li>
        <li>The delegator's ATX hash is embedded to preserve an audit trail.</li>
        <li>Scope is cryptographically bounded and MUST NOT be broadened by a
        delegatee.</li>
      </ul>

      <t>A DA is an AAP token in the form of <xref target="serialization"/>: the
      CGT claim set plus the delegation members of <xref target="RFC8693"/>. Here
      "sub" is the delegatee; "act" carries the delegating agent as
      {"sub": delegator}, with nested "act" objects expressing a chain, innermost
      actor first; "max_depth" bounds further delegation; and "delegator_atx"
      embeds the delegator's ATX hash for the audit trail. The delegatee's "scope"
      and "trust_class" MUST be equal to or a subset of the delegator's.</t>

      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
  "iss": "https://broker.acme.example",
  "sub": "did:opena2a:agent:acme/reporting-bot",
  "aud": "https://api.orders.internal",
  "scope": "orders.read",
  "trust_class": "orders:read",
  "issuer_chain": ["did:opena2a:authority:opena2a.org"],
  "trust_level": 4,
  "act": { "sub": "did:opena2a:agent:acme/orders-reader" },
  "max_depth": 1,
  "delegator_atx":
    "sha256:2052879dda15b1ca5e60319e3477a400\
      8412bffdaf3c3566c658795a48cab8fd",
  "iat": 1780315200,
  "exp": 1780315500,
  "jti": "4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d"
}
]]></sourcecode>

      <t>The v1 reference realizes delegation through the broker profile's
      Exchange mode, where the broker assertion is the subject token of the
      <xref target="RFC8693"/> exchange; it does not yet mint standalone DAs with
      an "act" chain.</t>

      <section anchor="da-attenuation">
        <name>Attenuation</name>
        <t>Delegation attenuates: a DA can only carry less than the delegator's
        grant. For "authorization_details" this is made mechanical by a
        "narrower than or equal to" relation defined per entry type. An entry
        of the delegatee is narrower than or equal to an entry of the delegator
        of the same "type" when every member of the delegatee's entry is
        narrower than or equal to the corresponding member under the member
        kind: identity members ("serverId", "serverAtx", "identifier",
        "version", "contentHash", "schemaHash", "peerDid", "endpoint") are
        equal, and a hash the delegator left open MAY be pinned by the
        delegatee; allow-set members ("locations", "actions", "datatypes",
        "privileges", "tools", "models", "destinations", "direction",
        "fieldsAllowed", "labelCeiling", "egressCeiling") are a subset, where an
        absent allow set in the delegator means unbounded except for
        "labelCeiling" and "egressCeiling", where absent means the empty set,
        and an absent allow set in the delegatee inherits the delegator's
        value, and where the subset of "destinations" is evaluated by pattern
        coverage (each delegatee element equals a delegator element or matches
        a delegator "*." pattern, and a delegatee pattern is covered only by an
        equal or broader delegator pattern); deny-set members ("fieldsDenied")
        are a superset; bound members ("subDelegationDepth", "maxUses",
        "concurrency", the "max" of "rate", the "amount" of "spend" in the same
        currency, and the members of "tokenCap") are less than or equal, with
        the "windowSeconds" of "rate" greater than or equal for the same or a
        smaller "max", with "subDelegationDepth" strictly less because the
        delegatee is one delegation deeper, and with a "spend" in a currency
        the delegator does not carry not comparable, which makes the entry an
        orphan; restriction flags ("tlsRequired", "requiresApproval") stay true
        when the delegator's is true; and constraint objects
        ("argumentConstraints") carry every constraint the delegator states,
        JSON-equal, and MAY add constraints for arguments the delegator leaves
        unconstrained (the constraint grammar is deferred to the revision that
        lands broker enforcement).</t>

        <t>A DA is valid only if every entry in its "authorization_details" is
        narrower than or equal to some entry of the same type in the
        delegator's "authorization_details", and no entry lacks such a parent.
        An orphan entry makes the DA invalid. The delegatee's array MAY hold
        fewer entries than the delegator's. When a chain is present, the
        relation is checked link by link. The minting broker MUST check the
        relation at mint time; a verifier that can resolve the delegator's
        grant MUST re-check it; a verifier that cannot MUST NOT treat the DA as
        carrying more than its own entries state. A DA's "max_depth" MUST NOT
        exceed the "subDelegationDepth" of the delegator's "peer_agent" entry
        whose "peerDid" is the DA's "sub", when such an entry exists; a
        "max_depth" of 0 is a terminal delegation. The "cnf" claim of a DA is
        bound to the delegatee's key, since the delegatee is the presenter.</t>

        <t>The following generated claim set delegates the grant of
        <xref target="cgt-example"/> with fewer fields and a smaller budget.</t>

      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
  "iss": "https://broker.acme.example",
  "sub": "did:opena2a:agent:acme/reporting-bot",
  "aud": "https://api.orders.internal",
  "scope": "orders.read",
  "trust_class": "orders:read",
  "issuer_chain": ["did:opena2a:authority:opena2a.org"],
  "trust_level": 4,
  "authorization_details": [
    {
      "type": "https://specs.opena2a.org/aap/types/data",
      "locations": ["https://api.orders.internal/orders"],
      "actions": ["read"],
      "fieldsAllowed": ["id", "status"],
      "fieldsDenied": ["customer.email"],
      "labelCeiling": ["internal"]
    },
    {
      "type": "https://specs.opena2a.org/aap/types/budget",
      "maxUses": 10,
      "rate": {"max": 10, "windowSeconds": 60}
    }
  ],
  "aap_crit": ["authorization_details", "cnf"],
  "cnf": {"jkt": "qI__BOccgAhhH9wob_G7gFVHLKIkS4CutvoSx0bMCY8"},
  "act": { "sub": "did:opena2a:agent:acme/orders-reader" },
  "max_depth": 1,
  "delegator_atx":
    "sha256:2052879dda15b1ca5e60319e3477a400\
      8412bffdaf3c3566c658795a48cab8fd",
  "iat": 1780315200,
  "exp": 1780315500,
  "jti": "d4e5f6a7b8c9012b3c4d5e6f70819203"
}
]]></sourcecode>
      </section>
    </section>

    <section anchor="bac">
      <name>Behavioral Attestation Claim (BAC)</name>
      <t>The BAC is a short-lived signed assertion of an agent's current
      behavioral state, with a time-to-live on the order of 60 seconds. It has no
      direct parallel in existing web protocols; it exists because agents are
      non-deterministic.</t>

      <t>A BAC declares its level in the "bac_level" claim, an integer 1, 2, or
      3. The levels are cumulative: an L2 claim carries the L1 members, and an L3
      claim carries all of them.</t>
      <dl spacing="compact">
        <dt>1</dt><dd>Build-time attestation: the "atx_reference".</dd>
        <dt>2</dt><dd>Runtime self-attestation: additionally the "binary_hash".</dd>
        <dt>3</dt><dd>Behavioral continuity: additionally the "drift_score", the
        "anomaly_state", and "intent_verified", and, where the issuer holds a
        session high water mark for the subject, the "session_label".</dd>
      </dl>

      <t>The "session_label" claim is an array holding the set of labels
      admitted into the session so far (the union of the label sets of every
      field returned to the agent, as maintained by the broker). It MUST
      appear in an L3 claim issued while the issuer holds a session high water
      mark for the subject, and MUST NOT appear at level 1 or at level 2. It is a set,
      not a level. An empty array means the session has admitted no labeled
      field; absence means the issuer holds no high water mark for the
      subject. The two are distinct. The 60-second validity window is
      unchanged.</t>

      <sourcecode type="json"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

{
  "iss": "did:opena2a:authority:opena2a.org",
  "sub": "did:opena2a:agent:acme/orders-reader",
  "bac_level": 3,
  "atx_reference":
    "sha256:2052879dda15b1ca5e60319e3477a400\
      8412bffdaf3c3566c658795a48cab8fd",
  "binary_hash":
    "sha256:479bd28a55e3a3eb20b9f5b48202318d\
      5de9d0dbea9e6df20b2ee7ff95a4c135",
  "drift_score": 0.04,
  "anomaly_state": "nominal",
  "intent_verified": true,
  "iat": 1780315200,
  "exp": 1780315260,
  "jti": "7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b"
}
]]></sourcecode>

      <t>The validity window MUST satisfy "exp" minus "iat" less than or equal to
      60 seconds. BAC verification is local: the receiver verifies the signature
      against the issuing Registry instance's published public key, under the
      suite model of <xref target="sec-pq"/>. The post-quantum profile, an
      ML-DSA-65 <xref target="FIPS204"/> signature alongside Ed25519 via the
      multi-signature form of <xref target="serialization"/>, is shipped for
      CGTs (the reference broker mints it and the conformance suite carries
      generated hybrid fixtures); for BACs it remains a target: no
      implementation mints BACs yet, and the v1 BAC fixtures carry a single
      Ed25519 signature.</t>
    </section>

    <section anchor="federation">
      <name>Cross-Organizational Federation</name>
      <t>Federation follows a PKI-style hierarchy: subordinate Registry nodes
      (Root Authorities) issue ATXs that are trusted by their peers according to
      published trust lists. Any federated node can verify any other node's ATXs
      without direct contact. No participant joins a central operator; each
      operates a conformant Root Authority and cross-trusts its peers.</t>

      <section anchor="revocation">
        <name>Revocation Propagation</name>
        <t>When any node revokes an ATX, the revocation MUST propagate to all
        federation members within 60 seconds via signed push. No member is
        required to poll. Revoking an agent's ATX revokes every grant minted
        for it within the propagation window.</t>

        <t>Revoking a single grant without revoking the agent is a local
        mechanism. A broker MUST maintain a grant revocation list, local to the
        operator, keyed by "jti" (one CGT or DA) and by "sub" (every CGT and DA
        minted for an agent by that broker, current and future). A revocation
        cascades through delegation chains by the delegator's "jti": listing a
        token's "jti" also revokes every DA whose "act" chain leads back to it.
        The list MUST be checked at every resolution, after the ATX and
        revocation list checks and before policy evaluation, and a listed token
        MUST be denied. The list never leaves the operator and is never fetched
        from a hosted service. As of the date of this revision no known implementation
        maintains such a list.</t>
      </section>
    </section>

    <section anchor="security">
      <name>Security Considerations</name>

      <section anchor="sec-replay">
        <name>Replay Prevention</name>
        <t>All tokens include a unique identifier ("jti"): 16 random bytes,
        lowercase hex (32 characters), as minted by the reference
        implementation. Receivers MUST track used identifiers for the token's
        TTL window and MUST reject a repeated identifier. The reference
        verifiers enforce this (conformance category "REPLAYED_JTI"): a jti is
        remembered from first acceptance until the token's "exp", and a second
        presentation inside that window rejects, after all other checks
        pass.</t>

        <t>The aap-conformance suite <xref target="AAP-CONFORMANCE"/>
        exercises this rule with the fixture:</t>
        <ul spacing="compact">
          <li>cgt-compact-replayed.json</li>
        </ul>
      </section>

      <section anchor="sec-pq">
        <name>Cryptographic Agility and Post-Quantum Readiness</name>
        <t>The signature suite is a named, swappable field, the JOSE "alg" of
        each signature's protected header (<xref target="serialization"/>), so
        suites can be added or retired by negotiation, never by a new
        credential format. A verifier MUST reject a token whose declared suite
        it does not support rather than silently downgrade. Suite acceptance is
        pinned by verifier policy per path, never selected by the token; a
        producer configured for the hybrid profile on a path MUST NOT fall back
        to a classical-only token on that path except through explicit version
        negotiation (broker profile Section 8.1).</t>

        <t>The v1 suite registry (<xref target="suite-registry"/>) contains two
        active entries: "EdDSA" (Ed25519, <xref target="RFC8037"/>) and
        "ML-DSA-65" (FIPS 204 <xref target="FIPS204"/>; JOSE "alg" identifier
        and "AKP" key type registered by <xref target="RFC9964"/>, May 2026).
        The post-quantum profile is hybrid Ed25519 + ML-DSA-65, carried as two
        "signatures[]" entries of the multi-signature form
        (<xref target="multi-signature"/>), one per suite, matching ATX's
        per-signature "algorithm" model: a hybrid token verifies only if at
        least one ML-DSA-65 signature and at least one Ed25519 signature
        verify, with every declared entry verifying
        (<xref target="multi-signature"/>). Hybrid is the RECOMMENDED form
        wherever both ends implement AAP; single-suite compact tokens remain
        the interoperability baseline
        (<xref target="compact-serialization"/>). ML-DSA-65 signing uses the
        empty context string and no pre-hash variant, as
        <xref target="RFC9964"/> requires. Key exchange, where AAP deployments
        negotiate transport keys, targets hybrid X25519 + ML-KEM-768 (FIPS 203
        <xref target="FIPS203"/>); ML-KEM has no final JOSE registration yet,
        so that row remains reserved on the same adoption path this section
        previously applied to ML-DSA-65.</t>

        <t>The aap-conformance suite <xref target="AAP-CONFORMANCE"/>
        exercises the hybrid profile with the fixtures:</t>
        <ul spacing="compact">
          <li>cgt-hybrid-general-valid.json</li>
          <li>cgt-hybrid-missing-ed25519.json</li>
          <li>cgt-hybrid-missing-mldsa65.json</li>
          <li>cgt-hybrid-ed25519-bad-signature.json</li>
          <li>cgt-hybrid-mldsa-bad-signature.json</li>
        </ul>
      </section>

      <section anchor="sec-intent">
        <name>Intent Verification</name>
        <t>Semantic intent classification can express constraints that static
        policies cannot. Intent classification is probabilistic; systems MUST NOT
        rely on it alone to authorize irreversible actions.</t>
      </section>

      <section anchor="sec-trust-authz">
        <name>Trust Is Not Authorization</name>
        <t>A valid AIT or ATX is an identity and posture assertion, not
        permission to act on a resource, and trust is not transitive.
        Authorization exists only where a local policy grants it. Brokers MUST
        default-deny.</t>
      </section>

      <section anchor="sec-confinement">
        <name>Credential Confinement</name>
        <t>Where AAP is deployed via a broker, no credential value, temporary
        token, or backend identifier may enter an agent's reasoning context. This
        requirement is normative in the broker profile
        <xref target="AAP-BROKER-PROFILE"/> and is the property that defends
        against the credential-harvest and exfiltration attack classes catalogued
        in <xref target="THREATMATRIX"/>. An agent emits an abstract grant
        reference; the broker verifies the agent's ATX, evaluates resource
        policy, obtains a scoped credential, performs the operation, and returns
        only the result.</t>
      </section>

      <section anchor="sec-possession">
        <name>Presentation Is Not Possession</name>
        <t>An ATX proves what was attested about a build, not that the
        presenter is that agent, and a CGT or DA without "cnf" proves only that
        someone holds the bytes. Before this revision every presentation in AAP
        was bearer. The presentation binding step of the broker profile
        <xref target="AAP-BROKER-PROFILE"/> and the "cnf" claim
        (<xref target="cgt-cnf"/>) close that gap. A deployment that accepts an
        ATX or a CGT over a network binding without the binding step accepts a
        badge and MUST NOT claim conformance to the broker profile.</t>
      </section>

      <section anchor="sec-crit">
        <name>A Constraint a Verifier May Ignore Is Not a Constraint</name>
        <t>Previous revisions reserved "fga_constraints" as optional to ignore.
        A downstream that does not understand it treats the grant as
        unconstrained, so the claim could never be relied on. This revision
        deprecates it and moves the constraint into "authorization_details",
        which "aap_crit" makes mandatory to understand. The residual hazard is
        a legacy verifier that ignores "aap_crit" itself; the producer rule of
        <xref target="cgt-authz"/> is the only control until every verifier on
        a path implements this revision, and deployments MUST treat a path with
        a legacy verifier as a bearer, unconstrained path.</t>
      </section>
    </section>

    <section anchor="serialization">
      <name>Token Serialization and Signing</name>
      <t>This section pins the byte-level form of every AAP token: the AIT, CGT,
      DA, and BAC. AAP tokens are JOSE objects, that is, JWTs
      <xref target="RFC7519"/> over JWS <xref target="RFC7515"/>. The form is
      ratified from the reference implementation: what the reference broker
      actually signs is normative, byte for byte.</t>

      <section anchor="canonical-form">
        <name>Canonical Form</name>
        <t>The signed bytes are the JWS Signing Input:</t>
        <sourcecode><![CDATA[
ASCII( BASE64URL(UTF8(protected header)) || "." ||
       BASE64URL(payload) )
]]></sourcecode>

        <t>AAP defines no other canonical form: serialization is
        canonicalization. The producer serializes the header and claim set
        once, as compact JSON with no insignificant whitespace, and signs those
        exact bytes; a verifier operates on the transmitted base64url segments
        and never re-serializes. There is no separate canonicalization step and
        no field projection. This is a deliberate difference from ATX and ATP,
        and it exists because AAP tokens, uniquely in the family, are verified
        by foreign systems: OAuth 2.0 Token Exchange <xref target="RFC8693"/>
        authorization servers and OpenID Connect-style verifiers that
        understand exactly one thing, a standard JWT. Base64url is unpadded,
        per <xref target="RFC7515"/>.</t>
      </section>

      <section anchor="protected-header">
        <name>Protected Header</name>
        <t>The protected header carries "alg" (a suite identifier from the
        registry in <xref target="suite-registry"/>), "typ" (the value "JWT"),
        and "kid" (the key identifier of the signing key in the issuer's
        published key material; Ed25519 keys publish as OKP JSON Web Keys and
        ML-DSA-65 keys as AKP JSON Web Keys per <xref target="RFC9964"/>).</t>
      </section>

      <section anchor="compact-serialization">
        <name>Compact Serialization</name>
        <t>The compact serialization "header.payload.signature" is the v1
        baseline and is REQUIRED on every interoperability path where a foreign
        system verifies the token; in particular a CGT or DA presented as an
        <xref target="RFC8693"/> "subject_token" MUST be compact. A compact
        token carries exactly one signature, and therefore exactly one suite.
        The suite of a compact token is pinned per path by verifier policy
        (<xref target="sec-pq"/>): "EdDSA" is the interoperability baseline,
        and an "ML-DSA-65" compact token serves counterparties that support
        the <xref target="RFC9964"/> suites. During the current adoption window
        the RECOMMENDED default on foreign-interoperability paths remains
        "EdDSA", because deployed token-exchange and OpenID Connect-style
        verifiers do not yet verify the <xref target="RFC9964"/> suites.</t>
      </section>

      <section anchor="multi-signature">
        <name>Multi-Signature Form</name>
        <t>This section is the one home of the family signature gate: every
        declared signature entry MUST verify, and an artifact that declares an
        ML-DSA-65 entry MUST also carry a verifying Ed25519 (EdDSA) entry,
        otherwise it is rejected as "HYBRID_INCOMPLETE". ATX, ATP and AIP cite
        this rule for their own signature arrays rather than restate it.</t>

        <t>Where more than one signature is required, the hybrid post-quantum
        profile of <xref target="sec-pq"/>, the token is carried as JWS General
        JSON Serialization (<xref target="RFC7515"/>, Section 7.2.1), pinned by
        "schemas/jws-general-v1.schema.json": one "signatures[]" entry per
        suite, each with its own protected header ("alg", "kid") over the same
        payload. This is the family's named, swappable per-signature suite
        model, an entry's {protected.alg, protected.kid, signature} corresponds
        one-to-one to the ATX/ATP {algorithm, keyId, value}, expressed in the
        JOSE-standard container. Every declared entry MUST verify; a verifier
        MUST NOT accept a token on a subset of its declared signatures.</t>

        <t>A general-form token that declares any "ML-DSA-65" entry is on the
        hybrid profile of <xref target="sec-pq"/> and MUST carry at least one
        "EdDSA" entry and at least one "ML-DSA-65" entry; a verifier MUST
        reject a general-form token missing either family (conformance
        category "HYBRID_INCOMPLETE"). Together with the subset rule above,
        this means a stripped hybrid token can never degrade to single-family
        acceptance. Multiple entries of one suite with no "ML-DSA-65" entry
        remain a legal multi-signature (co-signature) form, published as
        "examples/tokens/cgt-v1.general.json".</t>

        <t>The aap-conformance suite <xref target="AAP-CONFORMANCE"/>
        exercises this rule with the fixtures:</t>
        <ul spacing="compact">
          <li>cgt-hybrid-missing-ed25519.json</li>
          <li>cgt-hybrid-missing-mldsa65.json</li>
        </ul>
      </section>

      <section anchor="suite-registry">
        <name>Suite Registry</name>
        <t>The v1 suite registry contains two entries:</t>
        <dl spacing="compact">
          <dt>EdDSA</dt><dd>Ed25519 <xref target="RFC8037"/>. Active; the
          interoperability baseline.</dd>
          <dt>ML-DSA-65</dt><dd>FIPS 204 <xref target="FIPS204"/>, JOSE
          registration <xref target="RFC9964"/>. Active. Hybrid with EdDSA via
          the multi-signature form, or single-suite compact on
          post-quantum-capable interoperability paths. ML-DSA-44 and ML-DSA-87,
          though registered for JOSE, are not in this registry and are rejected
          as unknown suites.</dd>
        </dl>
        <t>Adding or retiring a suite is a change to this registry plus version
        negotiation, never a change of format.</t>
      </section>

      <section anchor="claim-conventions">
        <name>Claim Conventions</name>
        <t>Claim names use the JWT registry convention, lowercase with
        snake_case for compound names such as "trust_class" and "issuer_chain".
        This is a deliberate exception to the OpenA2A camelCase JSON
        convention, which governs API responses rather than IETF-track token
        claims. The "iat" and "exp" claims are NumericDate values (seconds
        since the epoch), not date strings. The optional "aap_ver" claim
        carries the claim-schema version; it is OPTIONAL in v1 and REQUIRED
        from the first federated version, where a peer broker must select a
        claim schema without a shared channel. Claims registered by another
        specification keep their registered spelling ("authorization_details",
        "cnf", "act"); members inside an "authorization_details" entry that
        this document defines are camelCase, and the common members of
        <xref target="RFC9396"/> keep their registered spelling. The claims
        added by this revision are additive: a token that omits them is
        byte-identical to a token of the previous revision, so the claim schema
        version is unchanged.</t>
      </section>
    </section>

    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document requests registration of the "aap" URI scheme in the
      Uniform Resource Identifier (URI) Schemes registry, and, via the broker
      profile <xref target="AAP-BROKER-PROFILE"/>, the "grant" URI scheme. It
      further anticipates registries for AAP protocol versions, credential-provider
      mode identifiers, signature suite identifiers, to be coordinated with
      the ATX signature suite registry <xref target="ATX"/>, and
      "authorization_details" entry types (<xref target="cgt-authz"/>). The
      "authorization_details" and "cnf" claims are registered in the JSON Web
      Token Claims registry by <xref target="RFC9396"/> and
      <xref target="RFC7800"/>; registration of "aap_crit" will be requested
      in a future revision. Until those
      registries exist, the signature suite registry of
      <xref target="serialization"/> is managed within this specification. The
      concrete registration templates will be provided in a future revision of
      this document.</t>
    </section>

  </middle>

  <back>
    <references>
      <name>References</name>
    <references>
      <name>Normative References</name>

      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner" fullname="S. Bradner"/>
          <date year="1997" month="March"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
      </reference>

      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba" fullname="B. Leiba"/>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
      </reference>

      <reference anchor="RFC6749" target="https://www.rfc-editor.org/info/rfc6749">
        <front>
          <title>The OAuth 2.0 Authorization Framework</title>
          <author initials="D." surname="Hardt" fullname="D. Hardt" role="editor"/>
          <date year="2012" month="October"/>
        </front>
        <seriesInfo name="RFC" value="6749"/>
      </reference>

      <reference anchor="RFC7515" target="https://www.rfc-editor.org/info/rfc7515">
        <front>
          <title>JSON Web Signature (JWS)</title>
          <author initials="M." surname="Jones" fullname="M. Jones"/>
          <author initials="J." surname="Bradley" fullname="J. Bradley"/>
          <author initials="N." surname="Sakimura" fullname="N. Sakimura"/>
          <date year="2015" month="May"/>
        </front>
        <seriesInfo name="RFC" value="7515"/>
      </reference>

      <reference anchor="RFC7519" target="https://www.rfc-editor.org/info/rfc7519">
        <front>
          <title>JSON Web Token (JWT)</title>
          <author initials="M." surname="Jones" fullname="M. Jones"/>
          <author initials="J." surname="Bradley" fullname="J. Bradley"/>
          <author initials="N." surname="Sakimura" fullname="N. Sakimura"/>
          <date year="2015" month="May"/>
        </front>
        <seriesInfo name="RFC" value="7519"/>
      </reference>

      <reference anchor="RFC8037" target="https://www.rfc-editor.org/info/rfc8037">
        <front>
          <title>CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)</title>
          <author initials="I." surname="Liusvaara" fullname="I. Liusvaara"/>
          <date year="2017" month="January"/>
        </front>
        <seriesInfo name="RFC" value="8037"/>
      </reference>

      <reference anchor="RFC8693" target="https://www.rfc-editor.org/info/rfc8693">
        <front>
          <title>OAuth 2.0 Token Exchange</title>
          <author initials="M." surname="Jones" fullname="M. Jones"/>
          <author initials="A." surname="Nadalin" fullname="A. Nadalin"/>
          <author initials="B." surname="Campbell" fullname="B. Campbell" role="editor"/>
          <author initials="J." surname="Bradley" fullname="J. Bradley"/>
          <author initials="C." surname="Mortimore" fullname="C. Mortimore"/>
          <date year="2020" month="January"/>
        </front>
        <seriesInfo name="RFC" value="8693"/>
      </reference>

      <reference anchor="RFC9396" target="https://www.rfc-editor.org/info/rfc9396">
        <front>
          <title>OAuth 2.0 Rich Authorization Requests</title>
          <author initials="T." surname="Lodderstedt" fullname="T. Lodderstedt"/>
          <author initials="J." surname="Richer" fullname="J. Richer"/>
          <author initials="B." surname="Campbell" fullname="B. Campbell"/>
          <date year="2023" month="May"/>
        </front>
        <seriesInfo name="RFC" value="9396"/>
      </reference>

      <reference anchor="RFC7800" target="https://www.rfc-editor.org/info/rfc7800">
        <front>
          <title>Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)</title>
          <author initials="M." surname="Jones" fullname="M. Jones"/>
          <author initials="J." surname="Bradley" fullname="J. Bradley"/>
          <author initials="H." surname="Tschofenig" fullname="H. Tschofenig"/>
          <date year="2016" month="April"/>
        </front>
        <seriesInfo name="RFC" value="7800"/>
      </reference>

      <reference anchor="RFC7638" target="https://www.rfc-editor.org/info/rfc7638">
        <front>
          <title>JSON Web Key (JWK) Thumbprint</title>
          <author initials="M." surname="Jones" fullname="M. Jones"/>
          <author initials="N." surname="Sakimura" fullname="N. Sakimura"/>
          <date year="2015" month="September"/>
        </front>
        <seriesInfo name="RFC" value="7638"/>
      </reference>

      <reference anchor="RFC9449" target="https://www.rfc-editor.org/info/rfc9449">
        <front>
          <title>OAuth 2.0 Demonstrating Proof of Possession (DPoP)</title>
          <author initials="D." surname="Fett" fullname="D. Fett"/>
          <author initials="B." surname="Campbell" fullname="B. Campbell"/>
          <author initials="J." surname="Bradley" fullname="J. Bradley"/>
          <author initials="T." surname="Lodderstedt" fullname="T. Lodderstedt"/>
          <author initials="M." surname="Jones" fullname="M. Jones"/>
          <author initials="D." surname="Waite" fullname="D. Waite"/>
          <date year="2023" month="September"/>
        </front>
        <seriesInfo name="RFC" value="9449"/>
      </reference>

      <reference anchor="FIPS203" target="https://doi.org/10.6028/NIST.FIPS.203">
        <front>
          <title>Module-Lattice-Based Key-Encapsulation Mechanism Standard</title>
          <author>
            <organization>National Institute of Standards and Technology</organization>
          </author>
          <date year="2024" month="August"/>
        </front>
        <seriesInfo name="FIPS" value="203"/>
      </reference>

      <reference anchor="FIPS204" target="https://doi.org/10.6028/NIST.FIPS.204">
        <front>
          <title>Module-Lattice-Based Digital Signature Standard</title>
          <author>
            <organization>National Institute of Standards and Technology</organization>
          </author>
          <date year="2024" month="August"/>
        </front>
        <seriesInfo name="FIPS" value="204"/>
      </reference>

      <reference anchor="RFC9964" target="https://www.rfc-editor.org/info/rfc9964">
        <front>
          <title>ML-DSA for JSON Object Signing and Encryption (JOSE) and CBOR
          Object Signing and Encryption (COSE)</title>
          <author initials="M." surname="Prorock"/>
          <author initials="O." surname="Steele"/>
          <date year="2026" month="May"/>
        </front>
        <seriesInfo name="RFC" value="9964"/>
        <seriesInfo name="DOI" value="10.17487/RFC9964"/>
      </reference>

      <reference anchor="ATX" target="https://specs.opena2a.org/atx">
        <front>
          <title>Agent Trust eXtension (ATX) Credential Format</title>
          <author initials="A." surname="Fane" fullname="Abdel Fane">
            <organization>OpenA2A</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="ATP" target="https://specs.opena2a.org/atp">
        <front>
          <title>Agent Trust Protocol (ATP)</title>
          <author initials="A." surname="Fane" fullname="Abdel Fane">
            <organization>OpenA2A</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>
    </references>

    <references>
      <name>Informative References</name>

      <reference anchor="RFC9162" target="https://www.rfc-editor.org/info/rfc9162">
        <front>
          <title>Certificate Transparency Version 2.0</title>
          <author initials="B." surname="Laurie" fullname="B. Laurie"/>
          <author initials="E." surname="Messeri" fullname="E. Messeri"/>
          <author initials="R." surname="Stradling" fullname="R. Stradling"/>
          <date year="2021" month="December"/>
        </front>
        <seriesInfo name="RFC" value="9162"/>
      </reference>

      <reference anchor="RFC8792" target="https://www.rfc-editor.org/info/rfc8792">
        <front>
          <title>Handling Long Lines in Content of Internet-Drafts and RFCs</title>
          <author initials="K." surname="Watsen" fullname="K. Watsen"/>
          <author initials="E." surname="Auerswald" fullname="E. Auerswald"/>
          <author initials="A." surname="Farrel" fullname="A. Farrel"/>
          <author initials="Q." surname="Wu" fullname="Q. Wu"/>
          <date year="2020" month="June"/>
        </front>
        <seriesInfo name="RFC" value="8792"/>
      </reference>

      <reference anchor="RFC9421" target="https://www.rfc-editor.org/info/rfc9421">
        <front>
          <title>HTTP Message Signatures</title>
          <author initials="A." surname="Backman" fullname="A. Backman" role="editor"/>
          <author initials="J." surname="Richer" fullname="J. Richer" role="editor"/>
          <author initials="M." surname="Sporny" fullname="M. Sporny"/>
          <date year="2024" month="February"/>
        </front>
        <seriesInfo name="RFC" value="9421"/>
      </reference>

      <reference anchor="AAP-BROKER-PROFILE" target="https://specs.opena2a.org/aap/broker-profile">
        <front>
          <title>AAP Broker and Resolution Profile</title>
          <author initials="A." surname="Fane" fullname="Abdel Fane">
            <organization>OpenA2A</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="AAP-CONFORMANCE" target="https://github.com/opena2a-standards/aap-conformance">
        <front>
          <title>AAP Conformance Suite</title>
          <author>
            <organization>OpenA2A</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="AIP" target="https://github.com/opena2a-standards/agent-identity-protocol/blob/main/AIP-SPEC.md">
        <front>
          <title>OpenA2A Agent Identity Protocol (OpenA2A AIP)</title>
          <author initials="A." surname="Fane" fullname="Abdel Fane">
            <organization>OpenA2A</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="A2A" target="https://a2aproject.github.io/A2A/">
        <front>
          <title>Agent2Agent (A2A) Protocol Specification</title>
          <author>
            <organization>A2A Project</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="MCP" target="https://modelcontextprotocol.io/">
        <front>
          <title>Model Context Protocol Specification</title>
          <author>
            <organization>Model Context Protocol</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="THREATMATRIX" target="https://threats.opena2a.org">
        <front>
          <title>AI Agent Threat Matrix</title>
          <author>
            <organization>OpenA2A</organization>
          </author>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="CRUZ-AAP" target="https://datatracker.ietf.org/doc/draft-aap-oauth-profile/">
        <front>
          <title>Agent Authorization Profile (AAP) for OAuth 2.0</title>
          <author surname="Cruz"/>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="DUNBAR-AAP" target="https://datatracker.ietf.org/doc/draft-dunbar-agent-attachment/">
        <front>
          <title>Agent Attachment Protocol (AAP)</title>
          <author surname="Dunbar"/>
          <date year="2026"/>
        </front>
      </reference>

      <reference anchor="MISHRA-DAAP" target="https://datatracker.ietf.org/doc/draft-mishra-oauth-agent-grants/">
        <front>
          <title>OAuth Profile for Delegated AI Agent Authorization (DAAP)</title>
          <author surname="Kumar"/>
          <date year="2026"/>
        </front>
      </reference>
    </references>
    </references>

    <section anchor="related-work">
      <name>Related Work</name>
      <t>The "AAP" acronym is contested in this space. An independent
      Internet-Draft, "Agent Authorization Profile" <xref target="CRUZ-AAP"/>,
      specifies an OAuth 2.0 and JSON Web Token profile for agent authorization;
      it is a profile of existing OAuth mechanisms and introduces no new protocol
      elements. A separate Internet-Draft uses the same "AAP" letters for an
      unrelated "Agent Attachment Protocol" <xref target="DUNBAR-AAP"/> concerned
      with edge-node attachment. The present document defines a distinct token
      model (AIT, CGT, DA, and BAC), a broker-based credential-confinement layer,
      and a federation and revocation model. These documents are author-namespaced
      and are intended to coexist on the Internet-Drafts record.</t>

      <t>Closest in intent is DAAP, the "OAuth Profile for Delegated AI Agent
      Authorization" <xref target="MISHRA-DAAP"/>, which profiles OAuth 2.0 for
      agent client instances: authenticated user consent, resource-bound and
      sender-constrained access tokens, and attenuation through OAuth Token
      Exchange. Its revision -01 (March 2026) carried budget controls, a policy
      engine, cascade revocation, and a credential vault; revision -02 (August
      2026) moves budgets, policy languages, and credential vaults outside its
      interoperable core (its abstract and Section 1.1) and retains one policy
      statement: an automated policy decision may deny, narrow, or require
      escalation of a request (its Section 2). The present document differs in
      that authorization is exercised through a local broker that confines the
      credential value away from the agent's reasoning context (<xref
      target="sec-confinement"/>) and binds to behavioral attestation (<xref
      target="bac"/>), rather than issuing an OAuth token the agent holds
      directly. It carries budgets as the "budget" entry type of
      "authorization_details" (<xref target="cgt-authz"/>) and escalation as the
      hook of the broker profile, both enforced by a local broker rather than by
      the authorization server that issued the token. The two differ in where
      enforcement sits (broker versus token holder and resource server) and in
      credential confinement (<xref target="sec-confinement"/>), which DAAP -02
      lists among the facilities it does not standardize. This document makes no
      claim about whether DAAP or other agent authorization drafts define a data
      sensitivity clearance. Related agent-identity drafts using the "AIP"
      acronym address identity assertion rather than the scoped-authorization
      and credential-confinement problems that are the focus of this
      document.</t>
    </section>

    <section anchor="ack">
      <name>Acknowledgments</name>
      <t>This specification was authored in the open and benefits from review of
      its authorization and delegation model by the OpenA2A community.</t>
    </section>
  </back>

</rfc>
