<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.34 (Ruby 4.0.2) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-yakung-oauth-agent-attestation-00" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="ACAP">Agent Credential Attestation Protocol (ACAP)</title>

    <author fullname="Chudah Yakung">
      <organization>Attest</organization>
      <address>
        <email>ychudah@gmail.com</email>
      </address>
    </author>

    <date year="2026" month="March" day="26"/>

    <area>Security</area>
    
    <keyword>AI agents</keyword> <keyword>delegation</keyword> <keyword>JWT</keyword> <keyword>authorization</keyword> <keyword>credential</keyword> <keyword>attestation</keyword>

    <abstract>


<?line 62?>

<t>This document defines the Agent Credential Attestation Protocol (ACAP),
a cryptographic credentialing protocol for autonomous AI agent pipelines.
An ACAP credential is a short-lived JSON Web Token (JWT) signed with
RS256 that carries scope-limited permissions together with a SHA-256
hash of the original human instruction that initiated the task.
Credentials may be delegated to child agents; each delegation narrows
scope, cannot outlive its parent, increments a delegation depth counter,
and extends a tamper-evident chain of token identifiers.  Every
lifecycle event is recorded in an append-only, hash-chained audit log.</t>

<t>This document specifies the credential format, issuance rules,
delegation rules, verification algorithm, revocation semantics,
human-in-the-loop approval protocol, and audit log structure.</t>



    </abstract>



  </front>

  <middle>


<?line 78?>

<section anchor="introduction"><name>Introduction</name>

<section anchor="problem-statement"><name>Problem Statement</name>

<t>Contemporary authorization frameworks such as OAuth 2.0 <xref target="RFC6749"/> and
OpenID Connect <xref target="OIDC"/> were designed for human-initiated, single-hop
delegations: a resource owner grants a client access on behalf of
themselves.  AI agent pipelines violate this assumption in several
important ways.</t>

<t>First, an agent pipeline may involve an arbitrary number of hops.  A
root agent receives a task from a human, decomposes it, and delegates
sub-tasks to child agents, which may themselves delegate further.
OAuth's two-party model has no native representation for this; each hop
requires a fresh grant cycle or an out-of-band trust agreement.</t>

<t>Second, the originating human instruction -- the intent -- is not
cryptographically bound to any OAuth token.  An agent can receive a
token whose original purpose has been transformed or corrupted by prompt
injection at an intermediate step, and the verifying party has no way to
detect this.</t>

<t>Third, scope in OAuth is flat and is not guaranteed to narrow
monotonically through a delegation chain.  A child agent can, in
principle, present its parent token to a different authorization server
and request broader access.  Nothing in the wire format prevents scope
creep.</t>

<t>Fourth, the delegation graph is not natively recorded.  OAuth
introspection surfaces information about a single token; it provides no
view of the full task ancestry.</t>

<t>Recent IETF work -- notably the WIMSE working group <xref target="WIMSE"/> and the
draft on AI agents acting on behalf of users <xref target="OBO01"/> -- acknowledges
these gaps but stops short of specifying a compact, self-contained
credential format with cryptographically enforced monotone scope
reduction and intent binding.</t>

</section>
<section anchor="what-acap-adds"><name>What ACAP Adds</name>

<t>ACAP addresses the gaps above as follows.</t>

<dl>
  <dt>Intent binding:</dt>
  <dd>
    <t>Every ACAP credential carries <spanx style="verb">att_intent</spanx>, a hex-encoded SHA-256
hash of the original UTF-8 instruction text.  This value is set at
issuance and propagated unchanged through every delegation.  A verifier
can confirm that a presented credential descends from a specific human
instruction by independently computing the hash.</t>
  </dd>
  <dt>Monotone scope reduction:</dt>
  <dd>
    <t>At delegation time the issuer MUST verify that the child's requested
scope is a subset of the parent's scope using the <spanx style="verb">IsSubset</spanx> algorithm
defined in <xref target="scope-model"/>.  Any request that fails this check MUST be
rejected.  Scope therefore only ever narrows; it can never widen through
delegation.</t>
  </dd>
  <dt>Depth-limited delegation:</dt>
  <dd>
    <t>Each credential carries <spanx style="verb">att_depth</spanx>, an integer that starts at 0 for a
root credential and increments by 1 at each delegation.  Depth is
bounded above by <spanx style="verb">MaxDelegationDepth</spanx> (10).  A credential whose depth
equals this limit MUST NOT be used as a parent for further delegation.</t>
  </dd>
  <dt>Tamper-evident chain:</dt>
  <dd>
    <t>Each credential carries <spanx style="verb">att_chain</spanx>, an ordered list of JWT IDs from
the root of the delegation tree to the current token.  The verifier
checks that the chain length equals <spanx style="verb">att_depth + 1</spanx> and that the final
element equals the token's own <spanx style="verb">jti</spanx>.  Together these checks detect any
tampering with the ancestry record.</t>
  </dd>
  <dt>Lifetime containment:</dt>
  <dd>
    <t>A child credential's expiry is capped at the parent's expiry.
Concretely, <spanx style="verb">exp = min(requested_exp, parent_exp)</spanx>.  This ensures that
revoking a parent token effectively expires all descendants, even
without an active revocation lookup.</t>
  </dd>
  <dt>Cascade revocation:</dt>
  <dd>
    <t>The revocation store records revoked JTIs and cascades revocation to
all descendants by inspecting the <spanx style="verb">att_chain</spanx> column in the credential
store.  Revocation is permanent and takes precedence over token expiry.</t>
  </dd>
  <dt>Append-only audit log:</dt>
  <dd>
    <t>Every issuance, delegation, verification, revocation, and expiry event
is recorded in a hash-chained log.  Each entry commits to the previous
entry's hash, the event type, the JTI, and the timestamp, forming a
tamper-evident record of all credential lifecycle events within a task
tree.</t>
  </dd>
</dl>

</section>
<section anchor="relationship-to-prior-art"><name>Relationship to Prior Art</name>

<t>ACAP is informed by but is not a profile of any existing specification.
The Agentic JWT (A-JWT) paper proposes delegation chains for AI agents
but does not specify exact claim semantics, scope subset enforcement, or
audit log structure.  The IETF draft <xref target="AGENTJWT"/> covers similar ground
in the JWT format domain.  The draft <xref target="OBO01"/> addresses delegation in
the OAuth authorization code flow context.  ACAP occupies a different
point in the design space: it is a self-contained signed-token format
with no external authorization server required at verification time.</t>

