<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>

<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="std"
  docName="draft-liu-oauth-authorization-evidence-02"
  ipr="trust200902"
  submissionType="IETF"
  xml:lang="en"
  version="3">

  <front>
    <title abbrev="OAuth Authorization Evidence">Authorization Evidence and Audit Trail for OAuth 2.0 Access Tokens</title>
    <seriesInfo name="Internet-Draft" value="draft-liu-oauth-authorization-evidence-02"/>

    <author fullname="Dapeng Liu" initials="D." surname="Liu">
      <organization>Alibaba</organization>
      <address>
        <email>max.ldp@alibaba-inc.com</email>
      </address>
    </author>

    <author fullname="Hongru Zhu" initials="H." surname="Zhu">
      <organization>Alibaba</organization>
      <address>
        <email>hongru.zhr@alibaba-inc.com</email>
      </address>
    </author>

    <author fullname="Suresh Krishnan" initials="S." surname="Krishnan">
      <organization>Cisco</organization>
      <address>
        <email>suresh.krishnan@gmail.com</email>
      </address>
    </author>

    <author fullname="Aaron Parecki" initials="A." surname="Parecki">
      <organization>Okta</organization>
      <address>
        <email>aaron@parecki.com</email>
      </address>
    </author>

    <date year="2026" month="November" day="2"/>
    <area>Security</area>
    <workgroup>Web Authorization Protocol</workgroup>

    <keyword>OAuth</keyword>
    <keyword>Evidence</keyword>
    <keyword>Audit</keyword>
    <keyword>Consent</keyword>
    <keyword>Approval</keyword>
    <keyword>Withdrawal</keyword>

    <abstract>
      <t>
        This specification defines an authorization details type for
        carrying authorization evidence in OAuth 2.0 access tokens,
        using the enriched response mechanism of Rich Authorization
        Requests. When an Authorization Server records an approval
        decision, it enriches the authorization details with
        cryptographic proof of the decision and of the structured
        disclosure on which the decision was based. Evidence is
        recorded for approved, narrowed, and declined decisions,
        supporting accountability, compliance, and dispute resolution
        in scenarios where autonomous agents act on behalf of users.
        An approval record that cannot be ended is not an accountable
        record, so this specification defines the withdrawal mechanism
        alongside the evidence itself. Withdrawal is one of the four
        ways a governing authorization ends, alongside completion,
        termination, and expiry.
      </t>
    </abstract>
  </front>

  <middle>
    <section anchor="introduction" title="Introduction and Problem Statement">
      <t>
        In OAuth 2.0 <xref target="RFC6749"/> flows, the Authorization
        Server (AS) records the approval decision internally, but the
        decision is not conveyed to Resource Servers or included in
        access tokens.  For many use cases this is sufficient.  In
        scenarios where an AI agent acts autonomously on behalf of a
        user, with the approval often given asynchronously and well
        before the work happens, the Resource Server, the auditor, and
        the user all need to know what was approved, what the approver
        was told at the time, and whether the authorization is still in
        force.
      </t>

      <t>
        Rich Authorization Requests (RAR) <xref target="RFC9396"/>
        provides the carrier but not the content.  <xref
        target="RFC9396" section="7.1"/> states: "The authorization
        details attached to the access token MAY differ from what the
        client requests.  In addition to the user authorizing less than
        what the client requested, there are some use cases where the
        AS enriches the data in an authorization details object.
        Whether enrichment is allowed and specifics of how it works are
        necessarily part of the definition of the respective
        authorization details type."  Two gaps remain for approval
        decisions:
      </t>

      <ol>
        <li>
          <t>
            The evidence gap.  No authorization details type records
            the approval decision itself: the outcome, the approver,
            the structured disclosure the approver was shown, the
            action that confirmed it, the bounds the decision approved,
            and a signature that makes the record tamper-evident to a
            party that does not hold the AS's key.
          </t>
        </li>
        <li>
          <t>
            The ending gap.  An approval establishes a governing
            authorization, and that authorization ends.  Nothing in the
            framework lets the approver end it, or lets a Resource
            Server learn that it ended.
          </t>
        </li>
      </ol>

      <t>
        This specification defines such an authorization details type.
        It defines how the AS enriches an <tt>authorization_evidence</tt>
        object at approval time, how the resulting record is signed and
        projected into credentials, and how the approver withdraws the
        authorization that the record establishes.  The mechanism
        combines:
      </t>

      <ol>
        <li>
          <t>
            A structured <tt>disclosure</tt> object that records what
            the approver was told, so that the evidence can be examined
            without reconstructing the consent interface.
          </t>
        </li>
        <li>
          <t>
            A detached JWS <xref target="RFC7515"/> over the approval
            record, canonicalized with JCS <xref target="RFC8785"/>,
            giving AS-signed proof of the decision; a digest of the
            signed input that detects corruption and binds a reference
            to the record it names; and a digest of the approved bounds
            that binds the decision to the authority it approved.
          </t>
        </li>
        <li>
          <t>
            Two projections of the record into a credential, embedded
            and by reference, so that deployments can trade token size
            and disclosure exposure against retrieval cost.
          </t>
        </li>
        <li>
          <t>
            An authorization record on the AS, reached through a
            withdrawal handle, by which the approver ends the governing
            authorization.
          </t>
        </li>
      </ol>

      <t>
        Evidence is recorded for approved, narrowed, and declined
        decisions.  Only evidence for approved or narrowed decisions is
        bound to issued credentials, since a declined decision
        establishes no authorization.
      </t>

      <t>
        One invariant governs the whole mechanism: evidence does not
        establish current permission.  A verified evidence record proves
        that an approval happened and what it covered.  Whether the
        authorization is still in force is determined by the lifecycle
        of the governing authorization and the validity of the
        credential, not by the presence of the record.
      </t>

      <t>
        Unless otherwise noted, all data types and serialization rules
        follow the JSON data interchange format as defined in
        <xref target="RFC8259"/>.
      </t>

      <section anchor="relationship-framework" title="Relationship to the Bounded Work Framework">
        <t>
          OAuth 2.0 Bounded Work Authorization
          <xref target="I-D.liu-mcguinness-oauth-bounded-work"/> sets
          out a framework for work a user has approved.  It describes
          three objects: a bounded work proposal, the governing
          authorization that an approval decision establishes for it,
          and approval evidence.  It states the invariants that relate
          them and lists eight requirements, R1 through R8, that a
          realization of the framework has to meet.  It specifies no
          wire formats.
        </t>
        <t>
          This specification is a realization of the framework's third
          object.  It defines the evidence record itself, how that
          record is projected into credentials, and the mechanism
          through which the approver can end the authorization the
          record describes.  Its terminology
          (<xref target="terminology"/>) uses "governing
          authorization", "approval record", "approver", and "subject"
          with the meanings the framework gives them.
        </t>
        <t>
          Against the framework's requirements, this specification is
          the realization of R2, of R5, and of the part of R7 that
          runs from a credential to the approval behind it.  It also
          carries the distinctness that R1 asks of the identifier:
          the disclosure object names the governing authorization by
          an identifier that is not the client identifier, not a token
          issued under the authorization, and not a refresh token
          family (<xref target="tbl-disclosure-fields"/>), and the
          Authorization Server assigns one where the authorization has
          none of its own.
        </t>
        <t>
          The remaining requirements belong to other work.  Comparing
          each requested operation against the approved bounds, and
          refusing where the comparison cannot decide (R3), is the
          work of whatever framework supplies the bounds, for example
          domain-specific authorization schemas
          (<xref target="I-D.liu-oauth-authorization-schemas"/>).
          Refusing every issuance path once the authorization has
          ended (R4), and bounding the time within which already
          issued credentials stop being accepted (R6), are properties
          of the token layer; <xref target="authorization-withdrawal"/>
          states what an ending requires of the Authorization Server,
          but it neither covers every issuance path nor sets an
          acceptance window.  Answering a query about the
          authorization from a party that holds no credential (R8) is
          not defined here either: <xref target="introspection"/>
          conveys lifecycle state as part of a response about a token.
        </t>
      </section>

      <section anchor="relationship-schemas" title="Relationship to Domain-Specific Authorization Schemas">
        <t>
          Domain-specific authorization schemas
          <xref target="I-D.liu-oauth-authorization-schemas"/> define the
          behavioral boundaries of a governing authorization and their runtime
          enforcement: a schema instance requested in
          <tt>authorization_details</tt>, once approved, is bound to the issued
          access token, verified by Resource Servers against each behavior, and
          given a lifecycle (active/ended, with ending reasons completed,
          withdrawn, terminated, and expired).
        </t>
        <t>
          The two compose in a single access token.  The schema
          instance states what is permitted, the bounds.  The
          authorization evidence states why it is permitted, the
          approval decision and the disclosure it was based on.  The
          <tt>authority_hash</tt> member of
          <xref target="tbl-evidence-fields"/> binds the second to
          the first, so that a party holding the evidence record
          apart from the token can tell whether the schema instance
          it later obtains is the one the approval was witnessed
          against (<xref target="bounds-binding"/>).
        </t>
      </section>
    </section>

    <section anchor="terminology" title="Terminology">
      <t>
        This specification uses the terms "authorization server" (AS),
        "client", "resource server" (RS), and "access token" defined in
        <xref target="RFC6749"/>, "authorization details" defined in
        <xref target="RFC9396"/>, and the <tt>NumericDate</tt> type
        defined in <xref target="RFC7519"/>.
      </t>

      <t>In addition, this specification defines the following terms:</t>

      <dl>
        <dt>Approval:</dt>
        <dd>
          The decision, recorded by the Authorization Server, that
          establishes a governing authorization for requested work.
          Approval may be based on user consent, an administrative
          decision, a policy authority, or another authorized basis;
          user consent is the most common basis in this specification.
        </dd>

        <dt>Approver:</dt>
        <dd>
          The party whose decision establishes the governing
          authorization. The approver is authenticated, is entitled
          to approve the bounds in question, and is recorded as the
          party accountable for the decision. The approver and the
          user on whose behalf the work is performed are often the
          same person but need not be.
        </dd>

        <dt>Governing Authorization:</dt>
        <dd>
          The authority established by an approval decision. A
          governing authorization has a lifecycle: it is active once
          approved and ends through withdrawal, completion,
          termination, or expiry. Credentials issued under it carry
          its authority only while it remains active.
        </dd>

        <dt>Disclosure:</dt>
        <dd>
          The structured description of the proposed authorization
          presented to the approver during the approval flow,
          including its summary, the authorization it described, and
          any notices or material risks it carried.
        </dd>

        <dt>Evidence:</dt>
        <dd>
          A cryptographically signed record of an approval decision
          and of the bounds that decision approved, including the
          disclosure on which the decision was based and how the
          approver responded.  Evidence is bound to the decision and
          not to any credential issued under it.
        </dd>

        <dt>Audit Trail:</dt>
        <dd>
          The set of records linking what the approver was told, what
          the approver decided, and what a Resource Server later did
          under that decision.
        </dd>

        <dt>Approval Record:</dt>
        <dd>
          The part of a governing authorization that records what was
          approved: the authority as described, the approved bounds,
          the termination conditions, and the approver accountable
          for the decision.  It is fixed at approval and does not
          change, including when the authorization ends.  The
          evidence object of <xref target="evidence-claim"/> is its
          signed, portable form.
        </dd>

        <dt>Authorization Record:</dt>
        <dd>
          An Authorization Server-side entity created at the moment of
          the approval decision, holding the approval record and,
          beside it, the lifecycle state of the authorization that
          decision established.  The two change differently: the
          approval record is immutable and the state is not, which is
          why lifecycle state is conveyed beside an evidence record
          rather than inside it
          (<xref target="introspection"/>).  The authorization record
          exists independently of any access token and is the anchor
          for withdrawal (see
          <xref target="authorization-withdrawal"/>). In deployments
          using domain-specific authorization schemas
          <xref target="I-D.liu-oauth-authorization-schemas"/>, the
          authorization record corresponds to the registered approved
          instance.
        </dd>

        <dt>Withdrawal Handle:</dt>
        <dd>
          A URI under the Authorization Server's control through which
          the approver can initiate withdrawal of a specific governing
          authorization. The handle is a lookup key, not a credential.
        </dd>
      </dl>

      <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>
    </section>

    <section anchor="use-case" title="Use Case">
      <t>
        This section walks through the scenario the mechanism is built
        for, so that the objects and checks defined in the rest of this
        document can be seen together in one place.  The scenario is a
        shopping assistant acting for a user, <tt>user_12345</tt>, and
        it is the same scenario that the complete token of
        <xref target="complete-example"/> carries.  It exercises both
        gaps of <xref target="introduction"/>: an approval that produces
        a signed evidence record, and a withdrawal that ends the
        authorization and is enforced against later operations.
      </t>

      <t>
        Step 1 (approval).  The user asks her agent to add items to her
        cart up to $50 in total.  The agent submits this as requested
        authority, and the AS discloses it to the user: what will be
        done, the $50 bound, and how the authority ends.  The user
        approves.  The AS creates a governing authorization, records the
        approval as an <tt>evidence</tt> object, and signs it
        (<xref target="evidence-generation"/>).  The signed record
        carries a <tt>content_hash</tt> of itself and an
        <tt>authority_hash</tt> of the approved bounds
        (<xref target="bounds-binding"/>).  The AS also generates a
        withdrawal handle and presents it to the user
        (<xref target="authorization-record"/>), then issues an access
        token whose <tt>authorization_details</tt> carry both the
        evidence object and the bounds object.
        <xref target="complete-example"/> shows that token in full.
      </t>

      <t>
        Step 2 (use within bounds).  The agent calls the shop's API to
        add a $30 item.  The Resource Server obtains the evidence, from
        the token or by introspection
        (<xref target="introspection"/>), verifies the
        <tt>as_signature</tt> under the AS's key
        (<xref target="rs-processing"/>), and checks the
        <tt>content_hash</tt> and <tt>authority_hash</tt> against the
        record and the bounds it holds.  It confirms that the governing
        authorization is still active and that this operation is within
        the approved bounds.  The request is allowed.
      </t>

      <t>
        Step 3 (withdrawal).  The user changes her mind and follows the
        withdrawal handle.  The AS authenticates her, confirms that she
        is the approver recorded on the authorization, and marks the
        governing authorization ended with reason <tt>withdrawn</tt>
        (<xref target="principal-withdrawal"/>).  It revokes the issued
        token and reflects the ending in its status mechanism
        (<xref target="authorization-withdrawal"/>).
      </t>

      <t>
        Step 4 (denial).  The agent, unaware of the withdrawal, calls
        the API again to add another item.  The token may still be
        cryptographically valid, but the Resource Server learns from
        introspection or the status mechanism that the governing
        authorization has ended, and denies the operation.  This is what
        the ending gap of <xref target="introduction"/> is about: a
        valid credential on ended work authorizes nothing.
      </t>

      <t>
        Step 5 (accountability afterwards).  Some time later an auditor
        retrieves the evidence record.  The authorization has ended and
        the token is gone, but the record still verifies under the AS's
        key and still states what the user approved, what she was shown,
        and the bounds she agreed to.  The record outlives both the
        credential and the authorization, which is what makes it useful
        for accountability.  It does not say, and never said, whether an
        operation is permitted now; Step 4 answered that through the
        lifecycle of the governing authorization, not through the record
        (<xref target="introduction"/>).
      </t>
    </section>

    <section anchor="evidence-claim" title="The authorization_evidence Authorization Details Type">
      <t>
        The <tt>authorization_evidence</tt> authorization details type contains
        a record of the approval decision made during the authorization
        process. It follows the enriched response pattern of
        <xref target="RFC9396" section="7.1"/>: the client requests the type,
        and the AS populates it with the evidence record derived from the
        approval interaction that actually took place.
      </t>

      <t>
        Carrying evidence as an authorization details type rather than as
        a standalone token claim is what makes that round trip possible.
        The client has a defined way to ask for a record, and the AS has
        a defined place to put the one it built.  A standalone claim
        leaves the AS to decide unilaterally whether evidence is
        attached and gives the client no means of requesting it, so the
        record a relying party later inspects would not correspond to
        anything the client asked for.
      </t>

      <section title="Type Definition">
        <dl>
          <dt>Type Identifier:</dt>
          <dd>authorization_evidence</dd>

          <dt>Usage:</dt>
          <dd>authorization_details in authorization requests and token responses</dd>
        </dl>
      </section>

      <section title="Client Request">
        <t>
          A client requests authorization evidence by including an
          <tt>authorization_evidence</tt> authorization details object in its
          authorization request. The client typically includes minimal fields,
          indicating that evidence is requested:
        </t>

        <figure>
          <artwork name="Client Request" type="json"><![CDATA[
{
  "authorization_details": [
    {
      "type": "authorization_evidence"
    }
  ]
}
          ]]></artwork>
        </figure>

        <t>
          The AS has final authority over the evidence content, which is
          derived from the actual approval interaction.
        </t>
      </section>

      <section title="Enriched Response">
        <t>
          After the approver completes the approval interaction, the AS enriches the
          <tt>authorization_evidence</tt> object with the complete evidence
          record. The enriched authorization details is included in the token
          response:
        </t>

        <figure>
          <artwork name="Enriched Response" type="json"><![CDATA[
{
  "authorization_details": [
    {
      "type": "authorization_evidence",
      "evidence": {
        "id": "urn:uuid:e73517f6-d8eb-4017-9602-2e251c7ffc7c",
        "approval": {
          "decision": "approved",
          "approver": "user_12345",
          "disclosure": {
            "summary": "Add items under $50 to cart",
            "authority_ref": "urn:uuid:d4affed6-3a05-4fa8-8d0f-936d5fdadc59",
            "notices": [
              "Items will be added to your saved cart at shop.example"
            ],
            "risks": [
              "The agent may add multiple items up to the $50 limit without further confirmation"
            ],
            "locale": "en-US"
          },
          "action": "button_click",
          "timestamp": 1731320595
        },
        "authority_hash": "yPT2jqmoJHFzOqrZRRfuOU8WNqkqDGhUmP_E09tgLKo",
        "content_hash": "LTfvHZqdAF4BzvfUZkUccL2mudBr3Re81CLkIEFIZjg",
        "as_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im...",
        "proposal_ref": "urn:uuid:d9172091-0653-41e2-8b76-9f960950c7bd",
        "withdrawal_handle": "https://as.example.com/revoke/urn:uuid:181c3a47-7ae7-4109-8290-d69cd3ca6896"
      }
    }
  ]
}
          ]]></artwork>
        </figure>

        <t>
          This is the same record <xref target="complete-example"/>
          carries, so it has the same <tt>content_hash</tt> and the
          same <tt>authority_hash</tt>.  The
          <tt>as_signature</tt> is abbreviated here for readability;
          <xref target="worked-signature"/> gives the complete value
          and the intermediate steps that produce it.  The
          authorization details object that <tt>authority_hash</tt>
          digests is not shown here;
          <xref target="complete-example"/> carries it beside the
          evidence record.
        </t>
      </section>

      <section title="Field Definitions">
        <table anchor="tbl-evidence-fields">
          <name>Evidence Object Fields</name>
          <thead>
            <tr>
              <th>Field</th>
              <th>Type</th>
              <th>Requirement</th>
              <th>Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>id</td>
              <td>string</td>
              <td>REQUIRED</td>
              <td>Unique identifier for this evidence record. The
                value MUST be a URI that is unique across the records
                the AS issues.  A UUID URN is RECOMMENDED.  The
                identifier is not a secret and is not required to be
                unguessable; the unguessability requirement falls on
                the withdrawal handle instead (see
                <xref target="handle-entropy"/>).</td>
            </tr>
            <tr>
              <td>approval</td>
              <td>object</td>
              <td>REQUIRED</td>
              <td>The approval decision: its outcome, the approver, the
                structured disclosure, the confirming action, and when
                it happened. See
                <xref target="tbl-approval-fields"/>.</td>
            </tr>
            <tr>
              <td>authority_hash</td>
              <td>string</td>
              <td>CONDITIONAL</td>
              <td>The base64url-encoded SHA-256 digest of the
                JCS-canonicalized form (<xref target="RFC8785"/>) of
                the authorization details object that carries the
                approved bounds and whose identifier member carries
                the value of
                <tt>approval.disclosure.authority_ref</tt>.  The
                member commits the signed evidence record to those
                bounds, so that a party holding the record on its
                own can tell whether a bounds object it obtains
                later is the one the AS witnessed the approval of.
                The member is REQUIRED where such an object is
                present in the token and is omitted only where the
                approved authority is carried by no authorization
                details object.  Where more than one object carries
                that identifier, the AS MUST NOT include the member,
                because this specification defines no digest over a
                set of objects.  <xref target="bounds-binding"/>
                states what the digest does and does not
                establish.</td>
            </tr>
            <tr>
              <td>content_hash</td>
              <td>string</td>
              <td>REQUIRED</td>
              <td>The base64url-encoded SHA-256 digest computed
                over the same JCS-canonicalized JSON object used
                as the <tt>as_signature</tt> input, as described in
                <xref target="evidence-signature"/>.  The digest is
                not a substitute for that signature.  A party that
                holds both the record and the digest can recompute
                one from the other and learns nothing, so the
                member detects corruption and truncation rather
                than adversarial modification.  Its uses are to
                detect damage to a record in storage or in transit,
                to bind a reference that reached a verifier by one
                path to the record that reached it by another, and
                to let two parties confirm that they hold the same
                record without disclosing it.</td>
            </tr>
            <tr>
              <td>as_signature</td>
              <td>string</td>
              <td>REQUIRED</td>
              <td>Detached JWS over the signed field set defined in
                <xref target="evidence-signature"/>.</td>
            </tr>
            <tr>
              <td>evidence_ref</td>
              <td>object</td>
              <td>OPTIONAL</td>
              <td>Reference to a related evidence record, for
                example the original approval in a delegation
                chain.  The object carries the <tt>id</tt> and
                <tt>content_hash</tt> of the referenced record and
                no other member, the same shape used by the
                reference projection of
                <xref target="projections"/>, so that the reference
                is bound to the content it names.</td>
            </tr>
            <tr>
              <td>proposal_ref</td>
              <td>string</td>
              <td>OPTIONAL</td>
              <td>A URI referencing the original authorization
                proposal, the client's initial request describing
                the intended operation before the AS applied policy
                evaluation, scope reduction, or narrowing at the
                approval decision.  The value is an opaque URI
                assigned by the AS for internal correlation; no
                protocol for retrieving the proposal content via
                this URI is defined by this specification.  It
                enables post-hoc comparison between what was
                requested and what was authorized.</td>
            </tr>
            <tr>
              <td>withdrawal_handle</td>
              <td>string</td>
              <td>OPTIONAL</td>
              <td>The withdrawal handle, a URI, for the governing
                authorization established by this approval, as
                defined in <xref target="withdrawal-member"/>.</td>
            </tr>
          </tbody>
        </table>

        <section anchor="approval-object" title="The approval Object">
          <table anchor="tbl-approval-fields">
            <name>approval Fields</name>
            <thead>
              <tr>
                <th>Field</th>
                <th>Type</th>
                <th>Requirement</th>
                <th>Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>decision</td>
                <td>string</td>
                <td>REQUIRED</td>
                <td>The outcome of the approval interaction:
                  <tt>approved</tt>, <tt>narrowed</tt>, or
                  <tt>declined</tt>. Evidence is recorded for all
                  three outcomes; only evidence for approved or
                  narrowed decisions is bound to issued credentials,
                  since a declined decision establishes no
                  authorization. A <tt>narrowed</tt> decision approves
                  less than was requested (for example, a lower
                  spending limit); the approved bounds are those of
                  the governing authorization actually established,
                  which may be reflected in the corresponding
                  authorization details objects.</td>
              </tr>
              <tr>
                <td>approver</td>
                <td>string</td>
                <td>OPTIONAL</td>
                <td>An identifier of the approver, opaque or a URI,
                  stable within the AS's domain. The value MAY be a
                  pseudonymous identifier, one that the AS can resolve
                  to a party but that carries no meaning to a holder of
                  the evidence record. When absent, the
                  approver is the resource owner to whom the
                  disclosure was presented. Identifiers of other
                  parties (subject, client) are carried by the
                  surrounding token or authorization details context
                  and are not duplicated in the evidence
                  object.</td>
              </tr>
              <tr>
                <td>disclosure</td>
                <td>object</td>
                <td>REQUIRED</td>
                <td>The structured disclosure presented to the
                  approver, as defined in
                  <xref target="disclosure-object"/>.</td>
              </tr>
              <tr>
                <td>action</td>
                <td>string</td>
                <td>REQUIRED</td>
                <td>How the approver confirmed the operation.  This
                  member is directed at auditors and at the AS's own
                  dispute resolution rather than at Resource Server
                  policy evaluation, which has no general basis for
                  ranking one confirmation mechanism against another.
                  The value is a free-form string, but implementations
                  SHOULD use values from the following set for
                  interoperability: <tt>button_click</tt>,
                  <tt>biometric_confirmation</tt>,
                  <tt>pin_entry</tt>, <tt>voice_confirmation</tt>,
                  <tt>hardware_key</tt>, <tt>implicit_consent</tt>.
                  Custom values MAY be used for deployment-specific
                  confirmation mechanisms.</td>
              </tr>
              <tr>
                <td>timestamp</td>
                <td>NumericDate</td>
                <td>REQUIRED</td>
                <td>When the decision occurred.</td>
              </tr>
            </tbody>
          </table>

          <t>
            The value <tt>implicit_consent</tt> indicates that the
            authorization was issued under a pre-approved standing
            consent arrangement rather than a direct interaction at
            authorization time.  In that case <tt>disclosure</tt>
            records what the approver was presented with when the
            standing arrangement was established, and
            <tt>timestamp</tt> is the time of that establishment
            rather than the time of the token request.  An AS that
            cannot supply both MUST NOT use <tt>implicit_consent</tt>,
            and MUST NOT issue an evidence record for an authorization
            that no approver interaction supports.
          </t>

          <t>
            For a <tt>narrowed</tt> decision, the <tt>disclosure</tt>
            records what the approver actually approved, not what was
            originally requested.  The request that was narrowed can be
            correlated through <tt>proposal_ref</tt>
            (<xref target="tbl-evidence-fields"/>).
          </t>
        </section>

        <section anchor="disclosure-object" title="The disclosure Object">
          <t>
            The <tt>disclosure</tt> object captures, in structured
            form, the description of the proposed authorization that
            was presented to the approver. Its purpose is evidential:
            a party examining the evidence can determine what the
            approver was told, without reconstructing it from the
            request parameters the client sent.
          </t>

          <table anchor="tbl-disclosure-fields">
            <name>disclosure Fields</name>
            <thead>
              <tr>
                <th>Field</th>
                <th>Type</th>
                <th>Requirement</th>
                <th>Description</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>summary</td>
                <td>string</td>
                <td>REQUIRED</td>
                <td>A short human-readable summary of the proposed
                  authorization, corresponding to the primary text
                  shown to the approver (for example, "Add items
                  under $50 to cart").</td>
              </tr>
              <tr>
                <td>authority_ref</td>
                <td>string</td>
                <td>REQUIRED</td>
                <td>The identifier of the governing authorization
                  that this approval established.  The value MUST be
                  distinct from the client identifier, from any token
                  issued under the authorization, and from any refresh
                  token family, so that a second party can name the
                  work without having to infer it.  Where the approved
                  authorization is described by other authorization
                  details objects in the same request (for example, a
                  domain-specific schema instance), this member MUST
                  carry the identifier those objects share (such as
                  <tt>identifier</tt>, <tt>work_id</tt>, or an
                  AS-assigned instance identifier).  Where the
                  authorization carries no identifier of its own, the
                  AS MUST assign one before it signs the evidence
                  record.</td>
              </tr>
              <tr>
                <td>notices</td>
                <td>array</td>
                <td>OPTIONAL</td>
                <td>Material information presented to the approver
                  in addition to the summary (for example, "Items
                  will be added to your saved cart at
                  shop.example").</td>
              </tr>
              <tr>
                <td>risks</td>
                <td>array</td>
                <td>OPTIONAL</td>
                <td>Material risks of the proposed authorization
                  that were presented to the approver (for example,
                  "The agent may add multiple items up to the $50
                  limit without further confirmation").</td>
              </tr>
              <tr>
                <td>locale</td>
                <td>string</td>
                <td>OPTIONAL</td>
                <td>The language of the presented disclosure, as a
                  language tag <xref target="RFC5646"/> (for
                  example, "en-US").</td>
              </tr>
            </tbody>
          </table>

          <t>
            The disclosure records what the approver was shown, and
            that includes how the authority ends.  Where the approved
            authority carries termination conditions and no
            authorization details object in the request records them,
            the AS SHOULD state them in <tt>notices</tt>, so that the
            evidence shows what the approver agreed about the end of
            the authority and not only about its extent.  Where such
            an object does record them, <tt>authority_hash</tt>
            commits the evidence record to it
            (<xref target="bounds-binding"/>).
          </t>

          <t>
            Rendering itself, including layout, presentation, and
            user interface, is an implementation matter and is not
            standardized by this specification. The
            <tt>disclosure</tt> object records what was communicated,
            not how it was displayed. It is covered by the AS
            signature of <xref target="evidence-signature"/>, which
            commits the AS to the content it presented. That
            signature is not an attestation by the approver's device,
            and this specification defines no mechanism through which
            a device proves what it rendered (see
            <xref target="rendering-attestation"/>).
          </t>
        </section>

      </section>

      <section anchor="evidence-signature" title="Signature">
        <t>
          The <tt>as_signature</tt> member is a signature by the
          Authorization Server over the approval record.  It proves
          that the AS witnessed the decision, it makes the record
          tamper-evident, and it is what a relying party examines in a
          dispute.  Its guarantee is bounded by trust in the AS, as
          discussed in <xref target="as-trust"/>.
        </t>

        <t>
          The signature covers the <tt>evidence</tt> object in full,
          with two exceptions.  The <tt>as_signature</tt> member is
          excluded because a signature cannot cover itself.  The
          <tt>content_hash</tt> member is excluded because it is the
          digest of the signing input and is therefore derived from
          it.  Every other member is covered, including
          <tt>id</tt>, <tt>approval</tt> together with the
          <tt>disclosure</tt> object inside it,
          <tt>authority_hash</tt>, <tt>evidence_ref</tt>,
          <tt>proposal_ref</tt>, and the OPTIONAL
          <tt>withdrawal_handle</tt> member defined in
          <xref target="withdrawal-member"/>.
        </t>

        <t>
          The signing input is a JSON object containing exactly the
          covered members, canonicalized with JCS
          <xref target="RFC8785"/>.  Because
          <tt>withdrawal_handle</tt> is covered, an AS that includes
          the member MUST have associated the handle with the
          authorization record before it signs, and cannot add or
          change the member afterwards without invalidating the
          signature.  The fields that carry the lifecycle state of the
          authorization are maintained on the AS and are not members
          of the <tt>evidence</tt> object, so signing the object does
          not fix any value that later changes.
        </t>

        <t>
          Members of the <tt>evidence</tt> object other than those
          defined by this specification MAY be present, for example an
          attestation of the rendering step of the kind discussed in
          <xref target="rendering-attestation"/>.  Any such member is
          part of the signed field set and is therefore covered by the
          <tt>as_signature</tt> without further provision.  A verifier
          that does not understand an extension member MUST still
          include it when reconstructing the signing input, and MUST
          NOT reject the record solely because a member is present and
          unrecognized.
        </t>

        <t>
          The signature format MUST be a detached JWS
          <xref target="RFC7515"/> in Compact Serialization, using the
          AS's signing key.  In detached Compact Serialization (see
          <xref target="RFC7515" section="F"/>), the payload portion is
          omitted, resulting in the form
          <tt>header..signature</tt>.
        </t>

        <t>
          The JWS header MUST contain a <tt>typ</tt> header parameter
          with the value <tt>evidence+jws</tt>, and a verifier MUST
          reject a JWS whose <tt>typ</tt> is absent or carries any
          other value.  The parameter separates this JWS from the
          others the AS produces under the same key, in particular
          from the signature over an access token.  Without it, an
          <tt>as_signature</tt> could be presented where a token
          signature is expected, and a signature made for another
          purpose could be accepted as one, because the two would be
          indistinguishable byte strings over the same key.  The value
          is not registered in the IANA "Media Types" registry;
          <xref target="RFC7515"/> permits an application to define
          its own.
        </t>

        <t>
          Implementations MUST support ES256 <xref target="RFC7518"/>
          for both signing and verification, so that a conformant AS
          and a conformant verifier interoperate without prior
          arrangement.  Other asymmetric algorithms registered in the
          IANA "JSON Web Signature and Encryption Algorithms" registry
          MAY be used where both parties support them.  The steps that
          produce the JCS input, the <tt>content_hash</tt>, and the
          <tt>as_signature</tt> are specified as a single algorithm in
          <xref target="evidence-generation"/>.
        </t>

        <t>
          To verify an <tt>as_signature</tt>, the verifier
          reconstructs the signing input from the received
          <tt>evidence</tt> object by removing the
          <tt>as_signature</tt> and <tt>content_hash</tt> members and
          canonicalizing the remainder with JCS, then verifies the
          detached JWS using the AS's public key.  The
          <tt>content_hash</tt> can be checked in the same pass: the
          verifier recomputes the digest over the reconstructed JCS
          output and compares it with the received
          <tt>content_hash</tt>.  That comparison requires no key
          material and detects corruption or truncation of the record.
          It does not detect adversarial modification, because an
          attacker who alters a record can recompute its digest, and
          it is therefore not a substitute for signature verification.
          <xref target="content-hash-security"/> states what the
          digest does provide.
        </t>

        <t>
          A verifier MUST NOT select the verification algorithm from
          the <tt>alg</tt> header parameter of the JWS it is
          verifying.  It MUST have an explicit allowlist of acceptable
          asymmetric algorithms, MUST reject a JWS whose
          <tt>alg</tt> value is not in that allowlist, and MUST reject
          a JWS whose <tt>alg</tt> value is <tt>none</tt>.  It MUST
          reject a JWS whose <tt>alg</tt> value does not match the type
          of the key used to verify it.  When the JWS header contains a
          <tt>crit</tt> member, the verifier MUST reject the JWS if any
          header parameter named in <tt>crit</tt> is absent from the
          header, or is present but not one the verifier understands
          and has processed.  These header parameters are defined in
          <xref target="RFC7515"/>.
        </t>

        <t>
          In the examples in this document the <tt>as_signature</tt>
          value is abbreviated for readability.  Actual values use the
          detached JWS Compact Serialization form described above.
          <xref target="worked-signature"/> gives a complete worked
          example, including the canonical signing input, the digest,
          and a signature that verifies.
        </t>

        <t>
          The key used to sign the evidence record MAY be the same key
          the AS uses to sign access tokens, provided the
          <tt>typ</tt> requirement above is met, or it MAY be a
          separate dedicated key.  Whichever key is used,
          implementations MUST ensure that it is associated with the
          AS through a verifiable mechanism, for example by publishing
          it in the AS's JWKS endpoint as defined in
          <xref target="RFC7517"/>.  A dedicated evidence signing key
          allows key rotation on a schedule independent of token
          validation.
        </t>
      </section>

      <section anchor="projections" title="Embedded and Reference Projections">
        <t>
          The <tt>evidence</tt> object defined in the preceding
          sections can be conveyed to Resource Servers in two forms:
        </t>

        <dl newline="true">
          <dt>Embedded projection:</dt>
          <dd>
            The full <tt>evidence</tt> object is carried in the
            <tt>authorization_details</tt> of the access token, as
            shown in the preceding examples.  This is the default
            form.
          </dd>

          <dt>Reference projection:</dt>
          <dd>
            The token carries a pointer to the record rather than the
            record itself.  The <tt>evidence</tt> object contains
            exactly two members, <tt>id</tt> and
            <tt>content_hash</tt>, and no others.  It contains no
            <tt>as_signature</tt>, because there is nothing in the
            token for such a signature to cover.  The Resource Server
            retrieves the complete evidence object, including its
            <tt>as_signature</tt>, via token introspection
            (<xref target="introspection"/>).
          </dd>
        </dl>

        <t>
          A non-normative example of the authorization details object
          as it appears in a token using the reference projection:
        </t>

        <figure>
          <artwork name="Reference Projection" type="json"><![CDATA[
{
  "authorization_details": [
    {
      "type": "authorization_evidence",
      "evidence": {
        "id": "urn:uuid:e73517f6-d8eb-4017-9602-2e251c7ffc7c",
        "content_hash": "LTfvHZqdAF4BzvfUZkUccL2mudBr3Re81CLkIEFIZjg"
      }
    }
  ]
}
          ]]></artwork>
        </figure>

        <t>
          This two-member pointer is the same shape the OPTIONAL
          <tt>evidence_ref</tt> member of
          <xref target="tbl-evidence-fields"/> uses to name a related
          record.  A deployment that needs a pointer to an evidence
          record uses this shape whichever way it is being carried.
        </t>

        <t>
          The requirement levels in
          <xref target="tbl-evidence-fields"/> and
          <xref target="tbl-approval-fields"/> describe the complete
          evidence record, as the AS produces it and as the embedded
          projection carries it.  The reference projection is a
          pointer to that record, not a fragment of it that is
          expected to satisfy the same requirements, and the
          introspection response returns the complete record.
        </t>

        <t>
          The AS selects the projection per deployment.  The
          reference projection reduces token size and limits the
          exposure of the <tt>disclosure</tt> object in signed tokens
          that are visible to multiple Resource Servers (see the
          privacy discussion in <xref target="privacy"/>).
        </t>

        <t>
          When a Resource Server receives a reference projection, it
          MUST retrieve the complete evidence object via token
          introspection, MUST verify its <tt>as_signature</tt> as
          described in <xref target="rs-processing"/>, and MUST verify
          that the <tt>id</tt> and <tt>content_hash</tt> of the
          retrieved record match the reference carried in the token.
          On mismatch, or when the introspection endpoint is
          unreachable, the Resource Server MUST treat the evidence as
          unavailable and apply its policy for a missing evidence
          record rather than relying on the unsigned reference alone.
        </t>
      </section>
    </section>


    <section anchor="as-processing" title="Authorization Server Processing">
      <section anchor="evidence-collection" title="Approval-to-Evidence Pattern">
        <t>
          The <tt>evidence</tt> object records the outcome of an
          approval interaction.  Before the AS can generate a signed
          evidence record, it first presents a consent interface to the
          approver and captures the decision.  Regardless of the grant
          type, that interaction follows a common pattern:
        </t>

        <ol>
          <li>
            <t>
              The AS receives an authorization request from a client,
              which may be acting on behalf of an AI agent.
            </t>
          </li>
          <li>
            <t>
              The AS determines that an approval decision is required
              and presents a consent interface to the approver.  The
              consent interface renders the structured disclosure of
              the requested authorization (the <tt>disclosure</tt>
              object, <xref target="disclosure-object"/>).
            </t>
          </li>
          <li>
            <t>
              The approver reviews the disclosure and performs a
              decision action, e.g., clicking an "Allow" or "Deny"
              button, providing biometric input, or entering a PIN.
            </t>
          </li>
          <li>
            <t>
              The AS captures the interaction details (the disclosure,
              the decision, the action the approver took, and when) and
              constructs the <tt>evidence</tt> object as defined in
              <xref target="evidence-claim"/>.
            </t>
          </li>
          <li>
            <t>
              For an approved or narrowed decision, the AS signs the
              evidence record and includes it in the issued access
              token.  For a declined decision, no credential is issued
              and no authorization record is created, because the
              decision establishes no governing authorization.  The AS
              MAY retain the evidence record for audit and dispute
              resolution, but a record retained this way is bound to
              no credential and is not reachable through token
              introspection (<xref target="introspection"/>).
            </t>
          </li>
        </ol>

        <figure>
          <artwork type="ascii-art"><![CDATA[
Client/Agent          Authorization Server           Approver
    |                         |                          |
    |-- authorization req --->|                          |
    |                         |                          |
    |                         |--- consent UI ---------->|
    |                         |    (disclosure)          |
    |                         |                          |
    |                         |<-- decision action ------|
    |                         |    (button_click, etc.)  |
    |                         |                          |
    |                         |  [capture evidence]      |
    |                         |  [sign with as_signature]|
    |                         |                          |
    |<-- access token --------|                          |
    |    (with evidence)      |                          |
    |                         |                          |
            ]]></artwork>
        </figure>
      </section>

      <section anchor="flow-applicability" title="Applicability to Other Flows">
        <t>
          The pattern above applies to any OAuth flow in which an
          approver is presented with a disclosure.  In the Authorization
          Code Grant the AS presents a consent screen during the
          <tt>/authorize</tt> redirect.  In CIBA the AS delivers a
          consent request to the approver's authentication device, e.g.,
          a push notification, and the evidence captures the approver's
          out-of-band decision action.  Flows that capture approval
          decisions asynchronously follow the same pattern, for example
          the JWT authorization grant with interaction response
          (<xref target="I-D.parecki-oauth-jwt-grant-interaction-response"/>)
          and the deferred token response
          (<xref target="I-D.ietf-oauth-deferred-token-response"/>).
        </t>

        <t>
          Flows that involve no approver interaction, e.g., the Client
          Credentials Grant without user context, cannot produce
          <tt>evidence</tt> records.  There is no approval decision to
          record, and this specification defines no substitute.
        </t>
      </section>

      <section anchor="evidence-generation" title="Evidence Generation and Signing">
        <t>
          When issuing an access token carrying evidence, the AS
          executes the following algorithm.  These steps answer the
          question that <xref target="RFC9396" section="7.1"/> leaves to
          the definition of the authorization details type: what the AS
          puts in the enriched object, and how that content is
          protected.
        </t>

        <ol>
          <li>
            <t>
              Record the structured disclosure presented to the
              approver, including its summary, the identifier of the
              governing authorization the approval establishes, and
              any notices or material risks, as the
              <tt>disclosure</tt> object.
            </t>
          </li>
          <li>
            <t>
              Capture the decision, the confirming action, and the
              timestamp of the decision in the <tt>approval</tt>
              object.
            </t>
          </li>
          <li>
            <t>
              Generate the <tt>id</tt> of the evidence record, a URI
              unique across the records the AS issues.
            </t>
          </li>
          <li>
            <t>
              Where the token carries the approved bounds in an
              authorization details object identified by
              <tt>disclosure.authority_ref</tt>, canonicalize that
              object with JCS <xref target="RFC8785"/>, compute its
              SHA-256 digest, and store the base64url encoding in
              <tt>authority_hash</tt>.  The digest is taken over the
              object as the AS will place it in the token response,
              so that a verifier recomputing it from the object it
              receives obtains the same bytes.
            </t>
          </li>
          <li>
            <t>
              Where the deployment conveys a withdrawal handle in the
              token response, associate the handle with the
              authorization record and populate
              <tt>withdrawal_handle</tt>, and populate
              <tt>evidence_ref</tt> and <tt>proposal_ref</tt> where
              they apply.  Every member of the <tt>evidence</tt>
              object other than <tt>content_hash</tt> and
              <tt>as_signature</tt> MUST be final before signing,
              because every one of them is covered by the signature.
            </t>
          </li>
          <li>
            <t>
              Create a JSON object containing every member of the
              <tt>evidence</tt> object except <tt>content_hash</tt>
              and <tt>as_signature</tt>.
            </t>
          </li>
          <li>
            <t>
              Apply JCS <xref target="RFC8785"/> to the object from the
              previous step, producing a deterministic byte string.
            </t>
          </li>
          <li>
            <t>
              Compute the SHA-256 digest of the JCS output, encode it in
              base64url, and store the result in the
              <tt>content_hash</tt> member of the <tt>evidence</tt>
              object.
            </t>
          </li>
          <li>
            <t>
              Compute a detached JWS in Compact Serialization over the
              JCS output from step 7, with a JWS header carrying the
              <tt>typ</tt> value required by
              <xref target="evidence-signature"/>, using the AS's
              private signing key, and store the resulting
              <tt>header..signature</tt> value in the
              <tt>as_signature</tt> member of the <tt>evidence</tt>
              object.
            </t>
          </li>
          <li>
            <t>
              Include the <tt>authorization_evidence</tt> authorization
              details object in the token response and bind it to the
              issued access token, in the embedded or the reference
              projection (<xref target="projections"/>).
            </t>
          </li>
        </ol>

        <t>
          Token refresh is a renewal operation, not a new approval.
          When the AS issues a new access token from a refresh token
          while the governing authorization is still active, it
          re-projects the same evidence record, with unchanged
          <tt>id</tt>, <tt>content_hash</tt>, and
          <tt>as_signature</tt>, into the new token.  A refresh
          request MUST NOT mint new evidence for the authorization.
          The condition under which the AS may issue a token carrying
          evidence at all is stated in
          <xref target="withdrawal-member"/>.
        </t>
      </section>
    </section>

    <section anchor="authorization-withdrawal" title="Authorization Withdrawal">
      <t>
        An evidence record proves that an approval happened.  It does
        not keep the approval in force, and on its own it gives the
        approver no way to end it.  This section supplies that missing
        half: the mechanism through which the approver ends the
        governing authorization that the evidence records.  Evidence
        collection (<xref target="as-processing"/>) establishes the
        authorization; the mechanism defined here ends it.
      </t>

      <t>
        A governing authorization ends in one of four ways:
        it is <tt>withdrawn</tt> by the approver (this section), it is
        <tt>completed</tt> when the work it authorized is finished, it
        is <tt>terminated</tt> by a party other than the approver (for
        example, an administrator or the AS), or it <tt>expires</tt>.
        These four ending reasons mirror the instance lifecycle of
        domain-specific authorization schemas
        <xref target="I-D.liu-oauth-authorization-schemas"/>.  The
        completed, terminated, and expired endings follow the
        semantics of the authorization framework in use and share the
        protocol consequences defined here; withdrawal is the ending
        this specification defines end to end.  The mechanism applies
        regardless of the OAuth grant type through which the
        authorization was obtained.  Some jurisdictions additionally
        require that withdrawal be as easy as the granting it undoes,
        which is a further reason to define it here rather than leave it
        to deployment practice.
      </t>

      <section anchor="authorization-record" title="Authorization Records and Withdrawal Handles">
        <t>
          The authorization record defined in
          <xref target="terminology"/> is distinct from its projection
          into a credential.  The record lives on the AS, is created at
          the moment of the approval decision, and carries the
          lifecycle state of the governing authorization.  The signed
          <tt>evidence</tt> object of <xref target="evidence-claim"/> is
          what a Resource Server sees.  Withdrawal operates on the
          record, not on the projection, and therefore remains possible
          after every credential carrying the evidence has expired.
        </t>

        <t>
          Because the authorization record is created at approval
          time, withdrawal is possible during the window after the
          approver has approved an authorization but before the
          resulting credential has been issued.
        </t>

        <t anchor="withdrawal-handle">
          When the AS records an approval decision, it SHOULD
          associate a withdrawal handle with the authorization
          record.  The withdrawal handle is a URI under the AS's
          control through which the approver can initiate withdrawal
          of that specific governing authorization.  A non-normative
          example:
        </t>

        <figure>
          <artwork type="example"><![CDATA[
https://as.example.com/revoke/urn:uuid:181c3a47-7ae7-4109-8290-d69cd3ca6896
          ]]></artwork>
        </figure>

        <t anchor="handle-entropy">
          The handle identifier MUST contain at least 112 bits of
          entropy so that valid handles cannot be enumerated, and MUST
          NOT be derived from the <tt>id</tt> of the evidence record or
          from any other member of the <tt>evidence</tt> object.  Those
          members are not secret: the <tt>id</tt> appears in every
          reference projection and in every log that records the
          evidence, so a handle computed from them would be
          reconstructible by any party that had seen the record.  A
          version 4 UUID satisfies the entropy requirement; a version 1
          UUID does not, because most of its bits come from a timestamp
          and a node identifier rather than from a random source.
        </t>

        <t>
          The requirement is a privacy control and not an authorization
          control: it limits what a third party can learn about the
          governing authorizations an approver has established, and it
          does not make possession of the handle sufficient to act on
          one.  The handle is a lookup key, not a credential:
          possession of the URI does not by itself authorize
          withdrawal.
        </t>

        <t>
          The AS SHOULD present the withdrawal handle to the approver
          over the front channel at or shortly after the approval
          interaction, for example on the consent confirmation page or
          in an authorization management view.  This is the primary
          delivery channel and the only one that reaches the approver
          directly.  The OPTIONAL
          <tt>withdrawal_handle</tt> member defined in
          <xref target="withdrawal-member"/> additionally conveys the
          handle in the token response; that copy reaches the client
          rather than the approver, and MAY support client-provided
          authorization management interfaces or agent-initiated
          self-withdrawal.
        </t>

        <t anchor="principal-withdrawal">
          When the approver follows a withdrawal handle, the AS MUST
          authenticate the approver (an active session MAY be used, and
          the AS MAY require step-up authentication) and MUST verify
          that the authenticated party is the approver recorded on the
          referenced authorization record, or is otherwise entitled to
          withdraw it, rejecting the request otherwise.  Retrieving
          the withdrawal handle with HTTP GET MUST only render a
          confirmation view summarizing the authorization being
          withdrawn (for example, which client was authorized, which
          scopes were granted, and when) and MUST NOT perform the
          withdrawal.  The withdrawal MUST be executed by an explicit
          action (for example, an HTTP POST request) protected against
          cross-site request forgery.
        </t>

        <t>
          When a withdrawal handle is delivered through a token
          response (in addition to, or instead of, the front channel),
          clients MUST treat it as sensitive data and MUST NOT expose
          it in URLs, logs, or user agents beyond what is necessary to
          present the withdrawal option to the approver.
        </t>

        <t>
          When a governing authorization ends, the AS SHOULD update
          the authorization record with <tt>ended_at</tt>, the
          timestamp of the ending, and <tt>ending_reason</tt>,
          indicating how the authorization ended.  Implementations
          SHOULD use values from the following set for
          <tt>ending_reason</tt>: <tt>withdrawn</tt> (the approver
          ended the authorization through the mechanism defined in
          this section), <tt>completed</tt> (the authorized work
          finished), <tt>terminated</tt> (ended by a party other than
          the approver, such as the client or an administrator of the
          AS), or <tt>expired</tt> (lapsed without any party acting).
          Where accountability requires distinguishing who initiated
          a withdrawal, implementations MAY additionally record the
          initiator (for example, principal, client, or
          administrator).  These fields are maintained on the AS and
          are not included in access tokens.  They support audit and
          dispute resolution, including the question of whether a
          contested operation occurred before or after the
          authorization ended.
        </t>
      </section>

      <section anchor="withdrawal-member" title="The withdrawal_handle Member and Withdrawal Semantics">
        <t>
          The OPTIONAL <tt>withdrawal_handle</tt> member of the
          <tt>evidence</tt> object carries the withdrawal handle for
          the governing authorization established by the approval
          recorded in the evidence
          (<xref target="withdrawal-handle"/>).  Its value is the
          handle URI itself:
        </t>

        <figure>
          <artwork name="withdrawal_handle member" type="json"><![CDATA[
{
  "withdrawal_handle": "https://as.example.com/revoke/urn:uuid:181c3a47-7ae7-4109-8290-d69cd3ca6896"
}
          ]]></artwork>
        </figure>

        <t>
          The member carries the handle and nothing else.  The
          current state of the governing authorization is deliberately
          not part of the evidence record.  The record is an immutable
          account of the approval, and a member whose value changes
          while the record is in force could not be signed.  A
          Resource Server that needs the current state obtains it
          through token introspection
          (<xref target="introspection"/>), and a party that needs to
          act on an ending follows the handle.
        </t>

        <t>
          The <tt>withdrawal_handle</tt> member is inside the signed
          field set of <xref target="evidence-signature"/>.  An AS that
          includes the member MUST therefore fix the handle before it
          signs the evidence record and MUST NOT alter the member
          afterwards.  A deployment that needs to replace the handle of
          an issued record MUST issue new evidence rather than modify
          the existing record.
        </t>

        <t>
          The AS MUST NOT issue an access token carrying evidence for
          a governing authorization that has ended at issuance time.
          Where issuance and withdrawal can race, the AS MUST
          evaluate the authorization record state atomically with
          credential issuance.
        </t>

        <t>
          The effect of an ending depends on the lifecycle phase
          of the governing authorization:
        </t>

        <dl newline="true">
          <dt>Before the approval decision:</dt>
          <dd>
            There is no authorization to withdraw.  If the approver
            refuses the request through the consent interface
            presented during the authorization flow, the AS records a
            <tt>declined</tt> decision (<xref target="tbl-approval-fields"/>)
            and no authorization is established.
          </dd>

          <dt>After the approval decision, before credential issuance:</dt>
          <dd>
            The AS invalidates the pending authorization by applying
            the cancellation semantics defined by the host protocol.
            For example, a deferred issuance flow may invalidate its
            deferral code so that subsequent polling requests return
            <tt>access_denied</tt>
            (<xref target="I-D.ietf-oauth-deferred-token-response"/>).
          </dd>

          <dt>After credential issuance:</dt>
          <dd>
            The AS revokes the issued tokens as appropriate per
            <xref target="RFC7009"/>, SHOULD reflect the ending in
            a status mechanism such as a token status list
            <xref target="I-D.ietf-oauth-status-list"/>, and MAY propagate the ending
            event to downstream subscribers using a shared signals
            mechanism such as CAEP
            <xref target="I-D.ietf-secevent-caep"/>.
          </dd>
        </dl>

        <t>
          This specification defines the withdrawal trigger and the
          authorization record state.  It does not redefine the
          cancellation or token revocation semantics of any host
          protocol; those semantics are applied as defined by the
          respective protocol.  The other three endings, completed,
          terminated, and expired, are defined by the authorization
          framework in use and carry the same protocol consequences
          for credentials issued under the ended authorization.
        </t>
      </section>
    </section>

    <section anchor="rs-processing" title="Resource Server Processing">
      <t>
        A Resource Server that relies on the evidence verifies it as
        follows:
      </t>

      <ol>
        <li>
          <t>
            Reconstruct the JCS signing input from the received
            <tt>evidence</tt> object by removing the
            <tt>as_signature</tt> and <tt>content_hash</tt> members,
            as described in <xref target="evidence-signature"/>.
          </t>
        </li>
        <li>
          <t>
            Verify the detached JWS carried in <tt>as_signature</tt>
            using the AS's public key, applying the header parameter
            checks of <xref target="evidence-signature"/>, including the
            required <tt>typ</tt> value.
          </t>
        </li>
        <li>
          <t>
            Recompute the SHA-256 digest of the JCS input and compare it
            with <tt>content_hash</tt>.  This check requires no key
            material and detects corruption or truncation of the record.
            It is not a security check on its own and does not replace
            the previous step.
          </t>
        </li>
        <li>
          <t>
            Where the record carries <tt>authority_hash</tt>, locate
            the authorization details object in the token whose
            identifier member carries the value of
            <tt>approval.disclosure.authority_ref</tt>, canonicalize
            that object with JCS <xref target="RFC8785"/>, compute its
            SHA-256 digest, and compare the base64url encoding with
            <tt>authority_hash</tt>.  Reject the record on mismatch:
            the bounds presented are not the bounds the AS witnessed
            the approval of.  Where the token carries no such object,
            obtain it from the introspection response
            (<xref target="RFC7662"/>) before comparing.
          </t>
        </li>
        <li>
          <t>
            Confirm that <tt>approval.timestamp</tt> is not later than
            the token's <tt>iat</tt> claim, that is, that the decision
            occurred at or before issuance.  For an opaque token, use
            the <tt>iat</tt> member of the introspection response
            (<xref target="RFC7662"/>).
          </t>
        </li>
      </ol>

      <t>
        The <tt>disclosure</tt> object records what was presented to the
        approver.  The Resource Server was not party to that interaction
        and cannot verify the content independently; it relies on the AS
        signature as proof that the AS witnessed the approver's decision
        on the authorization described.
      </t>

      <t>
        Resource Servers SHOULD log the evidence <tt>id</tt>, the
        decision timestamp, and the outcome of the operation.  That log
        is what closes the audit trail between the approval and the
        action taken under it.
      </t>
    </section>

    <section anchor="introspection" title="Token Introspection">
      <t>
        When opaque (reference) tokens are used, or when the evidence
        is conveyed as a reference projection
        (<xref target="projections"/>), Resource Servers obtain the
        authorization details, including the full evidence object,
        via token introspection (<xref target="RFC7662"/>) as
        described in <xref target="RFC9396" section="9"/>.
      </t>
      <t>
        The introspection response MUST return the
        <tt>authorization_details</tt> bound to the token at issuance
        without alteration.  For an embedded projection, the returned
        evidence object is identical to the one carried in the token.
        For a reference projection, the AS returns the full evidence
        object; the Resource Server MUST compare its <tt>id</tt> and
        <tt>content_hash</tt> with the reference carried in the token
        and MUST reject the record on mismatch.
      </t>
      <t>
        If the governing authorization underlying the evidence has
        ended, the AS SHOULD reflect this in the introspection
        response, for example by reporting the token as inactive or
        by conveying the current authorization state in a separate
        member.  Reflecting an ending does not license altering the
        evidence object.  The requirement above applies to the record
        as signed, and lifecycle state is conveyed beside it rather
        than inside it, because a change to any signed member would
        invalidate the <tt>as_signature</tt>.
      </t>
      <t>
        The <tt>as_signature</tt> is what establishes that the
        retrieved record is one the AS produced.  The
        <tt>content_hash</tt> comparison is what establishes that it is
        the record this token pointed at.  For a reference projection
        neither check is optional.
      </t>
    </section>

    <section anchor="security" title="Security Considerations">
      <t>
        This section discusses security considerations specific to
        authorization evidence in OAuth 2.0.  General OAuth 2.0
        security considerations, including token threats and
        countermeasures, are described in <xref target="RFC6819"/>.
      </t>

      <section title="Signing Keys">
        <t>
          The <tt>as_signature</tt> is the only integrity protection the
          evidence record has once it leaves the token, so the AS
          signing key is the root of the mechanism.  Implementations
          MUST use an algorithm of current security strength from the
          set <xref target="evidence-signature"/> defines, MUST protect
          the signing key against disclosure, and MUST rotate it under a
          documented key management process.  Key rotation is observable
          to verifiers through the <tt>kid</tt> of the JWS header
          (<xref target="cross-domain"/>).
        </t>

        <t>
          The algorithm and critical header parameter requirements of
          <xref target="evidence-signature"/> exist because a verifier
          that takes its algorithm from the JWS it is verifying lets
          the party that produced the JWS choose the strength of the
          check.  Where the evidence signing key is published in a
          JWKS alongside keys used for other purposes, the AS SHOULD
          assign it a <tt>kid</tt> that is not shared with other keys,
          and a verifier SHOULD confirm through the
          <tt>key_ops</tt> member of <xref target="RFC7517"/> that the
          key it selected is intended for signature verification.  A
          key published for encryption MUST NOT be used to verify an
          <tt>as_signature</tt>.
        </t>
      </section>

      <section anchor="content-hash-security" title="Content Hash">
        <t>
          The <tt>content_hash</tt> is a digest of data its holder
          already has, and it is worth being precise about what it
          establishes.  A party holding a record can recompute the
          digest, so the member detects corruption and truncation in
          storage or in transit.  It does not detect an adversary:
          anyone able to modify a record can recompute its digest, and
          a verifier comparing the two learns only that they are
          consistent with each other.  Integrity against modification
          comes from the <tt>as_signature</tt> and never from the
          digest.
        </t>

        <t>
          The digest becomes adversarially meaningful only when it
          reaches a verifier by a different path from the record it
          describes.  That is the case in the reference projection of
          <xref target="projections"/>, where the <tt>id</tt> and
          <tt>content_hash</tt> travel inside a signed token while the
          full record arrives from an introspection endpoint.
          Comparing the two establishes that the record the AS returned
          is the record the token pointed at.  The same reasoning is
          why <tt>evidence_ref</tt> in
          <xref target="tbl-evidence-fields"/> carries a digest of the
          record it names.
        </t>

        <t>
          Because identical records yield identical digests, the
          <tt>content_hash</tt> also allows deduplication in audit
          stores and lets two parties confirm that they hold the same
          record without disclosing it.  Since the digest is
          deterministic, a record whose content can be enumerated
          yields a digest that can be computed in advance and used as
          a correlation handle.  Records in this specification carry a
          unique <tt>id</tt> and a decision timestamp, which makes
          enumeration impractical, but implementations publishing
          digests to shared or public stores SHOULD assess whether
          correlation of digests across stores raises privacy concerns
          for their deployment.
        </t>
      </section>

      <section anchor="bounds-binding" title="Binding the Decision to the Approved Bounds">
        <t>
          The <tt>as_signature</tt> covers the <tt>evidence</tt> object,
          but the enforceable bounds are not members of that object.  A
          separate authorization details object in the same token carries
          them, and the evidence names it through
          <tt>approval.disclosure.authority_ref</tt>.  The signature
          therefore commits the AS to the decision and to what the
          approver was shown, but not to the bounds.  A party holding the
          record apart from the token cannot tell whether a bounds object
          it obtains later is the one the AS approved.
        </t>

        <t>
          The <tt>authority_hash</tt> member closes that gap.  It commits
          the signed record to a digest of the bounds object, in the same
          way <tt>content_hash</tt> commits a reference to the record it
          names.  It detects a bounds object presented alongside a genuine
          record that is not the one the record approves, whether the
          substitution happens in an audit store, in a retrieval from the
          AS, or in a Resource Server's own assembly of the two.  This
          matters most in the reference projection
          (<xref target="projections"/>) and after the credential expires,
          where the record and the bounds travel separately.
        </t>

        <t>
          Two limits are worth stating.  Where the access token is itself
          a signed JWT, its signature already covers the bounds object, so
          <tt>authority_hash</tt> adds nothing against an outside
          attacker; its value is in the uses of the record that leave the
          token behind.  And it does not remove the trust in the AS
          described in <xref target="as-trust"/>: the AS holds the signing
          key and can sign a digest of bounds it never intended to
          enforce.  Against the AS the digest buys consistency, not
          honesty.  An AS that commits to one set of bounds at approval
          and enforces another is detectable by any party holding both.
        </t>

        <t>
          Where no authorization details object carries the bounds, for
          example in a deployment that expresses authority only through
          <tt>scope</tt>, the member is absent and no such binding exists.
          This is a property of the deployment, not a defect in the record.
          A relying party that requires the binding MUST treat the absence
          of <tt>authority_hash</tt> as a reason not to rely on the record
          for bounds it cannot otherwise establish.
        </t>
      </section>

      <section anchor="as-trust" title="Evidence Tampering and Trust in the AS">
        <t>
          The trust boundary of the mechanism is narrow.  The
          <tt>as_signature</tt> provides cryptographic proof that the AS
          <strong>recorded</strong> an approval decision.  It does not
          independently prove that the approver <strong>actually</strong>
          approved.  The AS controls both the approval interaction and
          the signing key, so a compromised or malicious AS could
          fabricate evidence records.  Trust in the evidence record
          therefore depends on trust in the AS and its operational
          security.  Deployments requiring stronger non-repudiation
          guarantees SHOULD supplement this mechanism with approver-side
          signatures or independent approval auditing.
        </t>
      </section>

      <section anchor="rendering-attestation" title="Attestation of the Rendering Step">
        <t>
          The <tt>as_signature</tt> is an assertion by the AS about
          what the AS presented and recorded.  It is not an assertion
          by the approver's device about what that device displayed.
          Where the AS serves the consent interface directly to the
          approver's user agent, the two coincide closely enough that
          the distinction rarely matters.  Where a party other than
          the AS renders the disclosure, for example an agent or
          client that presents the structured <tt>disclosure</tt>
          object in its own interface, they do not: the AS records
          what it supplied for presentation and has no visibility
          into what was actually shown, in what form, or for how
          long.
        </t>

        <t>
          This specification provides no attestation of the rendering
          step.  Attestation backed by device hardware, such as a
          secure element or a trusted execution environment, can
          establish that a genuine application on a genuine device
          presented a given data structure and that a genuine
          approver gesture followed.  On a general-purpose operating
          system it cannot establish that what reached the display
          matched that data structure, because the rendering path
          lies outside the attested boundary.  A Resource Server MUST
          NOT read the absence of such an attestation from an
          evidence record as a defect in that record, since this
          specification neither defines nor requires one.
        </t>

        <t>
          A deployment that does use an attestation of the rendering
          step MUST carry it inside the <tt>evidence</tt> object, so
          that it is covered by the <tt>as_signature</tt> of
          <xref target="evidence-signature"/>, and MUST bind it to
          the same <tt>id</tt>.  An attestation carried outside the
          signed record, or bound only to a device or a session,
          proves that some consent interaction once occurred on that
          device.  It proves nothing about the approval this evidence
          record describes, and it can be replayed across approvals.
          The format of such an attestation, the trust anchors
          against which it is verified, and its privacy consequences
          are outside the scope of this specification.
        </t>
      </section>

      <section anchor="replay" title="Replay of Genuine Evidence">
        <t>
          A verified evidence record does not become invalid when the
          authorization it describes ends.  The <tt>as_signature</tt>
          carries no expiry and the record is deliberately immutable,
          so a genuine record taken from an expired or revoked token
          continues to verify indefinitely.  That the same record
          reappears in successive tokens issued for one governing
          authorization is intended behavior and not an attack; see
          <xref target="evidence-generation"/>.
        </t>

        <t>
          The exposure is a party presenting such a record as though
          the authorization were still in force.  That cannot be
          answered cryptographically, because nothing about the record
          changes when the authorization ends.  It is answered by the
          credential and by authorization state: the record is usable
          only through a credential the AS issued to carry it, and a
          Resource Server that needs to know whether the governing
          authorization is still active consults the mechanisms of
          <xref target="withdrawal-enforcement"/> rather than the
          evidence record.  Presenting a genuine record in a context
          the AS did not issue it for is addressed by
          <xref target="token-evidence-binding"/>.
        </t>
      </section>

      <section anchor="token-evidence-binding" title="Token-Evidence Binding">
        <t>
          When the <tt>evidence</tt> object is embedded in a signed
          JWT access token (<xref target="RFC9068"/>), the token
          signature and the <tt>as_signature</tt> cover the same
          bytes.  The value of having both is not that they protect
          different fields but that they answer different questions
          and have different reach.  The token signature binds the
          evidence to this particular token, with its subject,
          audience, and expiry.  The <tt>as_signature</tt> binds the
          evidence to the approval record the AS created, and it
          continues to verify after the evidence has left the token
          entirely.  Together they mean:
        </t>

        <ul>
          <li>
            An evidence record cannot be moved from one token to
            another without detection, because the receiving token's
            signature would not cover it;
          </li>
          <li>
            An evidence record cannot be altered, whether it is still
            inside a valid token or has been taken out of it, because
            the <tt>as_signature</tt> is invalidated either way;
          </li>
          <li>
            An evidence record that has been extracted from its token
            remains verifiable on its own, which the token signature
            cannot provide because the token is no longer present.
          </li>
        </ul>

        <t>
          The third point is what makes the reference projection of
          <xref target="projections"/> workable.  A Resource Server
          holding only an <tt>id</tt> and a <tt>content_hash</tt> can
          retrieve the record and establish that the AS produced it,
          with no reliance on the token that pointed at it.  It is
          also what makes the record usable as audit evidence after
          the credential has expired.
        </t>

        <t>
          Implementations MUST NOT copy an <tt>evidence</tt> object from
          one access token into another without re-validating the
          <tt>as_signature</tt> and confirming that
          <tt>approval.timestamp</tt> is consistent with the new
          token's issuance time.
        </t>

        <t>
          With an opaque (reference) token there is no token signature
          over the evidence at all.  The <tt>evidence</tt> object is not
          embedded in the token and MUST be retrieved by the Resource
          Server via token introspection (<xref target="RFC7662"/>) or a
          dedicated evidence retrieval endpoint, so the
          <tt>as_signature</tt> is the only integrity protection the
          record has.  Implementations MUST protect the transport
          between the Resource Server and that endpoint with TLS.
        </t>
      </section>

      <section anchor="cross-domain" title="Cross-Domain Evidence Verification">
        <t>
          When the RS is in a different trust domain from the AS, the RS
          still has to obtain the AS's public key to verify the
          <tt>as_signature</tt>.  Implementations SHOULD:
        </t>

        <ul>
          <li>
            Publish the AS's evidence signing keys at a well-known
            JWKS endpoint (<xref target="RFC7517"/>) accessible to
            the RS;
          </li>
          <li>
            Include a <tt>kid</tt> (Key ID) in the JWS header of
            the <tt>as_signature</tt> to enable key selection;
          </li>
          <li>
            Support key caching at the RS with appropriate cache
            invalidation to balance performance and key freshness.
          </li>
        </ul>

        <t>
          When the AS and RS belong to different administrative domains,
          trust establishment for the evidence signing key MAY be
          facilitated through a trust framework, federation agreement,
          or explicit key distribution mechanism.
        </t>

        <t>
          A second cross-domain case is not resolved here.  Where the
          same work reaches more than one Authorization Server, as
          when an agent obtains a token for that work at a second
          Authorization Server through an identity assertion grant
          (<xref target="I-D.ietf-oauth-identity-assertion-authz-grant"/>),
          each Authorization Server decides under its own policy and
          signs its own evidence record.  This specification does not
          say whether the second verifies and relies on the record the
          first signed, whether it produces a record of its own that
          refers to the first, or how an auditor is meant to join the
          two.  The <tt>authority_ref</tt> of the second record MAY
          carry the identifier the first assigned, which is what would
          join them, but nothing here requires that or defines what a
          verifier concludes when it is present.  How the records of
          two Authorization Servers for one piece of work relate is
          left for further work.
        </t>
      </section>

      <section anchor="withdrawal-enforcement" title="Withdrawal Enforcement Boundary">
        <t>
          Withdrawal under this specification is enforced by the AS and
          by downstream token revocation and status mechanisms; it is
          not purely cryptographic.  A token issued before the
          governing authorization ended remains cryptographically
          valid until it expires, is revoked via the token revocation
          mechanisms of the host protocol (e.g., <xref target="RFC7009"/>),
          or is rejected based on status information such as token
          status lists (<xref target="I-D.ietf-oauth-status-list"/>) or shared signals
          (<xref target="I-D.ietf-secevent-caep"/>).  Deployments with
          short-lived tokens reduce the window during which an ended
          authorization is not yet enforced; deployments requiring
          timely propagation of endings SHOULD combine token
          revocation with status lists or event-based propagation.
        </t>

        <t>
          This specification does not require resource servers to
          consult authorization state.  Whether an RS enforces the
          ending of a governing authorization directly, or relies on
          the AS to revoke the associated tokens, is a deployment
          decision.
        </t>
      </section>
    </section>

    <section anchor="privacy" title="Privacy Considerations">
      <t>
        An evidence record is a record of a person's decision.  The
        <tt>approval.approver</tt> identifier, the
        <tt>approval.timestamp</tt>, and the content of the
        <tt>disclosure</tt> are personal data in most jurisdictions, and
        the authorization record on the AS
        (<xref target="authorization-record"/>) holds the same
        information together with the ending state of the
        authorization.  Both are subject to applicable data protection
        requirements, including purpose limitation, retention limits,
        and the approver's rights of access and erasure.
      </t>

      <t>
        The <tt>disclosure</tt> object is shown to one approver during
        the approval flow but, in an embedded projection, becomes
        readable by every Resource Server that accepts the token.  Its
        summary, notices, and risks can reveal what the approver was
        doing, with whom, and up to what limit.  Deployments where this
        matters SHOULD use the reference projection
        (<xref target="projections"/>), which keeps the disclosure at
        the AS and exposes only the <tt>id</tt> and
        <tt>content_hash</tt> to Resource Servers.
      </t>

      <t>
        The <tt>content_hash</tt> is stable across re-projections of
        the same evidence record, for example when a refresh token
        yields a new access token
        (<xref target="evidence-generation"/>).  Two tokens carrying
        the same <tt>content_hash</tt> descend from the same approval.
        Implementations publishing evidence digests to shared or public
        stores SHOULD assess whether that linkage is acceptable in
        their deployment; <xref target="content-hash-security"/>
        discusses the entropy considerations.
      </t>

      <t>
        Both members of a reference projection are properties of the
        record, so a deployment that wants to limit correlation
        across audiences cannot vary the pointer on its own.  Giving
        each audience a pointer of its own means producing a distinct
        evidence record for each, with its own <tt>id</tt>,
        <tt>content_hash</tt>, and <tt>as_signature</tt>.  That
        limits what one Resource Server learns about the others, and
        it also removes the single record that joins them, which is
        what an auditor or an incident responder asks for.  This
        specification takes no position between the two.  A deployment
        decides according to whether the parties receiving evidence
        are trusted with the association.
      </t>

      <t>
        Authorization records outlive the tokens that carried their
        evidence, because withdrawal has to remain possible after a
        credential expires.  Retention of authorization records after
        the governing authorization ends SHOULD follow the same data
        protection policies that apply to the evidence records
        themselves and SHOULD be bounded rather than indefinite.  The
        authentication and entitlement checks that
        <xref target="principal-withdrawal"/> requires of a withdrawal
        request are what keep the authorization history of one approver
        from being inspected or acted on by another.
      </t>
    </section>

    <section anchor="iana" title="IANA Considerations">
      <section title="OAuth Authorization Details Type Registration">
        <t>
          This specification registers the following authorization details type
          in the "OAuth Authorization Details Types" registry established by
          <xref target="RFC9396"/>:
        </t>

        <dl>
          <dt>Type:</dt>
          <dd>authorization_evidence</dd>
          <dt>Description:</dt>
          <dd>
            Carries a signed record of the approval decision that
            established the authorization, using the enriched response
            pattern, together with a digest of the approved bounds the
            decision applies to and the withdrawal handle through which
            the approver can end it.
          </dd>
          <dt>Change Controller:</dt>
          <dd>IETF</dd>
          <dt>Specification Document:</dt>
          <dd><xref target="evidence-claim"/> of this document</dd>
        </dl>
      </section>

      <section title="Other Values Not Registered">
        <t>
          This specification defines three sets of enumerated values and
          creates no registry for any of them.  The reason differs in
          each case.
        </t>

        <t>
          The <tt>decision</tt> values <tt>approved</tt>,
          <tt>narrowed</tt>, and <tt>declined</tt> form a closed set.
          They carry protocol meaning, a verifier has to interpret all
          three, and this specification assigns no semantics to a
          fourth.  Extending the set would change what a conformant
          verifier is required to understand, so extension is left to a
          revision of this document rather than to a registry.
        </t>

        <t>
          The <tt>action</tt> values are informational.  They tell an
          auditor how the approver confirmed the decision and are not
          an input to any determination a Resource Server is required
          to make (see <xref target="tbl-approval-fields"/>).  A
          deployment whose confirmation mechanism falls outside the
          listed set records its own value, and nothing in the protocol
          depends on a verifier recognizing it, so assigning the values
          centrally would buy no interoperability.
        </t>

        <t>
          The <tt>ending_reason</tt> values of
          <xref target="authorization-record"/> never leave the
          Authorization Server.  They are carried neither in access
          tokens nor in evidence records, so they do not cross an
          interoperability boundary and there is nothing to coordinate.
        </t>

        <t>
          The <tt>typ</tt> header parameter value
          <tt>evidence+jws</tt> required by
          <xref target="evidence-signature"/> is not registered in the
          IANA "Media Types" registry either.  <xref target="RFC7515"/>
          permits an application to use a type value of its own, and
          this value identifies a JWS that only implementations of this
          specification produce or accept.
        </t>
      </section>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7515.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7517.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7518.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8785.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9396.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7009.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7662.xml"/>
      </references>

      <references>
        <name>Informative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6819.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9068.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5646.xml"/>

        <reference anchor="I-D.ietf-oauth-status-list">
          <front>
            <title>Token Status List (TSL)</title>
            <author initials="T." surname="Looker"/>
            <author initials="P." surname="Bastian"/>
            <author initials="C." surname="Bormann"/>
            <date year="2026" month="August"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-oauth-status-list-21"/>
        </reference>

        <reference anchor="I-D.liu-mcguinness-oauth-bounded-work">
          <front>
            <title>OAuth 2.0 Bounded Work Authorization</title>
            <author initials="D." surname="Liu"/>
            <author initials="K." surname="McGuinness"/>
            <date year="2026" month="October"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-liu-mcguinness-oauth-bounded-work-00"/>
        </reference>

        <reference anchor="I-D.liu-oauth-authorization-schemas">
          <front>
            <title>Domain-Specific Authorization Schemas for OAuth 2.0</title>
            <author initials="D." surname="Liu"/>
            <date year="2026" month="October"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-liu-oauth-authorization-schemas-00"/>
        </reference>

        <reference anchor="I-D.parecki-oauth-jwt-grant-interaction-response">
          <front>
            <title>JWT Authorization Grant with Interaction Response</title>
            <author initials="A." surname="Parecki"/>
            <author initials="B." surname="Campbell"/>
            <author initials="D." surname="Liu"/>
            <date year="2026" month="June"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-parecki-oauth-jwt-grant-interaction-response-00"/>
        </reference>

        <reference anchor="I-D.ietf-oauth-identity-assertion-authz-grant">
          <front>
            <title>OAuth 2.0 Identity Assertion Authorization Grant</title>
            <author initials="K." surname="Ying"/>
            <author initials="B." surname="Campbell"/>
            <date year="2026" month="January"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-oauth-identity-assertion-authz-grant"/>
        </reference>

        <reference anchor="I-D.ietf-oauth-deferred-token-response">
          <front>
            <title>OAuth 2.0 Deferred Token Response</title>
            <author initials="M." surname="Gerber"/>
            <author initials="G." surname="de Oliveira Niero"/>
            <author initials="D." surname="Liu"/>
            <date year="2026"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-oauth-deferred-token-response"/>
        </reference>

        <reference anchor="I-D.ietf-secevent-caep">
          <front>
            <title>Consent and Account Event Profile</title>
            <author initials="A." surname="Sannikov"/>
            <author initials="M." surname="Scurtescu"/>
            <author initials="A." surname="Backman"/>
            <author initials="M." surname="Jones"/>
            <date year="2026"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-secevent-caep"/>
        </reference>
      </references>
    </references>

    <section anchor="complete-example" title="Complete Example">
      <t>
        The following example shows a complete access token carrying
        both an <tt>authorization_evidence</tt> object and a
        <tt>transaction_authority</tt> object, a domain-specific
        authorization schema instance
        (<xref target="I-D.liu-oauth-authorization-schemas"/>).
      </t>

      <t>
        The scenario is a shopping assistant acting for
        <tt>user_12345</tt>.  The approver was shown the summary "Add
        items under $50 to cart", together with a notice about where the
        items would end up and a risk stating that the agent could add
        several items without asking again.  The approver clicked a
        button at 1731320595.  The AS recorded that interaction, signed
        it, and issued the token 105 seconds later.
      </t>

      <t>
        The schema instance states <strong>what is permitted</strong>:
        a $50 total, two operations, one location.  The evidence states
        <strong>why it is permitted</strong>: the approval decision and
        the disclosure it was based on.  The <tt>authority_ref</tt> in
        the disclosure and the <tt>transaction_id</tt> of the schema
        instance share a value, which is what correlates the two, and
        <tt>authority_hash</tt> commits the signed evidence record to
        the schema instance as issued, so that the correlation still
        holds when the two are retrieved separately.  A
        Resource Server can then enforce the boundary deterministically
        while retaining an audit trail from each authorized action back
        to the decision.
      </t>

      <t>
        The <tt>act.sub</tt> value uses the <tt>wit://</tt> URI scheme
        to identify the acting agent by its workload identity, as
        defined in the Identity Assertion Authorization Grant
        (<xref target="I-D.ietf-oauth-identity-assertion-authz-grant"/>).
        The hash suffix provides a collision-resistant binding between
        the URI and the agent's attestation evidence.
      </t>

      <figure>
        <artwork name="Complete Access Token Example" type="json"><![CDATA[
{
  "iss": "https://as.example.com",
  "sub": "user_12345",
  "aud": "https://api.shop.example",
  "exp": 1731369540,
  "iat": 1731320700,
  "jti": "urn:uuid:4d9aca66-58a9-46f2-b2c1-06c48e99980d",

  "act": {
    "sub": "wit://myassistant.example/sha256.abc123..."
  },

  "authorization_details": [
    {
      "type": "authorization_evidence",
      "evidence": {
        "id": "urn:uuid:e73517f6-d8eb-4017-9602-2e251c7ffc7c",
        "approval": {
          "decision": "approved",
          "approver": "user_12345",
          "disclosure": {
            "summary": "Add items under $50 to cart",
            "authority_ref": "urn:uuid:d4affed6-3a05-4fa8-8d0f-936d5fdadc59",
            "notices": [
              "Items will be added to your saved cart at shop.example"
            ],
            "risks": [
              "The agent may add multiple items up to the $50 limit without further confirmation"
            ],
            "locale": "en-US"
          },
          "action": "button_click",
          "timestamp": 1731320595
        },
        "authority_hash": "yPT2jqmoJHFzOqrZRRfuOU8WNqkqDGhUmP_E09tgLKo",
        "content_hash": "LTfvHZqdAF4BzvfUZkUccL2mudBr3Re81CLkIEFIZjg",
        "as_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im...",
        "proposal_ref": "urn:uuid:d9172091-0653-41e2-8b76-9f960950c7bd",
        "withdrawal_handle": "https://as.example.com/revoke/urn:uuid:181c3a47-7ae7-4109-8290-d69cd3ca6896"
      }
    },
    {
      "type": "transaction_authority",
      "transaction_id": "urn:uuid:d4affed6-3a05-4fa8-8d0f-936d5fdadc59",
      "domain": "ecommerce",
      "boundary": {
        "total_amount_limit": { "value": 50, "currency": "USD" },
        "operations": ["ecommerce.search", "ecommerce.cart.add"]
      },
      "actions": ["search", "cart.add"],
      "locations": ["https://api.shop.example"]
    }
  ]
}
        ]]></artwork>
      </figure>
    </section>

    <section anchor="worked-signature" title="Worked Signature Example">
      <t>
        This appendix gives the intermediate values that the algorithm
        in <xref target="evidence-generation"/> produces for the
        <tt>evidence</tt> object of <xref target="complete-example"/>,
        so that an implementation can check its JCS, digest, and
        detached JWS handling against a known answer.  The signing key
        is a test key generated for this example and MUST NOT be used
        in any deployment.
      </t>

      <t>
        Step 4 of <xref target="evidence-generation"/> digests the
        authorization details object that carries the approved bounds.
        For this token that is the <tt>transaction_authority</tt>
        object of <xref target="complete-example"/>.  Its JCS
        canonical form is 310 bytes, encoded in base64url below on
        the same terms as the other encoded values in this appendix.
      </t>

      <figure>
        <artwork name="Base64url of the JCS Canonical Form of the Bounds Object" type="inline"><![CDATA[
eyJhY3Rpb25zIjpbInNlYXJjaCIsImNhcnQuYWRkIl0sImJvdW5kYXJ5Ijp7Im9wZXJh
dGlvbnMiOlsiZWNvbW1lcmNlLnNlYXJjaCIsImVjb21tZXJjZS5jYXJ0LmFkZCJdLCJ0
b3RhbF9hbW91bnRfbGltaXQiOnsiY3VycmVuY3kiOiJVU0QiLCJ2YWx1ZSI6NTB9fSwi
ZG9tYWluIjoiZWNvbW1lcmNlIiwibG9jYXRpb25zIjpbImh0dHBzOi8vYXBpLnNob3Au
ZXhhbXBsZSJdLCJ0cmFuc2FjdGlvbl9pZCI6InVybjp1dWlkOmQ0YWZmZWQ2LTNhMDUt
NGZhOC04ZDBmLTkzNmQ1ZmRhZGM1OSIsInR5cGUiOiJ0cmFuc2FjdGlvbl9hdXRob3Jp
dHkifQ
        ]]></artwork>
      </figure>

      <t>
        The SHA-256 digest of those bytes, base64url-encoded, is the
        <tt>authority_hash</tt> member the evidence record carries:
      </t>

      <figure>
        <artwork type="inline"><![CDATA[
yPT2jqmoJHFzOqrZRRfuOU8WNqkqDGhUmP_E09tgLKo
        ]]></artwork>
      </figure>

      <t>
        Step 6 of <xref target="evidence-generation"/> collects every
        member of the <tt>evidence</tt> object except
        <tt>content_hash</tt> and <tt>as_signature</tt>.  For this
        record those members are <tt>id</tt>, <tt>approval</tt>,
        <tt>authority_hash</tt>, <tt>proposal_ref</tt>, and
        <tt>withdrawal_handle</tt>.
        Applying JCS
        <xref target="RFC8785"/> to them produces a canonical form of
        683 bytes, encoded in base64url below.  The line breaks are
        not part of the value; concatenating the lines yields the
        encoding of those 683 bytes.
      </t>

      <figure>
        <artwork name="Base64url of the JCS Canonical Form" type="inline"><![CDATA[
eyJhcHByb3ZhbCI6eyJhY3Rpb24iOiJidXR0b25fY2xpY2siLCJhcHByb3ZlciI6InVz
ZXJfMTIzNDUiLCJkZWNpc2lvbiI6ImFwcHJvdmVkIiwiZGlzY2xvc3VyZSI6eyJhdXRo
b3JpdHlfcmVmIjoidXJuOnV1aWQ6ZDRhZmZlZDYtM2EwNS00ZmE4LThkMGYtOTM2ZDVm
ZGFkYzU5IiwibG9jYWxlIjoiZW4tVVMiLCJub3RpY2VzIjpbIkl0ZW1zIHdpbGwgYmUg
YWRkZWQgdG8geW91ciBzYXZlZCBjYXJ0IGF0IHNob3AuZXhhbXBsZSJdLCJyaXNrcyI6
WyJUaGUgYWdlbnQgbWF5IGFkZCBtdWx0aXBsZSBpdGVtcyB1cCB0byB0aGUgJDUwIGxp
bWl0IHdpdGhvdXQgZnVydGhlciBjb25maXJtYXRpb24iXSwic3VtbWFyeSI6IkFkZCBp
dGVtcyB1bmRlciAkNTAgdG8gY2FydCJ9LCJ0aW1lc3RhbXAiOjE3MzEzMjA1OTV9LCJh
dXRob3JpdHlfaGFzaCI6InlQVDJqcW1vSkhGek9xclpSUmZ1T1U4V05xa3FER2hVbVBf
RTA5dGdMS28iLCJpZCI6InVybjp1dWlkOmU3MzUxN2Y2LWQ4ZWItNDAxNy05NjAyLTJl
MjUxYzdmZmM3YyIsInByb3Bvc2FsX3JlZiI6InVybjp1dWlkOmQ5MTcyMDkxLTA2NTMt
NDFlMi04Yjc2LTlmOTYwOTUwYzdiZCIsIndpdGhkcmF3YWxfaGFuZGxlIjoiaHR0cHM6
Ly9hcy5leGFtcGxlLmNvbS9yZXZva2UvdXJuOnV1aWQ6MTgxYzNhNDctN2FlNy00MTA5
LTgyOTAtZDY5Y2QzY2E2ODk2In0
        ]]></artwork>
      </figure>

      <t>
        The <tt>content_hash</tt> member is the base64url encoding of
        the SHA-256 digest of those bytes:
      </t>

      <figure>
        <artwork type="inline"><![CDATA[
LTfvHZqdAF4BzvfUZkUccL2mudBr3Re81CLkIEFIZjg
        ]]></artwork>
      </figure>

      <t>
        This is the value an implementation compares its own digest
        against.  Matching it confirms that the canonical form was
        reconstructed byte for byte, which is the part of the
        algorithm most easily implemented differently.
      </t>

      <t>
        The JWS header is the following JSON object, whose base64url
        encoding is 90 characters, shown wrapped:
      </t>

      <figure>
        <artwork type="inline"><![CDATA[
{"alg":"ES256","kid":"evidence-signing-key-1","typ":"evidence+jws"}

eyJhbGciOiJFUzI1NiIsImtpZCI6ImV2aWRlbmNlLXNpZ25pbmcta2V5LTEiLCJ0eXAi
OiJldmlkZW5jZStqd3MifQ
        ]]></artwork>
      </figure>

      <t>
        Because the JWS is detached
        (<xref target="RFC7515" section="F"/>), the payload is omitted
        from the serialization but is still part of the signature
        input.  The signature input is the ASCII encoding of the
        base64url header, a period, and the base64url of the 683
        canonical bytes, for a total of 1002 bytes.  Signing it with
        ES256 under the test key gives the following
        <tt>as_signature</tt> value, wrapped for page width:
      </t>

      <figure>
        <artwork type="inline"><![CDATA[
eyJhbGciOiJFUzI1NiIsImtpZCI6ImV2aWRlbmNlLXNpZ25pbmcta2V5LTEiLCJ0eXAi
OiJldmlkZW5jZStqd3MifQ..22UCJlAjbHNkN3SnUfSlyw6kclM8DwpyI5KIe4IAAZBs
jaH5wTZ4soXF0l4W6CutWsXiyqsdq-adUCuQVRvyJw
        ]]></artwork>
      </figure>

      <t>
        ECDSA signatures are randomized, so an implementation that
        signs the same input under the same key produces a different
        signature value.  Verification, not reproduction, is the test:
        the value above verifies against the signature input under the
        public key given below.
      </t>

      <figure>
        <artwork name="Public Key of the Test Signing Key" type="json"><![CDATA[
{
  "kty": "EC",
  "crv": "P-256",
  "kid": "evidence-signing-key-1",
  "x": "d0xHxTVj1-wZckpUgGic1hcnXCweVUUUCAkAoPGjOVc",
  "y": "oXz5fZ_W84y1JYu_Q9NZZPD2ipEuzs0Sa5q87jnr6Uo"
}
        ]]></artwork>
      </figure>

      <t>
        The canonical form covers the <tt>withdrawal_handle</tt>
        member as well as <tt>approval</tt>.  An implementation that
        omits <tt>withdrawal_handle</tt> from the signing input, or
        that includes <tt>content_hash</tt> in it, obtains a different
        digest and a signature that does not verify.
      </t>
    </section>

    <section title="Acknowledgments" numbered="false">
      <t>
        The authors would like to thank Brian Campbell for his feedback
        during the development of this specification.
      </t>
    </section>
  </back>

</rfc>