</section>
</section>
<section anchor="conventions-and-definitions"><name>Conventions and Definitions</name>

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

</section>
<section anchor="terminology"><name>Terminology</name>

<dl>
  <dt>Issuer:</dt>
  <dd>
    <t>The service that creates and signs ACAP credentials.  The Issuer holds
an RSA private key and is identified by a URI recorded in the <spanx style="verb">iss</spanx> JWT
claim.  A single Issuer MAY serve multiple task trees.</t>
  </dd>
  <dt>Root Credential:</dt>
  <dd>
    <t>An ACAP credential whose <spanx style="verb">att_depth</spanx> is 0 and whose <spanx style="verb">att_pid</spanx> is
absent.  A root credential is issued directly by the Issuer in response
to a human principal's instruction.  Its <spanx style="verb">att_chain</spanx> contains exactly
one element: its own <spanx style="verb">jti</spanx>.</t>
  </dd>
  <dt>Delegated Credential:</dt>
  <dd>
    <t>An ACAP credential whose <spanx style="verb">att_depth</spanx> is greater than 0.  A delegated
credential is derived from a parent credential and MUST have <spanx style="verb">att_pid</spanx>
set to the parent's <spanx style="verb">jti</spanx>.  Its scope MUST be a subset of the parent's
scope and its expiry MUST NOT exceed the parent's expiry.</t>
  </dd>
  <dt>Task Tree:</dt>
  <dd>
    <t>The complete graph of credentials that share the same <spanx style="verb">att_tid</spanx>.  A
task tree has exactly one root credential; all other credentials in the
tree are delegated credentials descended from it.</t>
  </dd>
  <dt>Intent Hash:</dt>
  <dd>
    <t>The value of the <spanx style="verb">att_intent</spanx> claim: a lowercase hex-encoded SHA-256
digest of the UTF-8 encoding of the original human instruction string.
The intent hash is set at root issuance and propagated unchanged to all
descendants.</t>
  </dd>
  <dt>Depth:</dt>
  <dd>
    <t>The integer value of <spanx style="verb">att_depth</spanx>.  Depth 0 identifies a root
credential.  Each delegation increments depth by exactly 1.  The maximum
permitted depth is <spanx style="verb">MaxDelegationDepth</spanx> (10).</t>
  </dd>
  <dt>Chain:</dt>
  <dd>
    <t>The ordered list of JWT IDs in <spanx style="verb">att_chain</spanx>.  For a credential at
depth D, the chain contains exactly D+1 elements: the root credential's
<spanx style="verb">jti</spanx> at index 0, followed by each intermediate credential's <spanx style="verb">jti</spanx> in
delegation order, with the current credential's <spanx style="verb">jti</spanx> at the final
position (index D).</t>
  </dd>
  <dt>Scope Entry:</dt>
  <dd>
    <t>A string of the form <spanx style="verb">resource:action</spanx> where <spanx style="verb">resource</spanx> and <spanx style="verb">action</spanx>
are non-empty strings.  The wildcard character <spanx style="verb">*</spanx> MAY appear in either
position.</t>
  </dd>
</dl>

</section>
<section anchor="credential-format"><name>Credential Format</name>

<section anchor="overview"><name>Overview</name>

<t>An ACAP credential is a JSON Web Token <xref target="RFC7519"/> with:</t>

<t><list style="symbols">
  <t>Header: <spanx style="verb">{ "alg": "RS256", "typ": "JWT" }</spanx></t>
  <t>Payload: the claims defined in <xref target="standard-jwt-claims"/> and
<xref target="acap-extension-claims"/></t>
  <t>Signature: RS256 over the ASCII representation of the header and
payload</t>
</list></t>

<t>All implementations MUST use RS256 (RSASSA-PKCS1-v1_5 using SHA-256
<xref target="RFC7518"/>) as the signing algorithm.  No other signing algorithm is
permitted.</t>

</section>
<section anchor="standard-jwt-claims"><name>Standard JWT Claims</name>

<t>The following standard JWT claims are used.  All are REQUIRED unless
noted.</t>

<texttable>
      <ttcol align='left'>Claim</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">iss</spanx></c>
      <c>string</c>
      <c>REQUIRED</c>
      <c>Issuer URI</c>
      <c><spanx style="verb">sub</spanx></c>
      <c>string</c>
      <c>REQUIRED</c>
      <c>Subject. MUST be of the form <spanx style="verb">agent:{agent_id}</spanx></c>
      <c><spanx style="verb">iat</spanx></c>
      <c>NumericDate</c>
      <c>REQUIRED</c>
      <c>Issued-at time (Unix epoch seconds, UTC)</c>
      <c><spanx style="verb">exp</spanx></c>
      <c>NumericDate</c>
      <c>REQUIRED</c>
      <c>Expiry time (Unix epoch seconds, UTC)</c>
      <c><spanx style="verb">jti</spanx></c>
      <c>string</c>
      <c>REQUIRED</c>
      <c>JWT ID. A UUID v4 <xref target="RFC9562"/> that uniquely identifies this credential</c>
</texttable>

<t>The <spanx style="verb">sub</spanx> claim MUST match the pattern <spanx style="verb">^agent:[A-Za-z0-9_\-]+$</spanx>.
Implementations MUST reject credentials whose <spanx style="verb">sub</spanx> does not begin with
the literal prefix <spanx style="verb">agent:</spanx>.</t>

</section>
<section anchor="acap-extension-claims"><name>ACAP Extension Claims</name>

<t>All ACAP-specific claims are prefixed with <spanx style="verb">att_</spanx>.  Implementations MUST
ignore unknown <spanx style="verb">att_*</spanx> claims to allow forward compatibility.</t>

<texttable>
      <ttcol align='left'>Claim</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">att_tid</spanx></c>
      <c>string (UUID v4)</c>
      <c>REQUIRED</c>
      <c>Task tree identifier</c>
      <c><spanx style="verb">att_pid</spanx></c>
      <c>string (UUID v4)</c>
      <c>CONDITIONAL</c>
      <c>Parent credential identifier</c>
      <c><spanx style="verb">att_depth</spanx></c>
      <c>integer</c>
      <c>REQUIRED</c>
      <c>Delegation depth (0 for root)</c>
      <c><spanx style="verb">att_scope</spanx></c>
      <c>array of strings</c>
      <c>REQUIRED</c>
      <c>Permission set</c>
      <c><spanx style="verb">att_intent</spanx></c>
      <c>string (hex)</c>
      <c>REQUIRED</c>
      <c>SHA-256 of original instruction (64 hex chars)</c>
      <c><spanx style="verb">att_chain</spanx></c>
      <c>array of strings</c>
      <c>REQUIRED</c>
      <c>Ordered list of JTIs from root to current</c>
      <c><spanx style="verb">att_uid</spanx></c>
      <c>string</c>
      <c>REQUIRED</c>
      <c>Originating human user identifier</c>
      <c><spanx style="verb">att_hitl_req</spanx></c>
      <c>string (UUID v4)</c>
      <c>OPTIONAL</c>
      <c>HITL approval request ID</c>
      <c><spanx style="verb">att_hitl_uid</spanx></c>
      <c>string</c>
      <c>OPTIONAL</c>
      <c>Identity of the human who approved</c>
      <c><spanx style="verb">att_hitl_iss</spanx></c>
      <c>string</c>
      <c>OPTIONAL</c>
      <c>IdP issuer of the approving human</c>
      <c><spanx style="verb">att_idp_iss</spanx></c>
      <c>string</c>
      <c>OPTIONAL</c>
      <c>IdP issuer from root OIDC session</c>
      <c><spanx style="verb">att_idp_sub</spanx></c>
      <c>string</c>
      <c>OPTIONAL</c>
      <c>IdP subject from root OIDC session</c>
      <c><spanx style="verb">att_ack</spanx></c>
      <c>string</c>
      <c>OPTIONAL</c>
      <c>Agent binary checksum digest</c>
</texttable>

<t><spanx style="verb">att_pid</spanx> MUST be present when <spanx style="verb">att_depth</spanx> &gt; 0 and MUST be absent when
<spanx style="verb">att_depth</spanx> == 0.</t>

<t><spanx style="verb">att_tid</spanx>, <spanx style="verb">att_intent</spanx>, and <spanx style="verb">att_uid</spanx> MUST be propagated unchanged
through all delegations.</t>

</section>
<section anchor="concrete-examples"><name>Concrete Examples</name>

<section anchor="root-credential-payload"><name>Root Credential Payload</name>

<figure><sourcecode type="json"><![CDATA[
{
  "iss": "https://attest.example.com",
  "sub": "agent:inbox-agent-v2",
  "iat": 1742386800,
  "exp": 1742473200,
  "jti": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "att_tid": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "att_depth": 0,
  "att_scope": ["email:read", "email:draft"],
  "att_intent": "3b4c2a1f8e7d6c5b4a3f2e1d0c9b8a7f...",
  "att_chain": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
  "att_uid": "user:alice"
}
]]></sourcecode></figure>

<t>Note that <spanx style="verb">att_pid</spanx> is absent because this is a root credential.  The
<spanx style="verb">att_chain</spanx> contains exactly one element -- the credential's own <spanx style="verb">jti</spanx>.</t>

</section>
<section anchor="delegated-credential-payload"><name>Delegated Credential Payload</name>

<figure><sourcecode type="json"><![CDATA[
{
  "iss": "https://attest.example.com",
  "sub": "agent:summariser-agent-v1",
  "iat": 1742387100,
  "exp": 1742473200,
  "jti": "c3d4e5f6-a7b8-9012-cdef-012345678901",
  "att_tid": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "att_pid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "att_depth": 1,
  "att_scope": ["email:read"],
  "att_intent": "3b4c2a1f8e7d6c5b4a3f2e1d0c9b8a7f...",
  "att_chain": [
    "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "c3d4e5f6-a7b8-9012-cdef-012345678901"
  ],
  "att_uid": "user:alice"
}
]]></sourcecode></figure>

</section>
</section>
</section>
<section anchor="scope-model"><name>Scope Model</name>

<section anchor="scope-entry-format"><name>Scope Entry Format</name>

<t>A scope entry is a string conforming to the grammar:</t>

<figure><artwork><![CDATA[
scope-entry = resource ":" action
resource    = 1*( ALPHA / DIGIT / "_" / "-" / "*" )
action      = 1*( ALPHA / DIGIT / "_" / "-" / "*" )
]]></artwork></figure>

<t>Both <spanx style="verb">resource</spanx> and <spanx style="verb">action</spanx> MUST be non-empty.  Implementations MUST
reject invalid scope entries at all stages: issuance, delegation, and
verification.</t>

</section>
<section anchor="wildcard-rules"><name>Wildcard Rules</name>

<t>The wildcard character <spanx style="verb">*</spanx> MAY appear as the entirety of either the
<spanx style="verb">resource</spanx> or <spanx style="verb">action</spanx> component (or both).  Coverage rules:</t>

<t><list style="symbols">
  <t>P covers C if P.resource equals <spanx style="verb">*</spanx> OR P.resource equals C.resource</t>
  <t>AND P.action equals <spanx style="verb">*</spanx> OR P.action equals C.action</t>
</list></t>

<t>Consequently <spanx style="verb">*:*</spanx> covers every valid scope entry, <spanx style="verb">email:*</spanx> covers
<spanx style="verb">email:read</spanx>, <spanx style="verb">email:draft</spanx>, etc.</t>

</section>
<section anchor="normalisescope"><name>NormaliseScope</name>

<t>Before storing scope in any credential or comparing scopes,
implementations MUST apply the NormaliseScope procedure:</t>

<t><list style="numbers" type="1">
  <t>Trim leading and trailing whitespace from each entry.</t>
  <t>Remove any empty entries that result from trimming.</t>
  <t>Remove duplicate entries, preserving the first occurrence.</t>
  <t>Return the resulting list in insertion order.</t>
</list></t>

</section>
<section anchor="issubset-algorithm"><name>IsSubset Algorithm</name>

<figure><artwork><![CDATA[
function IsSubset(parentScope, childScope):
    for each entry CE in childScope:
        childEntry = ParseScope(CE)
        if childEntry is invalid:
            return false
        covered = false
        for each entry PE in parentScope:
            parentEntry = ParseScope(PE)
            if parentEntry is invalid:
                continue
            if EntryCovers(parentEntry, childEntry):
                covered = true
                break
        if not covered:
            return false
    return true

function EntryCovers(parent, child):
    resourceOK = (parent.Resource == "*") OR
                 (parent.Resource == child.Resource)
    actionOK   = (parent.Action  == "*") OR
                 (parent.Action  == child.Action)
    return resourceOK AND actionOK
]]></artwork></figure>

</section>
</section>
<section anchor="issuance"><name>Issuance</name>

<section anchor="overview-1"><name>Overview</name>

<t>Issuance creates a root credential (depth 0) that anchors a new task
tree.  The Issuer MUST perform all validation checks before constructing
the credential.  The Issuer MUST sign the credential with its RSA
private key using RS256.</t>

</section>
<section anchor="input-validation"><name>Input Validation</name>

<t>The Issuer MUST reject the issuance request if any of the following
conditions hold:</t>

<t><list style="numbers" type="1">
  <t><spanx style="verb">agent_id</spanx> is absent or empty.</t>
  <t><spanx style="verb">user_id</spanx> is absent or empty.</t>
  <t><spanx style="verb">scope</spanx> is absent or contains no entries.</t>
  <t>Any entry in <spanx style="verb">scope</spanx> is not parseable as a valid scope entry.</t>
  <t><spanx style="verb">instruction</spanx> is absent or empty.</t>
</list></t>

</section>
<section anchor="intent-hash-computation"><name>Intent Hash Computation</name>

<t>The intent hash is computed as:</t>

<figure><artwork><![CDATA[
att_intent = lowercase-hex( SHA-256( UTF-8-encode( instruction ) ) )
]]></artwork></figure>

<t>The <spanx style="verb">instruction</spanx> string MUST be encoded as UTF-8 before hashing.  The
resulting 32-byte SHA-256 digest MUST be encoded as 64 lowercase
hexadecimal characters.  No canonicalization is applied to the
instruction before hashing; the raw UTF-8 bytes are hashed as-is.</t>

</section>
<section anchor="identifier-generation"><name>Identifier Generation</name>

<t>The Issuer MUST generate two UUID v4 <xref target="RFC9562"/> values at issuance:</t>

<t><list style="symbols">
  <t><spanx style="verb">jti</spanx>: the unique identifier for this credential.</t>
  <t><spanx style="verb">att_tid</spanx>: the task tree identifier.</t>
</list></t>

<t>Both values MUST be generated using a cryptographically secure random
source.</t>

</section>
<section anchor="ttl-and-expiry"><name>TTL and Expiry</name>

<t><list style="numbers" type="1">
  <t>If <spanx style="verb">ttl_seconds</spanx> is zero, the TTL defaults to <spanx style="verb">DefaultTTLSeconds</spanx>
(3600 seconds).</t>
  <t>If <spanx style="verb">ttl_seconds</spanx> is negative, the issuance MUST be rejected.</t>
  <t>If <spanx style="verb">ttl_seconds</spanx> exceeds <spanx style="verb">MaxTTLSeconds</spanx> (86400 seconds), the TTL is
capped at <spanx style="verb">MaxTTLSeconds</spanx>.</t>
  <t><spanx style="verb">exp = iat + ttl_seconds</spanx> (after applying the rules above).</t>
</list></t>

</section>
<section anchor="root-credential-construction"><name>Root Credential Construction</name>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Value</ttcol>
      <c><spanx style="verb">iss</spanx></c>
      <c>Issuer URI</c>
      <c><spanx style="verb">sub</spanx></c>
      <c><spanx style="verb">"agent:" + agent_id</spanx></c>
      <c><spanx style="verb">iat</spanx></c>
      <c>Current UTC time</c>
      <c><spanx style="verb">exp</spanx></c>
      <c><spanx style="verb">iat + ttl</spanx></c>
      <c><spanx style="verb">jti</spanx></c>
      <c>Freshly generated UUID v4</c>
      <c><spanx style="verb">att_tid</spanx></c>
      <c>Freshly generated UUID v4</c>
      <c><spanx style="verb">att_pid</spanx></c>
      <c>Absent</c>
      <c><spanx style="verb">att_depth</spanx></c>
      <c><spanx style="verb">0</spanx></c>
      <c><spanx style="verb">att_scope</spanx></c>
      <c><spanx style="verb">NormaliseScope(scope)</spanx></c>
      <c><spanx style="verb">att_intent</spanx></c>
      <c><spanx style="verb">hex(SHA-256(UTF-8(instruction)))</spanx></c>
      <c><spanx style="verb">att_chain</spanx></c>
      <c><spanx style="verb">[ jti ]</spanx></c>
      <c><spanx style="verb">att_uid</spanx></c>
      <c><spanx style="verb">user_id</spanx></c>
</texttable>

</section>
</section>
<section anchor="delegation"><name>Delegation</name>

<section anchor="overview-2"><name>Overview</name>

<t>Delegation creates a child credential derived from an existing parent
credential.  The result is a credential at <spanx style="verb">att_depth + 1</spanx> with a scope
that is a subset of the parent's scope and an expiry no later than the
parent's expiry.</t>

</section>
<section anchor="input-validation-1"><name>Input Validation</name>

<t>The Issuer MUST reject a delegation request if:</t>

<t><list style="numbers" type="1">
  <t><spanx style="verb">parent_token</spanx> is absent or empty.</t>
  <t><spanx style="verb">child_agent</spanx> is absent or empty.</t>
  <t><spanx style="verb">child_scope</spanx> is absent or contains no entries.</t>
</list></t>

</section>
<section anchor="parent-token-verification"><name>Parent Token Verification</name>

<t>The Issuer MUST:</t>

<t><list style="numbers" type="1">
  <t>Verify the RS256 signature against the Issuer's public key.</t>
  <t>Verify that the parent token has not expired (<spanx style="verb">exp &gt; now</spanx>).</t>
  <t>Verify that the signing algorithm is <spanx style="verb">RS256</spanx>.</t>
</list></t>

</section>
<section anchor="scope-subset-enforcement"><name>Scope Subset Enforcement</name>

<t>The Issuer MUST apply NormaliseScope to the requested <spanx style="verb">child_scope</spanx>.
The Issuer MUST then apply IsSubset(parentScope, childScope).  If
IsSubset returns <spanx style="verb">false</spanx>, the delegation MUST be rejected.</t>

</section>
<section anchor="depth-limit"><name>Depth Limit</name>

<t>The Issuer MUST check that <spanx style="verb">parent.att_depth &lt; MaxDelegationDepth</spanx> (10).
If the parent's depth equals or exceeds the limit, the delegation MUST
be rejected.</t>

</section>
<section anchor="expiry-computation"><name>Expiry Computation</name>

<figure><artwork><![CDATA[
parent_exp = parent.exp

if ttl_seconds > 0:
    requested_exp = now + ttl_seconds
    child_exp = min(requested_exp, parent_exp)
else:
    default_exp = now + DefaultTTLSeconds
    child_exp = min(default_exp, parent_exp)
]]></artwork></figure>

<t>The child's expiry MUST NOT exceed the parent's expiry.</t>

</section>
<section anchor="delegated-credential-construction"><name>Delegated Credential Construction</name>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Value</ttcol>
      <c><spanx style="verb">iss</spanx></c>
      <c>Issuer URI</c>
      <c><spanx style="verb">sub</spanx></c>
      <c><spanx style="verb">"agent:" + child_agent</spanx></c>
      <c><spanx style="verb">iat</spanx></c>
      <c>Current UTC time</c>
      <c><spanx style="verb">exp</spanx></c>
      <c><spanx style="verb">min(now + ttl_seconds, parent.exp)</spanx></c>
      <c><spanx style="verb">jti</spanx></c>
      <c>Freshly generated UUID v4</c>
      <c><spanx style="verb">att_tid</spanx></c>
      <c><spanx style="verb">parent.att_tid</spanx> (propagated)</c>
      <c><spanx style="verb">att_pid</spanx></c>
      <c><spanx style="verb">parent.jti</spanx></c>
      <c><spanx style="verb">att_depth</spanx></c>
      <c><spanx style="verb">parent.att_depth + 1</spanx></c>
      <c><spanx style="verb">att_scope</spanx></c>
      <c><spanx style="verb">NormaliseScope(child_scope)</spanx></c>
      <c><spanx style="verb">att_intent</spanx></c>
      <c><spanx style="verb">parent.att_intent</spanx> (propagated)</c>
      <c><spanx style="verb">att_chain</spanx></c>
      <c><spanx style="verb">parent.att_chain + [ jti ]</spanx></c>
      <c><spanx style="verb">att_uid</spanx></c>
      <c><spanx style="verb">parent.att_uid</spanx> (propagated)</c>
</texttable>

</section>
</section>
<section anchor="verification"><name>Verification</name>

<section anchor="overview-3"><name>Overview</name>

<t>A credential is valid if and only if all of the following conditions are
satisfied:</t>

<t><list style="numbers" type="1">
  <t>The RS256 signature verifies against the Issuer's public key.</t>
  <t>The current time is before <spanx style="verb">exp</spanx> (subject to clock-skew allowance).</t>
  <t>The length of <spanx style="verb">att_chain</spanx> equals <spanx style="verb">att_depth + 1</spanx>.</t>
  <t>The final element of <spanx style="verb">att_chain</spanx> equals <spanx style="verb">jti</spanx>.</t>
  <t>The <spanx style="verb">jti</spanx> is not present in the revocation store.</t>
</list></t>

</section>
<section anchor="verification-algorithm"><name>Verification Algorithm</name>

<figure><artwork><![CDATA[
function Verify(tokenString, issuerPublicKey, revocationStore):

    // Step 1: Signature and expiry
    claims, err = RS256Parse(tokenString, issuerPublicKey)
    if err is not nil:
        return invalid("signature verification failed")

    // Step 2: Chain length invariant
    expectedLen = claims.att_depth + 1
    if len(claims.att_chain) != expectedLen:
        return invalid("chain length mismatch")

    // Step 3: Chain tail invariant
    if claims.att_chain[len(claims.att_chain) - 1] != claims.jti:
        return invalid("chain tail does not match jti")

    // Step 4: Revocation check
    if revocationStore.IsRevoked(claims.jti):
        return invalid("credential has been revoked")

    return valid(claims)
]]></artwork></figure>

</section>
<section anchor="warnings-vs-hard-failures"><name>Warnings vs. Hard Failures</name>

<t>Chain length and chain tail inconsistencies are surfaced as warnings
that cause the credential to be reported as invalid.  The warning
mechanism exists to distinguish between cryptographic failures (which may
indicate active attack) and structural inconsistencies (which may
indicate implementation bugs).</t>

</section>
</section>
<section anchor="revocation"><name>Revocation</name>

<section anchor="semantics"><name>Semantics</name>

<t>Revocation permanently invalidates a credential identified by its <spanx style="verb">jti</spanx>.
Once revoked, a credential MUST be treated as invalid regardless of its
<spanx style="verb">exp</spanx> claim.  Revocation is irreversible.</t>

</section>
<section anchor="cascade-semantics"><name>Cascade Semantics</name>

<t>Revoking a credential with <spanx style="verb">jti</spanx> X automatically revokes every
credential whose <spanx style="verb">att_chain</spanx> contains X:</t>

<figure><artwork><![CDATA[
Revoke(X):
    targets = { jti | jti == X OR X in credentials[jti].att_chain }
    for each T in targets:
        revocations.insert(T, now, revokedBy)
]]></artwork></figure>

<t>Cascade revocation SHOULD be performed atomically within a single
database transaction.</t>

</section>
<section anchor="revocation-store"><name>Revocation Store</name>

<t>The revocation store records:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">jti</spanx></c>
      <c>text (PK)</c>
      <c>The revoked credential identifier</c>
      <c><spanx style="verb">revoked_at</spanx></c>
      <c>timestamptz</c>
      <c>UTC timestamp of revocation</c>
      <c><spanx style="verb">revoked_by</spanx></c>
      <c>text</c>
      <c>Agent or user ID that triggered revocation</c>
</texttable>

<t>Duplicate revocation attempts MUST be treated as a no-op (idempotent).</t>

</section>
<section anchor="lifetime-interaction"><name>Lifetime Interaction</name>

<t>A credential that has expired is invalid regardless of the revocation
store.  A credential that has been revoked is invalid regardless of
whether it has expired.  These are independent failure conditions.</t>

</section>
</section>
<section anchor="human-in-the-loop-approval"><name>Human-in-the-Loop Approval</name>

<section anchor="overview-4"><name>Overview</name>

<t>Certain delegations require explicit human approval before being
granted.  ACAP defines an approval protocol that makes the human
decision a cryptographic event embedded in the resulting credential.</t>

</section>
<section anchor="approval-lifecycle"><name>Approval Lifecycle</name>

<t>The HITL approval flow consists of four phases:</t>

<t><list style="numbers" type="1">
  <t><strong>Request.</strong>  The agent sends an approval request containing the
<spanx style="verb">parent_token</spanx>, requested <spanx style="verb">child_scope</spanx>, an <spanx style="verb">intent</spanx> description,
and the <spanx style="verb">agent_id</spanx>.  The Issuer creates a pending approval record
and returns a <spanx style="verb">challenge_id</spanx>.</t>
  <t><strong>Poll.</strong>  The agent polls for approval status using the
<spanx style="verb">challenge_id</spanx>.  Status is one of: <spanx style="verb">pending</spanx>, <spanx style="verb">approved</spanx>,
<spanx style="verb">rejected</spanx>, or <spanx style="verb">expired</spanx>.</t>
  <t><strong>Grant or Deny.</strong>  A human reviews the request via a dashboard or
integration.  To grant, the human authenticates via an OIDC Identity
Provider and the Issuer verifies the <spanx style="verb">id_token</spanx>.  The Issuer records
the human's identity and marks the approval as granted.</t>
  <t><strong>Credential Issuance.</strong>  Upon grant, the Issuer delegates a new
credential from the parent token with the approved scope.  The
credential carries <spanx style="verb">att_hitl_req</spanx>, <spanx style="verb">att_hitl_uid</spanx>, and
<spanx style="verb">att_hitl_iss</spanx>.</t>
</list></t>

</section>
<section anchor="approval-expiry"><name>Approval Expiry</name>

<t>Pending approvals MUST expire after a bounded time window.
Implementations MUST NOT allow approvals to remain pending indefinitely.
An expired approval MUST be treated identically to a rejection.</t>

</section>
<section anchor="parent-token-re-verification"><name>Parent Token Re-verification</name>

<t>When an approval is granted, the Issuer MUST re-verify the parent token
before issuing the delegated credential.  If the parent token has
expired or been revoked while the approval was pending, the Issuer MUST
reject the grant.</t>

</section>
<section anchor="hitl-claims-propagation"><name>HITL Claims Propagation</name>

<t>The HITL claims (<spanx style="verb">att_hitl_req</spanx>, <spanx style="verb">att_hitl_uid</spanx>, <spanx style="verb">att_hitl_iss</spanx>) from
the most recent human approval propagate to all subsequent delegations.
If a new HITL approval occurs at a deeper delegation, the new claims
replace the inherited ones.</t>

</section>
<section anchor="multi-tenant-isolation"><name>Multi-Tenant Isolation</name>

<t>Approval requests are scoped to the authenticated organization.  An
approval created by org A MUST NOT be resolvable by org B.</t>

</section>
</section>
<section anchor="audit-log"><name>Audit Log</name>

<section anchor="structure"><name>Structure</name>

<t>The audit log is an append-only, hash-chained record of credential
lifecycle events.  Each entry commits to the previous entry's hash,
making the log tamper-evident.</t>

<t>The audit log is partitioned by <spanx style="verb">att_tid</spanx>.  Each task tree has its own
independent hash chain.  The first event uses a genesis hash of 64
ASCII zero characters as the previous hash value.</t>

</section>
<section anchor="entry-hash-computation"><name>Entry Hash Computation</name>

<figure><artwork><![CDATA[
entry_hash = lowercase-hex( SHA-256(
    prev_hash
    || event_type
    || jti
    || created_at_rfc3339nano
) )
]]></artwork></figure>

<t>where <spanx style="verb">||</spanx> denotes string concatenation.  The genesis hash is:</t>

<figure><artwork><![CDATA[
"00000000000000000000000000000000\
 00000000000000000000000000000000"
]]></artwork></figure>

<t>(64 ASCII zero characters.)</t>

</section>
<section anchor="event-types"><name>Event Types</name>

<texttable>
      <ttcol align='left'>Event Type</ttcol>
      <ttcol align='left'>Trigger</ttcol>
      <c><spanx style="verb">issued</spanx></c>
      <c>Root credential issued</c>
      <c><spanx style="verb">delegated</spanx></c>
      <c>Delegated credential issued</c>
      <c><spanx style="verb">verified</spanx></c>
      <c>Credential verified</c>
      <c><spanx style="verb">revoked</spanx></c>
      <c>Credential revoked (one event per cascade target)</c>
      <c><spanx style="verb">expired</spanx></c>
      <c>Credential reached <spanx style="verb">exp</spanx> time</c>
      <c><spanx style="verb">hitl_granted</spanx></c>
      <c>Human approved a HITL request</c>
      <c><spanx style="verb">action</spanx></c>
      <c>Agent executed a registered action</c>
      <c><spanx style="verb">lifecycle</spanx></c>
      <c>Agent lifecycle transition (started/completed/failed)</c>
</texttable>

</section>
<section anchor="audit-entry-fields"><name>Audit Entry Fields</name>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">id</spanx></c>
      <c>bigserial</c>
      <c>Monotonically increasing row ID</c>
      <c><spanx style="verb">prev_hash</spanx></c>
      <c>text</c>
      <c>Hash of the prior entry for same <spanx style="verb">att_tid</spanx></c>
      <c><spanx style="verb">entry_hash</spanx></c>
      <c>text</c>
      <c>SHA-256 of concatenated fields</c>
      <c><spanx style="verb">event_type</spanx></c>
      <c>text</c>
      <c>One of the defined event types</c>
      <c><spanx style="verb">jti</spanx></c>
      <c>text</c>
      <c>JWT ID of the credential involved</c>
      <c><spanx style="verb">org_id</spanx></c>
      <c>text</c>
      <c>Tenant identifier</c>
      <c><spanx style="verb">att_tid</spanx></c>
      <c>text</c>
      <c>Task tree identifier</c>
      <c><spanx style="verb">att_uid</spanx></c>
      <c>text</c>
      <c>Human principal identifier</c>
      <c><spanx style="verb">agent_id</spanx></c>
      <c>text</c>
      <c>Agent identifier</c>
      <c><spanx style="verb">scope</spanx></c>
      <c>jsonb</c>
      <c>Scope array at time of event</c>
      <c><spanx style="verb">meta</spanx></c>
      <c>jsonb</c>
      <c>Optional implementation-defined metadata</c>
      <c><spanx style="verb">created_at</spanx></c>
      <c>timestamptz</c>
      <c>UTC timestamp</c>
</texttable>

</section>
<section anchor="append-only-enforcement"><name>Append-Only Enforcement</name>

<t>Implementations MUST enforce append-only semantics on the audit log.</t>

</section>
<section anchor="log-verification"><name>Log Verification</name>

<t>To verify the integrity of the audit log for a given <spanx style="verb">att_tid</spanx>:</t>

<t><list style="numbers" type="1">
  <t>Retrieve all entries in ascending <spanx style="verb">id</spanx> order.</t>
  <t>For each entry starting at the second, verify that <spanx style="verb">entry.prev_hash</spanx>
equals the <spanx style="verb">entry_hash</spanx> of the preceding entry.</t>
  <t>Recompute <spanx style="verb">entry_hash</spanx> from the raw fields and verify it matches.</t>
</list></t>

<t>Any discrepancy indicates tampering or corruption.</t>

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

<section anchor="prompt-injection"><name>Prompt Injection</name>

<t>ACAP credentials bind to the intent hash of the original instruction,
but they do not prevent a legitimate credential from being used by a
compromised agent.  The narrow, monotone-reducing scope model limits the
blast radius of a compromised agent.  The intent hash enables post-hoc
detection of misuse.  The <spanx style="verb">att_ack</spanx> claim carries a checksum of the
agent binary for agent substitution detection.</t>

</section>
<section anchor="replay-attacks"><name>Replay Attacks</name>

<t>Credentials carry a unique <spanx style="verb">jti</spanx>.  Verifiers MUST check the revocation
store on every verification call.  The <spanx style="verb">exp</spanx> claim bounds the replay
window for non-revoked credentials.  Verifiers SHOULD maintain a
short-term cache of recently seen <spanx style="verb">jti</spanx> values.</t>

</section>
<section anchor="scope-creep"><name>Scope Creep</name>

<t>Scope creep is prevented by IsSubset enforcement at delegation time.
Resource servers MUST verify that the presented credential's <spanx style="verb">att_scope</spanx>
covers the requested operation.</t>

</section>
<section anchor="clock-skew"><name>Clock Skew</name>

<t>Implementations SHOULD allow a clock-skew leeway of up to 60 seconds.
Implementations MUST NOT allow a leeway of more than 300 seconds.</t>

</section>
<section anchor="key-management"><name>Key Management</name>

<t>The Issuer's RSA private key is the root of trust.  Compromise allows
forging credentials.  Implementations SHOULD use hardware security
modules and short key rotation periods.  The public key MUST be
distributed via an out-of-band mechanism (e.g., a JWKS endpoint).</t>

</section>
<section anchor="credential-store-integrity"><name>Credential Store Integrity</name>

<t>The revocation store and credential store are security-critical.
Implementations MUST apply access controls preventing unauthorized
modification.</t>

</section>
<section anchor="audit-log-integrity"><name>Audit Log Integrity</name>

<t>Hash-chaining provides tamper-evidence but not tamper-prevention.  The
audit log SHOULD be replicated to a write-once store or transparency log
for stronger guarantees.</t>

</section>
</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>This specification defines the following JWT claim names for
registration in the IANA "JSON Web Token Claims" registry established by
<xref target="RFC7519"/>.</t>

<texttable>
      <ttcol align='left'>Claim Name</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Change Controller</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c><spanx style="verb">att_tid</spanx></c>
      <c>ACAP task tree identifier</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_pid</spanx></c>
      <c>ACAP parent credential identifier</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_depth</spanx></c>
      <c>ACAP delegation depth</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_scope</spanx></c>
      <c>ACAP permission scope</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_intent</spanx></c>
      <c>ACAP intent hash</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_chain</spanx></c>
      <c>ACAP delegation chain</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_uid</spanx></c>
      <c>ACAP originating user identifier</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_hitl_req</spanx></c>
      <c>ACAP HITL request ID</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_hitl_uid</spanx></c>
      <c>ACAP HITL approving user</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_hitl_iss</spanx></c>
      <c>ACAP HITL issuer authority</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_idp_iss</spanx></c>
      <c>ACAP IdP issuer</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_idp_sub</spanx></c>
      <c>ACAP IdP subject</c>
      <c>IESG</c>
      <c>This document</c>
      <c><spanx style="verb">att_ack</spanx></c>
      <c>ACAP agent checksum digest</c>
      <c>IESG</c>
      <c>This document</c>
</texttable>

</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>
<reference anchor="RFC7519">
  <front>
    <title>JSON Web Token (JWT)</title>
    <author fullname="M. Jones" initials="M." surname="Jones"/>
    <author fullname="J. Bradley" initials="J." surname="Bradley"/>
    <author fullname="N. Sakimura" initials="N." surname="Sakimura"/>
    <date month="May" year="2015"/>
    <abstract>
      <t>JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7519"/>
  <seriesInfo name="DOI" value="10.17487/RFC7519"/>
</reference>
<reference anchor="RFC7518">
  <front>
    <title>JSON Web Algorithms (JWA)</title>
    <author fullname="M. Jones" initials="M." surname="Jones"/>
    <date month="May" year="2015"/>
    <abstract>
      <t>This specification registers cryptographic algorithms and identifiers to be used with the JSON Web Signature (JWS), JSON Web Encryption (JWE), and JSON Web Key (JWK) specifications. It defines several IANA registries for these identifiers.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="7518"/>
  <seriesInfo name="DOI" value="10.17487/RFC7518"/>
</reference>
<reference anchor="RFC6749">
  <front>
    <title>The OAuth 2.0 Authorization Framework</title>
    <author fullname="D. Hardt" initials="D." role="editor" surname="Hardt"/>
    <date month="October" year="2012"/>
    <abstract>
      <t>The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6749"/>
  <seriesInfo name="DOI" value="10.17487/RFC6749"/>
</reference>
<reference anchor="RFC9562">
  <front>
    <title>Universally Unique IDentifiers (UUIDs)</title>
    <author fullname="K. Davis" initials="K." surname="Davis"/>
    <author fullname="B. Peabody" initials="B." surname="Peabody"/>
    <author fullname="P. Leach" initials="P." surname="Leach"/>
    <date month="May" year="2024"/>
    <abstract>
      <t>This specification defines UUIDs (Universally Unique IDentifiers) --
also known as GUIDs (Globally Unique IDentifiers) -- and a Uniform
Resource Name namespace for UUIDs. A UUID is 128 bits long and is
intended to guarantee uniqueness across space and time. UUIDs were
originally used in the Apollo Network Computing System (NCS), later
in the Open Software Foundation's (OSF's) Distributed Computing
Environment (DCE), and then in Microsoft Windows platforms.</t>
      <t>This specification is derived from the OSF DCE specification with the
kind permission of the OSF (now known as "The Open Group"). Information from earlier versions of the OSF DCE specification have
been incorporated into this document. This document obsoletes RFC
4122.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9562"/>
  <seriesInfo name="DOI" value="10.17487/RFC9562"/>
</reference>
<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>



    </references>

    <references title='Informative References' anchor="sec-informative-references">

<reference anchor="OIDC" target="https://openid.net/specs/openid-connect-core-1_0.html">
  <front>
    <title>OpenID Connect Core 1.0</title>
    <author initials="N." surname="Sakimura" fullname="N. Sakimura">
      <organization></organization>
    </author>
    <author initials="J." surname="Bradley" fullname="J. Bradley">
      <organization></organization>
    </author>
    <author initials="M." surname="Jones" fullname="M. Jones">
      <organization></organization>
    </author>
    <author initials="B. de" surname="Medeiros" fullname="B. de Medeiros">
      <organization></organization>
    </author>
    <author initials="C." surname="Mortimore" fullname="C. Mortimore">
      <organization></organization>
    </author>
    <date year="2014" month="November"/>
  </front>
</reference>
<reference anchor="AGENTJWT" target="https://datatracker.ietf.org/doc/draft-goswami-agentic-jwt/">
  <front>
    <title>Agentic JWT: Secure Delegation Protocol for AI Agent Pipelines</title>
    <author initials="D." surname="Goswami" fullname="D. Goswami">
      <organization></organization>
    </author>
    <date year="2025"/>
  </front>
</reference>
<reference anchor="OBO01" target="https://datatracker.ietf.org/doc/draft-oauth-ai-agents-on-behalf-of-user/">
  <front>
    <title>OAuth 2.0 for AI Agents Acting on Behalf of Users</title>
    <author >
      <organization></organization>
    </author>
    <date year="2025"/>
  </front>
</reference>
<reference anchor="WIMSE" target="https://datatracker.ietf.org/wg/wimse/about/">
  <front>
    <title>IETF Workload Identity in Multi System Environments (WIMSE) Working Group</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>


    </references>

</references>


<?line 832?>

<section anchor="summary-of-constants"><name>Summary of Constants</name>

<texttable>
      <ttcol align='left'>Constant</ttcol>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">MaxDelegationDepth</spanx></c>
      <c>10</c>
      <c>Maximum permitted <spanx style="verb">att_depth</spanx></c>
      <c><spanx style="verb">DefaultTTLSeconds</spanx></c>
      <c>3600</c>
      <c>Default credential lifetime (1 hour)</c>
      <c><spanx style="verb">MaxTTLSeconds</spanx></c>
      <c>86400</c>
      <c>Maximum credential lifetime (24 hours)</c>
      <c>Genesis hash</c>
      <c>64 x "0"</c>
      <c>Previous hash for first audit entry</c>
      <c>Clock skew (SHOULD)</c>
      <c>60s</c>
      <c>Recommended leeway</c>
      <c>Clock skew (MUST NOT exceed)</c>
      <c>300s</c>
      <c>Maximum leeway</c>
</texttable>

</section>
<section anchor="implementation-status"><name>Implementation Status</name>

<t>A reference implementation is available as open source software:</t>

<t><list style="symbols">
  <t>Server: Go, available at https://github.com/chudah1/attest-dev</t>
  <t>TypeScript SDK: <spanx style="verb">@attest-dev/sdk</spanx> on npm (0.1.0-beta.4)</t>
  <t>Python SDK: <spanx style="verb">attest-sdk</spanx> on PyPI (0.1.0b3)</t>
  <t>Framework integrations: Anthropic Claude, LangGraph, OpenAI Agents
SDK, Model Context Protocol (MCP)</t>
  <t>Deployment: Docker Compose, Railway</t>
</list></t>

<t>All SDKs implement credential issuance, delegation, offline
verification via JWKS, revocation, and audit trail retrieval.</t>

</section>
<section anchor="data-model"><name>Data Model</name>

<t>The following SQL schema is informative for implementations using
relational storage:</t>

<figure><sourcecode type="sql"><![CDATA[
CREATE TABLE IF NOT EXISTS credentials (
    jti         TEXT        PRIMARY KEY,
    org_id      TEXT        NOT NULL,
    att_tid     TEXT        NOT NULL,
    att_pid     TEXT,
    att_uid     TEXT        NOT NULL,
    agent_id    TEXT        NOT NULL,
    depth       INTEGER     NOT NULL DEFAULT 0,
    scope       TEXT[]      NOT NULL,
    chain       TEXT[]      NOT NULL,
    issued_at   TIMESTAMPTZ NOT NULL,
    expires_at  TIMESTAMPTZ NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_credentials_chain
    ON credentials USING GIN (chain);

CREATE TABLE IF NOT EXISTS revocations (
    jti         TEXT        PRIMARY KEY,
    revoked_at  TIMESTAMPTZ NOT NULL,
    revoked_by  TEXT        NOT NULL
);

CREATE TABLE IF NOT EXISTS approvals (
    id              TEXT        PRIMARY KEY,
    org_id          TEXT        NOT NULL,
    agent_id        TEXT        NOT NULL,
    att_tid         TEXT        NOT NULL,
    parent_token    TEXT        NOT NULL,
    intent          TEXT        NOT NULL,
    requested_scope TEXT[]      NOT NULL,
    status          TEXT        NOT NULL DEFAULT 'pending',
    approved_by     TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    resolved_at     TIMESTAMPTZ
);

CREATE TABLE IF NOT EXISTS audit_log (
    id           BIGSERIAL   PRIMARY KEY,
    org_id       TEXT        NOT NULL,
    prev_hash    TEXT        NOT NULL,
    entry_hash   TEXT        NOT NULL,
    event_type   TEXT        NOT NULL,
    jti          TEXT        NOT NULL,
    att_tid      TEXT        NOT NULL,
    att_uid      TEXT        NOT NULL,
    agent_id     TEXT        NOT NULL,
    scope        JSONB       NOT NULL DEFAULT '[]',
    meta         JSONB,
    idp_issuer   TEXT,
    idp_subject  TEXT,
    hitl_req     TEXT,
    hitl_issuer  TEXT,
    hitl_subject TEXT,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE OR REPLACE RULE audit_log_no_update AS
    ON UPDATE TO audit_log DO INSTEAD NOTHING;
CREATE OR REPLACE RULE audit_log_no_delete AS
    ON DELETE TO audit_log DO INSTEAD NOTHING;
]]></sourcecode></figure>

</section>
<section numbered="false" anchor="acknowledgements"><name>Acknowledgements</name>

<t>The authors acknowledge the contributions of the broader AI safety and
identity communities, including the IETF WIMSE working group, the NIST
AI Agent Standards Initiative, and the authors of the Agentic JWT
proposal.</t>

</section>


  </back>

<!-- ##markdown-source:
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
REXxz6Yg5vpvzPI1B599AAA=

-->

</rfc>

