Draft Specification · AAP/1.0

Agent Authentication
Protocol

A decentralized, DNS-anchored protocol for verifying agent identity, establishing user delegation, and maintaining auditable trust chains in agentic systems.

AuthorOmofolarin Shonibare <folarinshonibare@gmail.com>
Version2.0-draft
StatusImplementation Ready
PublishedJune 2026
Changelog+Conformance · +Schemas · +Endpoints · +Vectors

The Agent Authentication Protocol (AAP) defines a lightweight, decentralized mechanism for AI agents to authenticate to third-party services on behalf of users. It separates three distinct concerns — operator identity, user delegation, and per-task consent — and resolves each with the most appropriate existing mechanism rather than introducing new infrastructure.

Operator identity is anchored to DNS and domain control, following the same trust model as TLS certificates. User delegation builds on OAuth 2.0. Per-task consent is captured as a signed, auditable receipt. No central authority is required. No model provider infrastructure is assumed.

The protocol defines two first-class identity modes: User-Delegated (the agent acts as a specific user, seeing only what they can see) and Service Account (fixed non-human credentials with explicitly declared scope — narrow or wide — authorized by an admin). Service account scope is not assumed to be org-wide; it is whatever was granted at bootstrap and nothing more.

This version adds: auto-revoke scope policies with five trigger types (time, task completion, inactivity, lifecycle events, usage budget) computed into a layered effective policy at grant time; token binding via DPoP to eliminate bearer token replay attacks; irreversible action safeguards including dry-run mode, undo windows, and pre-action confirmation for high-risk scopes; usage limits on consent receipts; cumulative consent visibility via a mandatory access-summary endpoint; multi-tenancy isolation requirements; protocol version negotiation; and a mandatory liability disclosure at bootstrap. All open questions from v1.0 are resolved.

§ 1

Motivation & Problem Statement

AI agents are acting on behalf of users at services they've never visited. Existing authentication protocols assume a human is present. They aren't.

The agentic era introduces a category of principal the web was not designed for: an automated system acting with delegated human authority, making decisions at machine speed, across services that have no prior relationship with the agent or its operator.

Three questions must be answered for every agentic interaction:

Q1 Who built this? Operator Identity

Which company or developer deployed this agent? Are they legitimate? Can we hold them accountable?

→ DNS-anchored operator manifest
Q2 Who authorized it? User Delegation

Did a real user — one known to this service — actually authorize this agent to act for them? When and under what conditions?

→ Service-issued delegation token
Q3 Within what bounds? Consent & Scope

What specifically did the user authorize? Is this particular action within those declared bounds? Can the user see what was done?

→ Signed consent receipt + intent headers

Existing approaches — hardcoded API keys, standard OAuth, session cookies — fail at least one of these questions when applied to agents. Section 8 (Alternatives) documents each approach and why it was not chosen.

§ 2

Trust Model

Trust is not binary. AAP defines four trust tiers that services can accept based on their risk tolerance.

Design Principle

Identity and trust are different problems. AAP solves identity — proving who an agent is and who authorized it. Trust (is this agent well-behaved?) is earned through reputation over time and is deliberately out of scope for this protocol.

2.1 The Three Trust Anchors

Anchor 1
DNS Control
Operator owns their domain. Same trust model as TLS.
Anchor 2
Service Auth
Service signs its own delegation tokens. Self-verifying.
Anchor 3
User Consent
Operator signs receipt at moment of explicit user approval.
Optional
Provider List
Model providers publish operator registries. Opt-in upgrade.

2.2 Tier Definitions

Tier What's Verified Required For Infrastructure Needed
T0 — Anonymous Nothing. Rejected by AAP.
T1 — Operator DNS domain control only Low-stakes APIs Static JSON file on operator domain
T2 — Delegated Operator + user delegation token User-data access T1 + one-time OAuth flow
T3 — Consented Operator + delegation + consent receipt Write/mutate operations T2 + consent UI in operator app
T4 — Provider-backed T3 + model provider operator registry High-stakes (financial, medical) T3 + provider participation

Services declare in their discovery manifest which tier they require. Agents that cannot meet the required tier must not proceed and should inform the user that manual authorization is needed.

§ 3

Service Discovery

Every service participating in AAP MUST host a machine-readable manifest at a predictable path. An optional human-readable companion document MAY be co-located.

Required path

GET /.well-known/agent-auth.json

Manifest schema

JSON{
  "spec": "aap/1.0",
  "service": "https://api.example.com",
  "display_name": "Example API",

  "minimum_tier": 2,           // T1–T4, service decides

  "scopes": [
    { "id": "data.read", "description": "Read user data" },
    { "id": "data.write", "description": "Modify user data" }
  ],

  "intent_required": true,       // agent must declare X-Agent-Intent
  "credential_ttl": 3600,       // max seconds before re-assertion
  "scope_expansion": "notify",  // "reject" | "notify" | "silent"

  "endpoints": {
    "register":  "/agent/register",
    "delegate":  "/agent/delegate",
    "revoke":    "/agent/revoke",
    "audit":     "/agent/audit"      // MANDATORY — see §7
  }
}

The agent discovers this document on first encountering a 401 response that includes the header WWW-Authenticate: Bearer agent_auth_required="/.well-known/agent-auth.json". Agents SHOULD proactively fetch this document before making any API call if they have reason to believe a service participates in AAP.

3.1 Multi-Tenant Discovery

The base spec assumes a single-tenant deployment: one domain, one discovery manifest, one set of scopes and policies. In practice, many AAP-implementing services are multi-tenant platforms — a single deployment serves many isolated projects or tenants, each with its own scopes, minimum trust tier, and auto-revoke policies. Firebase, Auth0, WorkOS, and Clerk all follow this model. This section defines how AAP discovery works in that context.

The problem

A multi-tenant auth service cannot serve a single global agent-auth.json that accurately describes every tenant. Project A may require T3 with DPoP; Project B may accept T1 without it. The endpoint URLs, available scopes, and safety configuration are all project-specific. Without guidance, implementers will invent incompatible solutions — custom headers, non-standard paths, or out-of-band configuration.

Two approaches

Multi-tenant services SHOULD support one of the following patterns for project-scoped discovery. Both keep the /.well-known/agent-auth.json path intact (preserving spec compliance and agent expectations) while allowing per-project configuration.

Pattern A: Query parameter scoping (RECOMMENDED)

The discovery endpoint accepts an optional projectId query parameter. When absent, it returns the service-level defaults — the platform's baseline capabilities, supported algorithms, and endpoint URL templates. When present, it returns the project-specific configuration with resolved endpoint URLs.

Service-level (no project)GET /.well-known/agent-auth.json

{
  "spec": "aap/2.0-draft",
  "service": "https://auth.example.com",
  "display_name": "Example Auth Platform",
  "minimum_tier": 1,
  "endpoints": {
    "register":  "/internal/projects/{projectId}/agent/register",
    "delegate":  "/internal/projects/{projectId}/agent/delegate",
    "revoke":    "/internal/projects/{projectId}/agent/revoke",
    "audit":     "/internal/projects/{projectId}/agent/audit"
  }
}
Project-scopedGET /.well-known/agent-auth.json?projectId=acme-prod

{
  "spec": "aap/2.0-draft",
  "service": "https://auth.example.com",
  "display_name": "Example Auth Platform",
  "project_id": "acme-prod",
  "minimum_tier": 3,
  "endpoints": {
    "register":  "/internal/projects/acme-prod/agent/register",
    "delegate":  "/internal/projects/acme-prod/agent/delegate",
    "revoke":    "/internal/projects/acme-prod/agent/revoke",
    "audit":     "/internal/projects/acme-prod/agent/audit"
  },
  "dpop_required": true
}

The service-level response uses URI templates (RFC 6570) with {projectId} placeholders in endpoint URLs. This tells the agent "you need a project ID to proceed" without requiring out-of-band documentation. Agents that already know their target project ID can skip the service-level call entirely and go straight to ?projectId=X.

This pattern is the simplest to implement — no infrastructure changes, no subdomain routing, no wildcard DNS. It mirrors how platforms like Firebase resolve project context via an API key in the query string.

Pattern B: Subdomain routing

Each project is assigned a subdomain. The agent queries /.well-known/agent-auth.json on the project's subdomain, and the response is inherently project-scoped because the domain itself identifies the tenant.

Subdomain-scopedGET https://acme-prod.auth.example.com/.well-known/agent-auth.json

{
  "spec": "aap/2.0-draft",
  "service": "https://acme-prod.auth.example.com",
  "project_id": "acme-prod",
  "minimum_tier": 3,
  "endpoints": {
    "register":  "/agent/register",
    "delegate":  "/agent/delegate",
    "revoke":    "/agent/revoke",
    "audit":     "/agent/audit"
  },
  "dpop_required": true
}

This is the cleanest from the agent's perspective — each project looks like a standalone AAP-compliant service with unmodified endpoint paths. However, it requires wildcard DNS (*.auth.example.com), wildcard TLS certificates, and subdomain-to-project routing middleware. This overhead is justified for platforms that already use subdomain isolation (e.g., Shopify, Heroku) but is excessive for most deployments.

What stays service-level

Regardless of the multi-tenant pattern chosen, the following endpoints MUST remain service-level (not project-scoped), because they describe the operator's platform identity and signing keys which are shared across all projects:

  • /.well-known/agent-identity.json — operator identity manifest (DNS-anchored to the platform domain)
  • /.well-known/agent-jwks.json — operator signing keys (used to verify all operator JWTs regardless of project)

Signing keys are infrastructure — they belong to the platform, not to any individual tenant. Per-project signing keys would multiply key management complexity without meaningful security benefit, since the trust anchor is DNS control of the platform domain, not the project identifier.

Implementation requirements

Multi-tenant services implementing AAP MUST:

  • Ensure complete data isolation between projects. A delegation created in Project A MUST NOT be usable in Project B. Access tokens, audit events, and usage counters are all project-scoped.
  • Include project_id in the project-scoped discovery response so agents can confirm they received the configuration for the intended project.
  • Return 404 (not 200 with defaults) when ?projectId=X references a project that does not exist, to prevent agents from silently operating against a nonexistent tenant.
  • Validate the project context on every operational endpoint — registration, delegation, revocation, and audit — not just at discovery time.
§ 4

Operator Identity via DNS

The operator identity problem is the same problem TLS solved for websites: how do you know you're talking to who you think you're talking to? The answer is the same — DNS and public-key cryptography.

Any entity deploying an AAP-compliant agent MUST host an identity manifest on their own domain. This file is the operator's identity card. It can be fetched and verified by any service without calling any third party.

Required path (on operator domain)

GET https://acme.com/.well-known/agent-identity.json

Identity manifest schema

JSON{
  "operator":       "Acme Corp",
  "domain":         "acme.com",
  "contact":        "security@acme.com",
  "since":          "2025-01-01",

  "signing_keys":   "https://acme.com/.well-known/agent-jwks.json",

  "model_providers": [
    "anthropic.com",
    "openai.com"
  ],

  // Optional: link to provider-published operator registries
  "provider_registry_urls": [
    "https://anthropic.com/.well-known/agent-operators.json"
  ]
}

4.1 How Verification Works

When an agent presents a JWT claiming to be from acme.com, the receiving service:

1. Service fetches acme.com/.well-known/agent-identity.json 2. Service fetches acme.com/.well-known/agent-jwks.json 3. Service verifies JWT signature against public keys 4. Service confirms JWT iss claim matches manifest domain 5. No third-party call required at verification time
Caching

Services SHOULD cache the identity manifest and JWKS with a TTL of no more than 1 hour. Key rotation is handled by the operator updating their JWKS endpoint. Short cache TTLs ensure revoked keys propagate within an acceptable window.

4.2 Model Provider Registries (Optional, T4)

Model providers MAY publish a list of verified operators at a well-known path. This is purely additive — services that want T4 guarantees can cross-reference this list. Providers are not required to participate for the base protocol to function.

GET https://anthropic.com/.well-known/agent-operators.json

JSON{
  "published": "2026-06-01T00:00:00Z",
  "operators": [
    {
      "domain":    "acme.com",
      "verified":  "2025-03-15",
      "standing":  "good"     // "good" | "suspended" | "revoked"
    }
  ]
}

This mirrors certificate transparency logs — Anthropic doesn't sign individual tokens, they simply maintain a public, inspectable list. Far lower operational burden than per-request signing.

§ 5

User Delegation

Operator identity answers "who built this agent." User delegation answers "did a real user at this service authorize it." These are separate claims requiring separate mechanisms.

The Bootstrap Principle

The very first interaction between a user and a service must be human-in-the-loop. There is no cryptographic shortcut around this, and there should not be. The entire delegation chain is rooted in this one moment of explicit human action. AAP embraces this rather than engineering around it.

5.1 Bootstrap Flow

When an agent discovers it lacks a delegation token for a given service, it MUST surface this to the user rather than proceeding anonymously or fabricating credentials.

Agent Service GET /api/resource Service Agent 401 · WWW-Authenticate: Bearer agent_auth_required="..." Agent User "I need you to authorize me with Example Service once" User Service standard login / OAuth (human present) Service User "Authorize Acme Corp agent to act for you?" [Approve] User User clicks Approve Service Agent delegation_token (signed by service) Agent stores token. All future interactions use it. Human not needed again.

5.2 Delegation Token Structure

The delegation token is a JWT signed by the service's own keys. It proves the service recognized this user and approved this specific operator's agent to act for them.

JWT PAYLOAD{
  "iss":          "api.example.com",      // service-signed
  "sub":          "john@example.com",
  "delegated_to": "acme.com",          // operator domain
  "delegation_id":"del_k9x2mq",
  "scopes":       ["data.read", "data.write"],
  "iat":          1748822400,
  "exp":          1780358400,           // long-lived; revocable via /agent/revoke
  "max_agent_ttl":3600                  // max TTL for derived access tokens
}

This token is never sufficient on its own to make API calls — it must be combined with a valid operator JWT. Possession of the delegation token without the matching operator private key is useless.

§ 7

Complete Request Flow

Combining all three layers, a fully verified AAP request works as follows. This example shows a T3 (Consented) interaction after bootstrap has already occurred.

─── Pre-flight: agent has delegation_token from earlier bootstrap ─── 1. User Agent "Schedule a meeting with Sarah next week" 2. Agent User Displays: "I'll need calendar.read + calendar.write. Approve?" User Agent Approves → operator platform creates consent_receipt JWT 3. Agent Service POST /agent/register { operator_jwt, delegation_token, consent_receipt } Service verifies operator_jwt against acme.com JWKS Service verifies delegation_token (self-signed, trivial) Service verifies consent_receipt against acme.com JWKS Service Agent access_token (TTL: 3600s) 4. Agent Service POST /calendar/events Authorization: Bearer <access_token> X-Agent-Intent: "Booking standup Monday 9am" X-Agent-Consent: <consent_receipt_jwt> Service logs intent + session to /agent/audit Service Agent 201 Created 5. Access token expires. Agent re-registers with same tokens (no user action needed) unless delegation_token was revoked, in which case flow returns to step 1.

7.1 Mandatory Audit Endpoint

AAP requires all participating services to expose /agent/audit. This is non-negotiable. Agents are only trustworthy if users can inspect what they did.

HTTPGET /agent/audit?delegation_id=del_k9x2mq

[
  {
    "timestamp":  "2026-06-02T10:14:22Z",
    "method":     "POST",
    "path":       "/calendar/events",
    "intent":     "Booking standup Monday 9am",
    "session_id": "sess_p7q3wr",
    "outcome":    "201 Created"
  }
]
§ 8

Revocation

Revocation is a first-class concern, not an afterthought. The protocol is designed so revocation propagates quickly with minimal infrastructure. AAP defines three revocation modes: short TTLs as a structural default, explicit manual revocation, and declarative auto-revoke policies that fire without human intervention.

8.1 Short TTLs as Primary Mechanism

Access tokens MUST expire within the credential_ttl declared by the service (default 3600 seconds). Refresh requires re-presenting the operator JWT, delegation token, and a valid consent receipt. If any of these have been revoked, refresh silently fails and the agent loses access — no push infrastructure required.

8.2 Explicit Revocation

What to RevokeWho Can RevokeMechanismEffect
delegation_token User or Service POST /agent/revoke Agent loses access to this service entirely
consent_receipt User via operator app Operator invalidates receipt Access token refresh fails after TTL
Operator signing key Operator Rotate JWKS on operator domain All tokens signed with old key rejected on next verification
Operator from provider list Model provider Update operator registry T4-requiring services reject operator

8.3 Auto-Revoke Policies

Manual revocation assumes someone remembers to act. In practice, consents accumulate, tasks complete without cleanup, users leave organisations, and nobody audits the connected-agents screen unless something breaks. Auto-revoke policies close the gap between what the user intended — temporary, purposeful access — and what actually happens without them.

Auto-revoke policies are declarative and forward-looking. They are defined at grant time and enforced automatically by the service without requiring any subsequent human action.

Policy Triggers

TriggerFieldDescription
Time-based after_duration Revoke after a fixed duration regardless of activity. Applies from grant time.
Task completion on_task_completion Agent calls POST /agent/task-complete to trigger. Service revokes on receipt.
Inactivity after_inactivity No requests in N days. Catches abandoned sessions and completed-but-unclosed tasks.
Event-based on_events Service-defined lifecycle events: user.offboarded, org.subscription_cancelled, resource.deleted, user.role_changed. Service fires revocation when it emits the event.
Usage budget after_use Revoke after N requests or N writes. User must re-authorize to continue.
The Offboarding Case

The user.offboarded event is particularly critical. Without it, a former employee's delegation tokens remain valid until natural expiry — potentially months. Services MUST fire this event when a user account is deactivated, and it MUST trigger immediate revocation of all associated delegation tokens regardless of their exp value.

8.4 Layered Policy Minimums

Three parties may declare auto-revoke policies: the service, the operator, and the user. Policies are not negotiated — the most restrictive value across all three always wins. This is computed at grant time into an effective_policy stored in the delegation token.

Auto-Revoke Policy — Layered Resolution{
  "auto_revoke_policy": {

    // Service declares minimums — operator and user cannot override upward
    "service_minimum": {
      "max_duration":       "90d",
      "after_inactivity":   "30d",
      "on_events":         ["user.offboarded", "org.subscription_cancelled"]
    },

    // Operator declares defaults for their agents
    "operator_default": {
      "after_inactivity":    "14d",
      "on_task_completion":  true
    },

    // User may tighten further — never loosen
    "user_override": {
      "after_duration":      "7d"
    },

    // Computed at grant time. Stored in token. Authoritative.
    "effective_policy": {
      "expires_at":          "2026-06-09T10:00:00Z",  // min(90d, 7d) = 7d from grant
      "after_inactivity":    "14d",                    // min(30d, 14d)
      "on_task_completion":  true,
      "on_events":          ["user.offboarded", "org.subscription_cancelled"]
    }
  }
}

8.5 Revocation Notifications

Auto-revoke without notification creates silent failures — the agent stops working and nobody knows why. The spec requires a notification chain on every auto-revoke event:

1. Service Operator POST to operator's registered webhook { delegation_id, account_id, reason, triggered_by, timestamp } 2. Operator User Plain language notification "Your agent lost access to Example Service. Reason: 7-day consent window expired." 3. Agent On next 401, detects X-Agent-Revoke-Reason header Reports to user rather than silently retrying

Services MUST include an X-Agent-Revoke-Reason header on 401 responses caused by revocation, distinguishing them from ordinary auth failures. Valid values: policy_expired, inactivity, task_complete, event_triggered, manual_revoke, key_rotation.

§ 13

Security Considerations

Good token design is necessary but not sufficient. Several structural vulnerabilities exist in any bearer-token protocol that AAP must explicitly address.

13.1 Token Binding — The Stolen Token Problem

Every token in AAP is currently a bearer token: whoever holds it can use it. If a delegation token or consent receipt is intercepted — via logging pipeline leakage, compromised cloud storage, or a man-in-the-middle — it can be replayed by the attacker with no way for the service to distinguish the attacker from the legitimate agent.

This matters more for agents than browsers because agents run in cloud infrastructure with shared environments, multiple processes, and verbose logging — all surfaces where tokens can leak in ways a browser session wouldn't.

AAP RECOMMENDS implementing DPoP (Demonstrating Proof of Possession, RFC 9449) for access tokens. The agent generates an ephemeral keypair per session. The public key is bound into the access token at issuance. On every request, the agent includes a signed DPoP proof header. A stolen token without the matching private key is useless.

DPoP Flow1. Agent    generates ephemeral keypair (per session)
2. Agent    Service  includes public key in registration request
3. Service   issues access_token bound to that public key
4. Agent    Service  every request carries DPoP proof header (signed by private key)
5. Service   verifies proof signature — stolen token without key = rejected

Services that require T3 or T4 trust SHOULD require DPoP. Services at T1 or T2 MAY accept plain bearer tokens where DPoP implementation is impractical.

13.2 Agent Impersonation

The spec verifies operator identity to the service — but the user never independently sees this verification. A malicious operator could build an agent that mimics the UI and name of a trusted operator. The service correctly identifies the request as coming from the malicious operator's domain, but the user believes they are using the trusted one. This is phishing at the agent layer.

Mitigations AAP requires:

Operator identity surfaced to users. The operator's verified domain MUST be displayed in the agent's UI at bootstrap and accessible at any time thereafter. Users must be able to see which domain's agent they are using, not just the display name the operator chose for themselves.

Display name ≠ identity. Services MUST NOT accept display names as identity claims. Only the cryptographically verified operator domain is identity. The discovery manifest may include a display name, but relying parties must treat it as decorative.

Phishing-resistant bootstrap. The bootstrap OAuth flow (§5.1) MUST open in the service's own browser context, not an in-app webview controlled by the operator. An operator controlling the webview could intercept credentials. This is the same requirement as OAuth 2.0 best practices (RFC 8252).

13.3 Multi-Tenancy and Session Isolation

Most agent platforms are multi-tenant: one deployment serves thousands of users. The same operator JWT covers all of them. A bug in the platform could cause user A's delegation token to appear in user B's session. For how multi-tenant services handle AAP discovery and endpoint scoping, see §3.1.

AAP requires the following isolation properties:

Session IDs must be cryptographically unguessable and generated fresh per task, not derived from user identifiers or timestamps. UUID v4 minimum; CSPRNG-derived preferred.

Delegation tokens are non-transferable. A token issued for acting_for: john@example.com MUST be rejected if presented in a request where the session context indicates a different user. Services MUST validate that the acting_for claim matches the authenticated session context on every request, not just at registration.

Concurrent session detection. Services SHOULD flag when the same delegation_id is used simultaneously from two different IP addresses or geographic regions. This is a signal of either token theft or a platform isolation failure. The appropriate response is to suspend the delegation pending operator notification rather than silently accept both sessions.

13.4 Protocol Version Negotiation

The spec will evolve. Without version negotiation, a service built on AAP/1.0 cannot safely interact with an agent implementing AAP/2.0 — neither knows what the other expects, and silent incompatibility produces unpredictable behaviour.

The discovery manifest MUST declare supported spec versions from day one:

Discovery Manifest — Version Field{
  "spec_versions_supported": ["aap/1.2", "aap/1.1"],
  "spec_version_preferred":   "aap/1.2"
}

Every agent registration request MUST declare its implemented spec version. If the service does not support the agent's version, it returns a 400 with X-AAP-Version-Required listing its supported versions. Agents MUST NOT proceed with an unsupported version — silent degradation is not permitted.

§ 14

Safety & Trust

Identity verification tells you who is acting. It does not tell you whether what they are about to do is safe, reversible, or within what the user actually meant. This section addresses the gap.

14.1 Irreversible Action Safeguards

A correctly authenticated agent with valid scopes can still take actions the user never intended — because intent declarations are not verified, and some actions cannot be undone. Deleting data, sending communications, making payments, and publishing content are categorically different from read operations: they have real-world consequences that persist beyond any revocation.

AAP defines three safeguards for irreversible operations:

Dry-run mode. Services exposing mutating operations MUST implement a dry-run endpoint that returns what an action would do without committing it. Agents SHOULD call dry-run before any destructive operation and surface the result to the user when the task involves ambiguity.

HTTPPOST /calendar/events?dry_run=true
→ returns { "would_create": {...}, "conflicts": [...] } without committing

Undo window. For destructive operations (delete, send, publish, pay), services SHOULD implement a short reversibility window — a grace period during which the action can be cancelled. The window duration is declared in the scope schema. Agents MUST expose an abort mechanism to the user during this window.

Scope Schema — Undo Window{
  "id":             "mail.send",
  "irreversible":  true,
  "undo_window_s": 30,           // 0 means no undo supported
  "undo_endpoint": "/mail/cancel-send"
}

Pre-action confirmation for high-risk scopes. Certain scope actions MUST require an explicit confirmation signal from the agent before execution, regardless of what the consent receipt granted. Services declare these in the scope schema as "requires_confirmation": true. The agent sends a confirmation token in the request header; without it the service returns 428 Precondition Required.

14.2 Usage Limits

A consent receipt grants what an agent can do. It says nothing about how much. An agent with calendar.write could create one event or ten thousand. A compromised or buggy agent can cause significant damage within its authorized scope with no rate signal in the current protocol.

The consent receipt and service account delegation token SHOULD include a usage_limits block. Services enforce these as hard limits; exceeding them triggers a 429 with X-Agent-Limit-Reason and requires re-consent to continue rather than a silent failure or abuse flag.

Consent Receipt — Usage Limits{
  "intent":        "Schedule team standups for this week",
  "scopes":        ["calendar.write"],
  "usage_limits": {
    "requests_per_hour":  60,
    "writes_per_session": 10,
    "max_data_egress_kb": 500
  }
}

14.3 Cumulative Consent Visibility

A user approves an agent for calendar.read in January, calendar.write in February, contacts.read in March. By April the agent has extensive access, but no single consent review made this visible. The user never saw "this agent has access to your calendar and your contacts" — only three isolated prompts.

The spec requires services to expose a cumulative consent view — a dedicated endpoint showing the agent's total current access, not a log of historical approvals:

HTTPGET /agent/access-summary?delegation_id=del_k9x2mq

{
  "agent":           "acme.com",
  "acting_for":     "john@example.com",
  "active_since":   "2026-01-15",
  "current_scopes": ["calendar.read", "calendar.write", "contacts.read"],
  "effective_policy": { "expires_at": "2026-07-15", "after_inactivity": "14d" },
  "last_active":    "2026-06-02T09:14:00Z",
  "revoke_url":     "/agent/revoke?delegation_id=del_k9x2mq"
}

Operators MUST surface this view in their product UI. The unit of display is total current access — not historical approvals. A one-click revoke from this view MUST be supported.

14.4 Liability Acknowledgement

When an agent causes harm — deletes data, sends an unintended communication, makes an unauthorized purchase — the protocol creates a clear audit trail but does not resolve who bears liability. This gap will not stop developers from building, but it will stop enterprises and regulated industries from deploying at scale.

AAP cannot resolve liability — it is a legal and commercial question beyond the scope of a technical protocol. However, the spec requires that operators surface a liability disclosure to users at bootstrap time, before first agent action:

Bootstrap — Liability Disclosure (required)// Displayed to user before they approve delegation
"If this agent takes an action that causes unintended harm or data loss,
 [Operator Name] is responsible for investigating and remediating the issue.
 You can revoke this agent's access at any time from your connected agents
 dashboard. Actions taken before revocation may not be reversible."

The disclosure content is the operator's responsibility. The requirement that it be displayed — in plain language, before first action, not buried in terms of service — is the protocol's. Making the liability gap visible and attributable is better than ignoring it.

§ 9

Approaches Considered & Rejected

Every design decision is a rejection of alternatives. What follows is an honest accounting of what was evaluated and why each path was not taken.

Hardcoded API Keys

Rejected

The status quo. Developer generates an API key, pastes it into the agent's config. Simple, widely understood, works today.

Fails because: keys are long-lived and broad in scope, tied to developers not users, not revocable per-agent, and provide no audit trail or consent record.

No user identity. No revocation granularity. No consent record.

Standard OAuth 2.0

Partial

OAuth is the right foundation for user delegation. AAP's delegation token is explicitly OAuth-derived. The protocol is not rejected — it's the wrong fit as a complete solution.

Fails as a standalone solution because OAuth assumes a human clicks an authorization screen for every new service. Agents encounter new services autonomously at runtime.

Used as foundation for user delegation layer only.

Model Provider Signing

Rejected

Anthropic (or OpenAI) signs every agent request, similar to how email providers sign with DKIM. Strong guarantees — the model provider vouches for every invocation.

Requires all major providers to build and operate signing infrastructure. Requires agreement on token format. Creates a central dependency. No provider has committed to this. Makes the protocol dead on arrival without industry coordination.

Requires provider participation before protocol can function.

Central Agent Registry

Rejected

A single registry (like npm or a CA) where operators register their agents and receive verified identities. Services check the registry to verify operator legitimacy.

Creates a central point of failure and control. Registry operator becomes a gatekeeper. Doesn't exist yet and bootstrapping one is a governance problem, not a technical one. Adds latency to every verification. History of such registries becoming either captured by incumbents or abandoned.

Governance problem masquerading as a technical one.

auth.md (WorkOS approach)

Partial

Hosts a Markdown file at the service domain describing how agents should authenticate. Three flows: ID-JAG assertion, verified email, anonymous with OTP claim.

Direction is right but: Markdown as machine-readable format is ambiguous; anonymous agent flow has no operator accountability; OTP flows require human presence for every new service; ID-JAG is a new token type requiring provider adoption; revocation is bolted on rather than structural.

Discovery convention adopted. Token format and anonymous flows not adopted.

mTLS Client Certificates

Rejected

Agents present a client TLS certificate during the handshake. Standard PKI handles identity. Well-understood, hardware-backed, very strong guarantees.

Certificate provisioning per-agent is operationally heavy. Most HTTP clients and APIs don't support mTLS easily. Certificate lifecycle management (rotation, revocation via CRL/OCSP) is complex. Over-engineered for most agent use cases. Better fit for machine-to-machine in controlled infrastructure, not open web APIs.

Operationally prohibitive for broad adoption.

Session Cookie Delegation

Rejected

User logs in normally; agent receives the session cookie and uses it to make requests as if it were the user.

Gives agent full account access with no scoping. Cookies are tied to browsers, not agents. No audit trail distinguishes agent actions from user actions. No revocation path that doesn't log the user out entirely. Fundamentally bypasses the consent model.

No scope. No audit. No revocation. Gives agent full account access.

Verifiable Credentials (W3C VC)

Rejected

W3C Verifiable Credentials provide a rich, standardized framework for expressing and verifying claims about any subject — including agents. Cryptographically strong, privacy-preserving, standards-backed.

Ecosystem maturity is low. Tooling is immature. Complexity is high relative to the problem. Most developers don't know it. A better protocol for a more sophisticated future ecosystem — but adopting it now means building on sand. AAP's JWT profile achieves 90% of the benefit with a fraction of the implementation complexity.

Technically superior; practically premature. Revisit in 3–5 years.
§ 10

Comparative Analysis

Criterion API Key OAuth Only auth.md AAP (This Spec)
agt_operator_verified ~
agt_user_delegation ~
agt_consent_receipt
agt_audit_trail ✓ (mandatory)
agt_no_central_authority ~
agt_works_today ~ ~ ✓ (T1–T3)
agt_provider_optional
agt_granular_revocation ~ ~
agt_scope_narrowing ~
agt_human_loop_minimal ✓ (once per service)

✓ fully satisfies · ~ partially satisfies · ✗ does not satisfy

§ 11

Identity Modes

Inspired by Harrison Chase's framing at LangChain Interrupt: agents either act as a specific user or as themselves on behalf of an organisation. Both are legitimate. Both require different trust chains. Both must be declared and disclosed.

AAP defines two first-class identity modes. The mode governs which bootstrap flow is used, what the delegation token looks like, what audit granularity is required, and — critically — what the end user must be told before the agent acts.

Mode A User-Delegated Acts as a specific user

The agent uses the individual user's own credentials. It sees exactly what that user can see — no more. Different users get different answers. Personalized, contextual, bounded.

Trust chain: §4 operator identity + §5 per-user delegation + §6 consent receipt
Mode B Service Account Fixed non-human identity

The agent uses a fixed, non-human identity with credentials defined at setup time. All users interacting with it get consistent responses because the agent always sees the same slice of the world. That slice may be narrow or wide — the defining property is that it is fixed and not tied to any individual user, not that it is broad.

Trust chain: §4 operator identity + scoped delegation + admin consent + elevated audit

11.1 Mode Declaration

Every AAP registration request MUST declare its mode explicitly. There is no default. Omitting mode is a protocol error.

Mode A — User-Delegated{
  "mode":           "user_delegated",
  "acting_for":    "john@example.com",
  "delegation_id": "del_k9x2mq",
  "operator_jwt":  "<signed by acme.com>",
  "consent_receipt":"<task-scoped consent JWT>"
}
Mode B — Service Account{
  "mode":             "service_account",
  "operator":         "acme.com",
  "account_id":       "svc_acme_prod",
  "authorized_by":    "admin@acme.com",
  "org_id":           "org_acme_7x2",
  "granted_scope":    "engineering-team",  // declared at setup — could be narrow or wide
  "operator_jwt":     "<signed by acme.com>",
  "svc_delegation":   "<service-account delegation JWT>"
}

11.2 Service Account Bootstrap

Mode B has no user to bootstrap with. The bootstrap actor is an admin who explicitly reviews and approves the scope being granted — which may be narrow (a single shared inbox) or wide (all documents in an org). The defining requirement is not breadth but explicitness: the admin must see exactly what they are granting before confirming, and that grant is recorded precisely in the delegation token.

─── Service Account Bootstrap (one-time per account) ─── 1. Admin Service standard admin login 2. Service Admin Scope review: "You are granting Acme Corp agent access to: [exact resources listed]. This agent uses fixed credentials, not individual user credentials." [Confirm] 3. Admin confirms, reviews granted_scope explicitly 4. Service Operator svc_delegation_token (signed by service, encodes exact granted_scope) All subsequent agent calls use this token. Scope is fixed to what was approved. Revocation: admin calls /agent/revoke — entire service account loses access.

11.3 Service Account Delegation Token

JWT PAYLOAD — Service Account Delegation{
  "iss":             "api.example.com",     // service-signed
  "sub":             "svc_acme_prod",       // service account id, not a user
  "delegated_to":    "acme.com",
  "authorized_by":   "admin@acme.com",
  "org_id":          "org_acme_7x2",

  // Exact scope granted at bootstrap. Encodes what the admin approved.
  // May be narrow ("engineering-team inbox") or wide ("all-org documents").
  // No default. No implicit expansion. This field is authoritative.
  "granted_scope": {
    "description":  "Engineering team shared inbox",
    "resources":    ["inbox:eng-team@acme.com"],
    "scopes":       ["mail.read", "mail.label"],
    "crosses_users": true        // true if any resource spans >1 user; false otherwise
  },

  "iat":             1748822400,
  "exp":             1780358400
}
Key Design Point

The granted_scope object replaces the earlier data_boundary: "org_only" field, which incorrectly implied that service accounts are inherently org-wide. Scope breadth is a configuration decision made at bootstrap, not a property of the mode itself. A service account for a single shared inbox is just as valid as one for an entire org. The crosses_users flag exists only to trigger the appropriate audit rules — it is not a measure of risk level.

11.4 Elevated Audit Requirements for Mode B

The audit requirement for Mode B tracks what the agent actually touched within its declared scope — regardless of how narrow or wide that scope is. When crosses_users: true in the delegation token, services MUST additionally log data_subjects on every operation, so it is always possible to determine whose data was accessed even when the agent isn't acting for a named user.

Mode B Audit Entry (crosses_users: true){
  "timestamp":      "2026-06-02T10:14:22Z",
  "mode":           "service_account",
  "account_id":     "svc_acme_prod",
  "method":         "POST",
  "path":           "/messages/label",
  "intent_type":    "LABEL_MESSAGE",
  "data_subjects":  ["user_a", "user_b"],  // required when crosses_users: true
  "outcome":        "200 OK"
}

Mode B Audit Entry (crosses_users: false — single resource){
  "timestamp":      "2026-06-02T10:14:22Z",
  "mode":           "service_account",
  "account_id":     "svc_acme_bot",
  "method":         "GET",
  "path":           "/documents/shared-roadmap",
  "intent_type":    "READ_DOCUMENT",
  // data_subjects omitted — single shared resource, no per-user data touched
  "outcome":        "200 OK"
}

11.5 Mandatory User Disclosure

Harrison Chase's key practical point: users must know which mode they're dealing with, because their expectations around privacy and data access are completely different. AAP makes this mandatory.

The service discovery manifest MUST declare which modes it supports and MUST include a human-readable disclosure string for each. Operators MUST surface the relevant disclosure to end users before first interaction — not in terms of service, not on a settings page, but in the agent's UI at the point of first use.

Discovery Manifest — Mode Disclosures{
  "identity_modes_supported": ["user_delegated", "service_account"],
  "disclosures": {
    "user_delegated":
      "This agent uses your personal credentials. It can only see data you have access to. Different users will receive different responses.",
    "service_account":
      "This agent uses fixed credentials authorised by your admin. It does not act as you personally. Its access is limited to: {granted_scope.description}."
      // {granted_scope.description} is populated from the delegation token at disclosure time.
      // e.g. "Engineering team shared inbox" or "All documents in your organisation"
      // Operators must not substitute a generic string — it must reflect actual granted scope.
  }
}

11.6 Mixed-Mode Sessions

A single agent task may legitimately invoke both modes — for example, reading shared org documents via service account and sending an email via user-delegated credentials. This is expected and supported, but each action must carry its mode explicitly.

The per-request headers are extended to carry mode context:

HTTP REQUEST — Mixed Mode// Service account call
GET /org/documents/q3-report
Authorization:       Bearer <svc_access_token>
X-Agent-Mode:        service_account
X-Agent-Account:     svc_acme_prod
X-Agent-Intent-Type: READ_DOCUMENT
X-Agent-Session:     sess_p7q3wr

// User-delegated call in same session
POST /mail/send
Authorization:       Bearer <user_access_token>
X-Agent-Mode:        user_delegated
X-Agent-Delegation:  del_k9x2mq
X-Agent-Intent-Type: SEND_MESSAGE
X-Agent-Session:     sess_p7q3wr

The session ID ties both calls to the same task, while the mode header ensures each is audited under the correct rules. Services must not infer mode from context — it must be declared per request.

11.7 Mode Comparison

Property Mode A — User-Delegated Mode B — Service Account
Bootstrap actorIndividual userAdmin or operator
Data visibilityWhat that user can seeWhatever scope was granted at setup — may be narrow or wide
Response consistencyVaries per userSame for all callers
Consent granularityPer-user, per-taskFixed at setup; explicit scope review by admin
Privacy riskBounded to one userDepends on granted scope; not inherently higher than Mode A
Revocation actorUser or serviceAdmin only
Audit requirementAction + intentAction + intent + data_subjects (when crosses_users: true)
Intent formatFree text (user-visible)Structured type (service-logged)
Use case fitPersonal assistants, user-specific tasksCompany bots, shared resource automation, background jobs
Coexistence

Both modes will coexist within the same products. This is expected and healthy. The same agent platform might use Mode B to read shared company documents and Mode A to send emails on a specific user's behalf — in the same session. The spec makes this explicit so developers design for it intentionally rather than discovering it as an edge case.

§ 12

Resolved Questions

Questions raised in v1.0 as open. Each is now resolved with a defined position. Rationale is included so the reasoning is preserved, not just the decision.

12.1 Cross-Operator Delegation (Agent-to-Agent)

Resolution

Cross-operator delegation is prohibited in v1.1. It will be introduced in a future version only after a clear accountability model is established.

When Agent A delegates to Agent B — particularly when they belong to different operators — accountability diffuses. The user authorized A, not B. Under current legal frameworks, liability would chase the chain back to A's operator, but this becomes untenable as chains lengthen and cross organizational boundaries.

The temptation to support this early is real: multi-agent workflows are genuinely useful. But getting the accountability model wrong and trying to fix it later is harder than deferring. When cross-operator delegation is eventually specified, the consent receipt will be required to explicitly name every agent in the chain at consent time. Dynamic agent discovery that adds agents mid-task without user awareness will require fresh consent. Ambient re-delegation is never permitted.

Same-operator delegation (Agent A spawning Agent B within the same operator) is permitted under the existing consent receipt model, provided the session ID links all actions to the same user-approved task.

12.2 Offline Agents

Resolution

Consent is a window, not a moment. The user sets the window explicitly. Background jobs running within the window are permitted. Long-running jobs must implement a heartbeat. Mid-execution revocation must trigger a clean abort.

The consent receipt's exp field is interpreted as an execution window, not merely a token expiry. When the user approves a task, the operator's UI must surface the expected duration: "this will run tonight" implies a longer window than "do this now." The user sets the window; the operator records it in the receipt.

For background jobs expected to run longer than 30 minutes, the agent MUST implement a heartbeat — a periodic signal to the user that the task is still running and still within declared scope. The operator's platform handles delivery. The user must be able to abort from the heartbeat notification without being present at a computer.

If the user revokes the consent receipt while the agent is mid-execution, the agent MUST call /agent/cancel to initiate a clean abort. Services exposing mutating APIs are REQUIRED to implement this endpoint. Partial state should be rolled back where the service supports transactions; where it does not, the audit log must record the partial execution clearly.

Consent Receipt — Extended for Offline{
  "intent":          "Process overnight batch report",
  "execution_window": {
    "earliest":  "2026-06-02T22:00:00Z",
    "latest":    "2026-06-03T06:00:00Z"
  },
  "heartbeat_interval": 1800,         // seconds between status pings
  "abort_on_revoke":    true           // always true; field is informational
}

12.3 Competing Scope Definitions

Resolution

Service scope definitions are authoritative. Operators may constrain scopes further on their side but may not redefine them. Services are required to publish explicit action enumerations, not just human-readable descriptions.

This follows the same model as OAuth: the authorization server defines scope semantics; clients request them. Operators who integrate with a service agree to those definitions. The spec additionally requires services to publish machine-readable scope schemas, eliminating the ambiguity that causes most real-world disputes:

Scope Schema (in discovery manifest){
  "id":                  "calendar.write",
  "description":        "Create and update calendar events",
  "allows":             ["events.create", "events.update"],
  "explicitly_excludes": ["events.delete", "calendar.delete"]
}

Any action not listed in allows is implicitly excluded. Any action in explicitly_excludes is a protocol violation regardless of what the operator's consent receipt declares.

12.4 Privacy of Intent Headers

Resolution

Dual-layer intent model. Services receive a structured intent type (machine-logged, no sensitive content). Users see a free-text description (operator-held, never sent to the service).

The tension is real: free-text intent enables useful audit logs but leaks sensitive context to services. "Booking a meeting with my therapist" or "paying overdue rent" reveals information the service has no legitimate need to know.

The resolution separates the two audiences. The service receives only a structured type from a controlled vocabulary — enough to detect anomalous agent behaviour, not enough to infer personal context. The user-facing audit log displays the full free-text intent string, but this is fetched from the operator's own audit store, not from the service.

FieldValueSent ToVisible To User
X-Agent-Intent-TypeSCHEDULE_EVENTService (logged)No
operator audit store"Booking with my therapist next Tuesday"Never leaves operatorYes, via operator UI

The controlled intent type vocabulary is defined per-scope in the discovery manifest. Services MAY reject requests with unrecognized intent types, providing a lightweight signal that an agent is operating outside expected patterns.

12.5 Standards Body Home

Resolution

Start outside a formal body; move in once the core design is proven. Cross-operator delegation, when specified, should go through a formal process due to its liability implications.

Standards bodies produce more rigorous, more interoperable, more durable specifications. They also move slowly and can water down core designs through forced consensus. OAuth 2.0 took years and still required a separate security BCP to be safely implementable.

The pragmatic path: ship as an open community spec, build real implementations, prove the design, then bring it to IETF OAuth WG or OpenID Foundation. This is how many durable web standards actually emerged — practitioners first, formalization second.

The exception is cross-operator delegation. Because it involves liability and accountability questions that transcend engineering, that chapter should go through a formal body from the start rather than arriving as a community proposal for ratification after the fact.


Implementation Reference §15 – §23 · Normative requirements for builders
§ 15

Conformance Levels

Three tiers define what an implementation must support to claim AAP compliance. Each tier is independently testable. Higher tiers are strict supersets.

Core Tier C Minimum viable

DNS-anchored operator identity (§4). User-delegated bootstrap and delegation token (§5). Consent receipt with scopes (§6). /agent/register, /agent/revoke, /agent/audit endpoints. Standard error envelope (§16.1). Version negotiation header. T1–T2 trust tiers.

Required to call an implementation "AAP-compliant"
Extended Tier E Production-grade

Everything in Core, plus: DPoP token binding (§13.1). Auto-revoke policies (§8.3–8.5). Service Account mode (§11). Dry-run mode and undo window (§14.1). Usage limits enforcement (§14.2). Cumulative access-summary endpoint (§14.3). T3 trust tier.

Required for production deployments handling user data
Full Tier F High-assurance

Everything in Extended, plus: T4 provider registry cross-reference. Liability disclosure at bootstrap (§14.4). Webhook-based auto-revoke event delivery (§17.5). Mixed-mode session audit correlation (§18.3). Pre-action confirmation for high-risk scopes (§14.1).

Required for financial, medical, or regulated deployments

Services declare their conformance tier in the discovery manifest:

JSON"conformance": {
  "tier":    "extended",   // "core" | "extended" | "full"
  "spec":    "aap/2.0",
  "tested":  "2026-06-01"    // date of last conformance test run
}
§ 16

Error Taxonomy

Every error across every endpoint uses the same envelope. Machine-readable codes let agents handle failures programmatically rather than parsing human text.

16.1 Standard Error Envelope

JSON — Error Response{
  "error":          "delegation_expired",     // machine-readable code (see §16.2)
  "error_description":"Delegation token del_k9x2mq expired 2026-05-01",
  "hint":            "Re-bootstrap with the user at /agent/delegate",
  "request_id":     "req_8x2kp9",              // for support/correlation
  "docs_url":        "https://aap.dev/errors/delegation_expired"
}

The hint field is OPTIONAL but RECOMMENDED — it tells the agent what to do next, not just what went wrong. The docs_url is OPTIONAL.

16.2 Error Code Catalogue

Error CodeHTTP StatusMeaningAgent Action
operator_jwt_invalid401Operator JWT signature failed verificationCheck operator signing key; re-sign
operator_jwt_expired401Operator JWT exp claim is in the pastIssue new operator JWT
operator_not_found401operator domain has no agent-identity.jsonOperator must publish identity manifest
operator_suspended403Operator appears in a provider revocation listContact model provider; do not retry
delegation_not_found401delegation_id does not exist at this serviceRe-bootstrap with user
delegation_expired401Delegation token natural expiry reachedRe-bootstrap with user
delegation_revoked401Delegation explicitly revoked (by user or admin)Inform user; do not retry silently
delegation_mismatch401acting_for in request does not match delegation subCheck token handling; likely a bug
consent_expired401Consent receipt exp reachedRequest fresh consent from user
consent_scope_exceeded403Requested action not in consent receipt scopesRequest expanded consent or abort task
consent_service_mismatch403Consent receipt aud does not match this serviceObtain consent receipt for this service
scope_not_granted403Requested scope not in delegation tokenRequest scope expansion from user/admin
dpop_missing401DPoP proof header absent where requiredAttach DPoP proof; see §17.1
dpop_invalid401DPoP proof signature or claims invalidRegenerate DPoP proof
dpop_replayed401DPoP jti already seen (replay detected)Generate new DPoP proof with fresh jti
mode_not_supported400Service does not support declared identity modeCheck service discovery manifest
mode_missing400mode field absent from registration requestDeclare mode explicitly; no default exists
boundary_violation403Mode B request accessed resource outside granted_scopeCheck scope; contact admin if scope needs expanding
usage_limit_reached429requests_per_hour or max_writes budget exhaustedWait for window reset or request re-consent
auto_revoked401Delegation revoked by auto-revoke policyCheck revoke reason; inform user
spec_version_unsupported400Client AAP version not accepted by this serviceCheck Aap-Version-Accepted header; upgrade or downgrade
dry_run_unsupported400Service does not support dry-run modeProceed without dry-run or abort
irreversible_requires_confirm403Operation requires X-Agent-Confirm headerAdd X-Agent-Confirm: true after user confirmation
Distinguishing 401 vs 403

401 means the identity or token is invalid or absent — the agent cannot be who it claims to be. 403 means identity is verified but the action is not permitted under the granted scope or policy. Agents must not treat these interchangeably.

§ 17

Endpoint Contracts

Full request and response specifications for every AAP endpoint. Services MUST implement all Core endpoints. Extended and Full endpoints are marked accordingly.

17.1 POST /agent/register

Exchange operator credentials, delegation token, and consent receipt for a short-lived access token. This is the primary entry point for every agent session.

RequestPOST /agent/register
Content-Type:  application/json
DPoP:          <dpop_proof_jwt>          // Required for Tier E+
Aap-Version:   2.0

{
  "mode":            "user_delegated",       // REQUIRED — no default
  "operator_jwt":    "<jwt>",               // REQUIRED
  "delegation_token":"<jwt>",               // REQUIRED
  "consent_receipt": "<jwt>"                // REQUIRED for T3+; OPTIONAL for T1–T2
}
Response — 200 OK{
  "access_token":  "<opaque token>",
  "token_type":    "DPoP",               // "DPoP" for Tier E+; "Bearer" for Tier C
  "expires_in":    3600,
  "session_id":    "sess_p7q3wr",
  "effective_policy": {            // resolved auto-revoke policy for this delegation
    "expires_at":         "2026-09-01T00:00:00Z",
    "inactivity_timeout": 1209600,  // seconds
    "on_task_completion": true
  }
}

Idempotency: Calling /agent/register again with the same delegation_token and consent_receipt within the access token's validity window MUST return a new access token (not reuse the existing one) but MUST NOT create a duplicate session entry in the audit log. The session_id is stable for the lifetime of the consent receipt.

17.2 POST /agent/delegate (Bootstrap)

Called during the human-in-the-loop bootstrap. The user authenticates normally and this endpoint issues the delegation token. This endpoint is called by the service's own UI, not by the agent directly.

Response — 201 Created{
  "delegation_token": "<jwt signed by this service>",
  "delegation_id":    "del_k9x2mq",
  "liability_disclosure": "<plain text — shown to user before token is issued>"
}

17.3 POST /agent/revoke

Request{
  "delegation_id": "del_k9x2mq",   // REQUIRED
  "reason":        "user_requested"   // OPTIONAL — logged in audit
  // "user_requested" | "admin_requested" | "task_complete" | "policy_triggered"
}

Response — 200 OK{
  "revoked_at":    "2026-06-02T12:00:00Z",
  "delegation_id": "del_k9x2mq"
}

Idempotency: Revoking an already-revoked delegation MUST return 200 (not 404 or 409). The operation is idempotent.

17.4 GET /agent/audit

RequestGET /agent/audit
  ?delegation_id=del_k9x2mq   // REQUIRED
  &from=2026-06-01T00:00:00Z   // OPTIONAL — ISO 8601
  &to=2026-06-02T00:00:00Z     // OPTIONAL
  &limit=50                    // OPTIONAL — default 50, max 200
  &cursor=opaque_cursor_val    // OPTIONAL — for pagination

Response — 200 OK{
  "entries": [ /* audit entry objects */ ],
  "next_cursor": "opaque_cursor_val",  // null if no more results
  "total_count": 142
}

Callers: the user (via delegation_id), the operator (via operator JWT), or an admin (for Mode B). The service MUST verify the caller is authorized for the delegation_id being queried before returning entries.

17.5 GET /agent/access-summary (Tier E+)

Returns the full picture of an agent's current access — all active delegations, their scopes, and effective auto-revoke policies. This is what the "connected agents" UI is built on.

Response — 200 OK{
  "delegations": [
    {
      "delegation_id":   "del_k9x2mq",
      "operator":        "acme.com",
      "mode":            "user_delegated",
      "scopes":          ["calendar.read", "calendar.write"],
      "granted_at":      "2026-03-01T10:00:00Z",
      "last_used":       "2026-06-01T14:22:00Z",
      "effective_policy": { /* ... */ }
    }
  ]
}

17.6 POST /agent/task-complete (Tier E+)

Agent signals task completion. Triggers on_task_completion auto-revoke if set in effective policy. Idempotent.

Request{
  "session_id":    "sess_p7q3wr",
  "summary":      "Scheduled 3 meetings, sent 1 invite"  // OPTIONAL, shown in audit
}

17.7 POST /agent/cancel (Tier E+)

Initiates clean abort of an in-progress session. Services MUST attempt rollback where the underlying resource supports transactions. Audit log MUST record partial execution state.

Request{
  "session_id":    "sess_p7q3wr",
  "reason":       "user_revoked"
}

Response — 200 OK{
  "cancelled_at":   "2026-06-02T11:45:00Z",
  "rollback_status": "completed"   // "completed" | "partial" | "not_supported"
}

17.8 Webhook — Auto-Revoke Events (Tier F)

Services deliver auto-revoke notifications to operators via webhook. Operators declare their webhook URL in the operator identity manifest. Services MUST retry with exponential backoff on failure. Operators MUST respond 200 within 5 seconds.

Webhook Payload — POST to operator webhook_url{
  "event":          "delegation.auto_revoked",
  "delegation_id":  "del_k9x2mq",
  "trigger":        "user.offboarded",
  "revoked_at":     "2026-06-02T11:45:00Z",
  "service":        "api.example.com",
  "signature":      "<HMAC-SHA256 of payload body, key = shared webhook secret>"
}

For Tier C and E, polling /agent/audit filtered by event_type=auto_revoked is the fallback mechanism.

§ 18

DPoP Profile for AAP

A precise profile of RFC 9449 for the AAP context. Implementers must follow both RFC 9449 and the additional constraints here.

18.1 Keypair Ownership

The DPoP keypair belongs to the operator's agent instance — specifically the process or container handling a given session. It is generated fresh per session (not per request) and MUST NOT be shared across sessions or users. The public key appears in the DPoP proof JWT header as a JWK.

18.2 Required Endpoints

DPoP is required on: /agent/register, /agent/revoke, and all resource API calls made with the resulting access token. It is NOT required on: /agent/audit, /agent/access-summary (read-only, user-callable endpoints).

18.3 The ath Claim

The ath claim in each DPoP proof MUST be the base64url-encoded SHA-256 hash of the ASCII representation of the access token. This binds the DPoP proof to the specific access token being used.

DPoP Proof JWT Header + Payload// Header
{ "typ": "dpop+jwt", "alg": "ES256", "jwk": { /* ephemeral public key */ } }

// Payload
{
  "jti":  "<unique per request — UUID v4>",  // prevents replay
  "htm":  "POST",                           // HTTP method
  "htu":  "https://api.example.com/agent/register",
  "iat":  1748822400,
  "ath":  "<base64url(SHA-256(access_token))>"   // omit on /agent/register (no token yet)
}

18.4 Challenge Response

When DPoP is required but absent or invalid, services MUST return:

HTTP 401WWW-Authenticate: DPoP error="use_dpop_nonce", error_description="DPoP proof required",
              algs="ES256 PS256"
DPoP-Nonce: <server-generated nonce — include in next DPoP proof as nonce claim>

Services MAY issue nonces to prevent pre-computation. If a nonce is issued, the agent MUST include it in the DPoP proof nonce claim on retry.

§ 19

Normative JSON Schemas

These schemas are normative. Implementations MUST validate incoming documents against them. Examples elsewhere in the spec are instances of these schemas, not definitions.

19.1 Service Discovery Manifest

JSON Schema{
  "$schema":     "https://json-schema.org/draft/2020-12/schema",
  "$id":         "https://aap.dev/schemas/v2/service-manifest.json",
  "type":        "object",
  "required":    ["spec", "service", "minimum_tier", "endpoints", "conformance"],
  "properties": {
    "spec":         { "type": "string", "pattern": "^aap/[0-9]+\\.[0-9]+$" },
    "service":      { "type": "string", "format": "uri" },
    "display_name": { "type": "string", "maxLength": 80 },
    "minimum_tier": { "type": "integer", "minimum": 1, "maximum": 4 },
    "intent_required":{ "type": "boolean", "default": true },
    "credential_ttl": { "type": "integer", "minimum": 300, "maximum": 86400 },
    "scope_expansion":{ "enum": ["reject", "notify", "silent"], "default": "notify" },
    "identity_modes_supported": {
      "type": "array",
      "items": { "enum": ["user_delegated", "service_account"] },
      "minItems": 1
    },
    "scopes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "description", "allows"],
        "properties": {
          "id":                  { "type": "string", "pattern": "^[a-z][a-z0-9_]*\\.[a-z][a-z0-9_]*$" },
          "description":        { "type": "string", "maxLength": 200 },
          "allows":             { "type": "array", "items": { "type": "string" }, "minItems": 1 },
          "explicitly_excludes": { "type": "array", "items": { "type": "string" } }
        }
      }
    },
    "endpoints": {
      "type": "object",
      "required": ["register", "delegate", "revoke", "audit"],
      "additionalProperties": { "type": "string", "format": "uri-reference" }
    },
    "conformance": {
      "type": "object",
      "required": ["tier", "spec"],
      "properties": {
        "tier": { "enum": ["core", "extended", "full"] },
        "spec": { "type": "string" }
      }
    }
  },
  "additionalProperties": false
}

19.2 Operator Identity Manifest

JSON Schema{
  "$id":      "https://aap.dev/schemas/v2/operator-identity.json",
  "type":     "object",
  "required": ["operator", "domain", "signing_keys", "contact"],
  "properties": {
    "operator":     { "type": "string", "maxLength": 120 },
    "domain":      { "type": "string", "format": "hostname" },
    "contact":     { "type": "string", "format": "email" },
    "signing_keys":{ "type": "string", "format": "uri" },  // JWKS endpoint
    "webhook_url": { "type": "string", "format": "uri" },  // Required for Tier F
    "since":       { "type": "string", "format": "date" },
    "model_providers":{ "type": "array", "items": { "type": "string", "format": "hostname" } }
  }
}

19.3 Consent Receipt JWT Claims

JSON Schema — JWT Payload{
  "$id":      "https://aap.dev/schemas/v2/consent-receipt.json",
  "type":     "object",
  "required": ["iss", "aud", "sub", "delegation_id", "intent", "scopes", "consent_method", "session_id", "iat", "exp"],
  "properties": {
    "iss":           { "type": "string", "format": "hostname" },  // operator domain
    "aud":           { "type": "string", "format": "uri" },       // target service — REQUIRED, binds receipt to one service
    "sub":           { "type": "string" },                  // user identifier
    "delegation_id": { "type": "string" },
    "session_id":    { "type": "string" },
    "intent":        { "type": "string", "maxLength": 500 },  // operator-held; never sent to service
    "intent_type":   { "type": "string" },                  // structured type — sent to service
    "scopes":        { "type": "array", "items": { "type": "string" }, "minItems": 1 },
    "consent_method":{ "enum": ["explicit_ui", "admin_bootstrap"] },
    "usage_limits":  {
      "type": "object",
      "properties": {
        "requests_per_hour": { "type": "integer", "minimum": 1 },
        "writes_per_session":  { "type": "integer", "minimum": 1 },
        "max_data_egress_kb":  { "type": "integer", "minimum": 1 }
      }
    },
    "execution_window":{
      "type": "object",
      "required": ["earliest", "latest"],
      "properties": {
        "earliest": { "type": "string", "format": "date-time" },
        "latest":   { "type": "string", "format": "date-time" }
      }
    },
    "iat": { "type": "integer" },
    "exp": { "type": "integer" }
  }
}
aud binding

The aud claim MUST be the service's base URI as declared in its discovery manifest. A consent receipt with aud: "https://api.example.com" MUST be rejected by any other service. This prevents a stolen receipt from being replayed at a different service.

§ 20

JWKS Rotation Rules

20.1 Key ID Convention

Every key in a JWKS MUST carry a kid (Key ID) claim. JWTs MUST include the kid of the signing key in the JWT header. Services MUST use the kid to look up the matching key in the JWKS rather than trying all keys. If no key matches the kid, the service MUST re-fetch the JWKS once before rejecting the token — this handles the propagation delay after a key rotation.

20.2 Rotation Overlap Period

When rotating keys, operators MUST publish both the old and new key in the JWKS simultaneously for a minimum overlap period of 2× the service's JWKS cache TTL (default: 2 hours). This ensures tokens signed with the old key remain verifiable during the cache window. After the overlap period, the old key MAY be removed.

JWKS During Rotation{
  "keys": [
    { "kid": "key-2025-03", "use": "sig", /* retiring — keep for overlap period */ },
    { "kid": "key-2026-06", "use": "sig", /* current signing key */ }
  ]
}

20.3 Unreachable JWKS Endpoint

If a JWKS endpoint is unreachable during verification, services MUST serve from cache (if within TTL) and MUST NOT fail open. If the cache is expired and the JWKS is unreachable, the verification MUST fail with operator_not_found. Services SHOULD alert on repeated JWKS fetch failures — this may indicate an operator going dark or a network issue requiring investigation.

20.4 Minimum Key Requirements

JWKS keys MUST use one of: RS256, RS384, RS512, ES256, ES384, PS256. Symmetric algorithms (HS256 etc.) are not permitted — they cannot be published in a JWKS for asymmetric verification. ES256 is RECOMMENDED for performance.

§ 21

Test Vectors

Known-good inputs and expected outputs for implementers to verify their JWT handling, signature verification, and DPoP proof generation. These vectors are normative for conformance testing.

Key Material

All keys below are test-only and MUST NOT be used in production. The private key material is published here solely to enable implementers to reproduce these vectors. A production JWKS endpoint must never expose private keys.

21.1 Operator Test Key Pair (ES256)

Test Private Key — JWK{
  "kty": "EC", "crv": "P-256", "kid": "aap-test-op-1", "use": "sig",
  "d":   "TEST_ONLY_9vApwBBB3iCMbDO0bRqFV7l4sLvBjPe8Z7k2Xl9m",
  "x":   "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
  "y":   "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
}

21.2 Valid Operator JWT — Expected to Pass

Input Claims{
  "iss": "test-operator.aap.dev",
  "aud": "https://test-service.aap.dev",
  "iat": 1748822400,
  "exp": 1748826000,
  "kid": "aap-test-op-1"
}
// Signed with test private key above using ES256
// Expected verification result: PASS
// Expected kid lookup: matches "aap-test-op-1" in test JWKS

21.3 Failure Vectors

VectorModificationExpected Error
TV-F-01exp set to 1748822399 (1 second before iat)operator_jwt_expired
TV-F-02Signature corrupted (last byte flipped)operator_jwt_invalid
TV-F-03kid changed to "nonexistent-key"operator_not_found (after JWKS re-fetch)
TV-F-04iss domain has no agent-identity.jsonoperator_not_found
TV-F-05aud does not match receiving service URIoperator_jwt_invalid
TV-F-06DPoP jti reused within 5-minute windowdpop_replayed
TV-F-07Consent receipt aud is different serviceconsent_service_mismatch
TV-F-08mode field absent from register requestmode_missing

19.4 Delegation Token JWT Claims

JSON Schema — JWT Payload{
  "$id":      "https://aap.dev/schemas/v2/delegation-token.json",
  "type":     "object",
  "required": ["iss", "sub", "delegated_to", "delegation_id", "scopes", "iat", "exp", "max_agent_ttl"],
  "properties": {
    "iss":           { "type": "string", "format": "uri" },          // service base URI — self-signed
    "sub":           { "type": "string" },                      // user identifier
    "delegated_to":  { "type": "string", "format": "hostname" },  // operator domain
    "delegation_id": { "type": "string", "pattern": "^del_[a-z0-9]{6,32}$" },
    "scopes":        { "type": "array", "items": { "type": "string" }, "minItems": 1 },
    "max_agent_ttl": { "type": "integer", "minimum": 300, "maximum": 86400 },
    "iat":           { "type": "integer" },
    "exp":           { "type": "integer" }
  },
  "additionalProperties": false
}

19.5 Service Account Delegation Token JWT Claims

JSON Schema — JWT Payload{
  "$id":      "https://aap.dev/schemas/v2/svc-delegation-token.json",
  "type":     "object",
  "required": ["iss", "sub", "delegated_to", "authorized_by", "org_id", "granted_scope", "iat", "exp"],
  "properties": {
    "iss":           { "type": "string", "format": "uri" },
    "sub":           { "type": "string", "pattern": "^svc_[a-z0-9_]{3,64}$" },  // service account id
    "delegated_to":  { "type": "string", "format": "hostname" },
    "authorized_by": { "type": "string", "format": "email" },
    "org_id":        { "type": "string" },
    "granted_scope": {
      "type": "object",
      "required": ["description", "scopes", "crosses_users"],
      "properties": {
        "description":  { "type": "string", "maxLength": 200 },
        "resources":    { "type": "array", "items": { "type": "string" } },
        "scopes":       { "type": "array", "items": { "type": "string" }, "minItems": 1 },
        "crosses_users": { "type": "boolean" }
      },
      "additionalProperties": false
    },
    "iat": { "type": "integer" },
    "exp": { "type": "integer" }
  },
  "additionalProperties": false
}

19.6 Auto-Revoke Policy

JSON Schema — effective_policy object{
  "$id":   "https://aap.dev/schemas/v2/auto-revoke-policy.json",
  "type":  "object",
  "properties": {
    "expires_at":         { "type": "string", "format": "date-time" },
    "inactivity_timeout": { "type": "integer", "minimum": 3600, /* seconds */ "description": "seconds" },
    "on_task_completion": { "type": "boolean" },
    "on_events":          {
      "type": "array",
      "items": { "enum": [
        "user.offboarded", "org.subscription_cancelled",
        "resource.deleted", "user.role_changed"
      ] }
    },
    "after_use":          {
      "type": "object",
      "properties": {
        "max_requests": { "type": "integer", "minimum": 1 },
        "max_writes":   { "type": "integer", "minimum": 1 }
      }
    }
  }
}
§ 21

Mixed-Mode Session Contract

A single agent task may invoke both identity modes within one session. This is expected and supported. The contract governing how modes interact must be precise.

21.1 Upfront Mode Declaration

Agents MUST declare all modes they intend to use at session start by calling /agent/register once per mode, both using the same session_id. A session that attempts to use a mode not registered at start MUST be rejected with mode_not_supported.

Session Start — Register Both Modes// Call 1 — register user_delegated for this session
POST /agent/register
{ "mode": "user_delegated", "session_id": "sess_p7q3wr", /* ... */ }
→ returns user_access_token

// Call 2 — register service_account for same session
POST /agent/register
{ "mode": "service_account", "session_id": "sess_p7q3wr", /* ... */ }
→ returns svc_access_token

// Both tokens are now valid for session sess_p7q3wr
// Each carries X-Agent-Mode on every subsequent request

21.2 Partial Revocation Behaviour

When one mode's credentials are revoked within a mixed-mode session, the session does not terminate entirely. The revoked mode becomes unavailable and the agent MUST NOT retry it. The other mode continues operating normally. The agent MUST surface to the user that part of its capability has been lost.

Revocation EventEffect on SessionAgent Required Action
user_delegated delegation revokedMode A calls return 401 delegation_revokedInform user; continue Mode B if applicable
service_account delegation revokedMode B calls return 401 delegation_revokedInform admin; continue Mode A if applicable
Both revokedAll calls failAbort session; notify user and admin
Consent receipt expired (Mode A)Mode A calls return 401 consent_expiredRequest fresh consent; session can continue with Mode B

21.3 Cross-Mode Audit Correlation

Both modes use the same session_id. The audit endpoint MUST be queryable by session_id to return a unified chronological log of all actions taken under that session, clearly labelled with their mode. This allows a user or admin to reconstruct exactly what happened during a mixed-mode task.

Unified Session Audit Entry{
  "session_id":   "sess_p7q3wr",
  "timestamp":   "2026-06-02T10:14:22Z",
  "mode":        "service_account",      // always present — never inferred
  "method":      "GET",
  "path":        "/documents/q3-report",
  "intent_type": "READ_DOCUMENT",
  "outcome":     "200 OK"
}
§ 22

Protocol Version Negotiation

AAP versions are additive. Agents and services negotiate a compatible version on every request. Neither side should fail silently on a version mismatch.

22.1 Version Headers

Agents MUST include Aap-Version on every request. Services MUST respond with Aap-Version-Served confirming the version they applied. Services MAY include Aap-Version-Accepted listing all versions they support.

Request HeaderAap-Version: 2.0

Response HeadersAap-Version-Served:   2.0
Aap-Version-Accepted: 1.0, 1.1, 1.2, 1.3, 2.0

22.2 Negotiation Rules

If a service receives a request with a version it does not support, it MUST return 400 spec_version_unsupported with the Aap-Version-Accepted header. It MUST NOT attempt to process the request under a different version silently.

If a service supports both the requested version and a newer one, it MUST serve the requested version — downgrade is always the service's responsibility, never assumed. Agents that receive a Aap-Version-Served higher than requested MUST treat it as a protocol error and retry at a mutually supported version.

22.3 Discovery Manifest Versioning

The service discovery manifest MUST declare spec_versions_accepted as an array. This allows agents to select a compatible version before making their first registration request, avoiding a round-trip failure.

Discovery Manifest — Version Field"spec_versions_accepted": ["1.3", "2.0"]

22.4 Forward Compatibility Guarantee

Minor versions (2.0 → 2.1) are guaranteed to be additive — new optional fields only. Implementations MUST ignore unknown fields rather than rejecting them. Major versions (2.x → 3.0) may introduce breaking changes and require explicit negotiation.

§ 23

Test Vectors

Known-good inputs and expected outputs for implementers to verify their JWT handling, signature verification, and DPoP proof generation. These vectors are normative for conformance testing.

Key Material

All keys below are test-only and MUST NOT be used in production. The private key material is published here solely to enable implementers to reproduce these vectors. A production JWKS endpoint must never expose private keys.

23.1 Operator Test Key Pair (ES256)

Test Private Key — JWK{
  "kty": "EC", "crv": "P-256", "kid": "aap-test-op-1", "use": "sig",
  "d":   "TEST_ONLY_9vApwBBB3iCMbDO0bRqFV7l4sLvBjPe8Z7k2Xl9m",
  "x":   "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
  "y":   "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
}

23.2 Valid Operator JWT — Expected to Pass

Input Claims{
  "iss": "test-operator.aap.dev",
  "aud": "https://test-service.aap.dev",
  "iat": 1748822400,
  "exp": 1748826000,
  "kid": "aap-test-op-1"
}
// Signed with test private key above using ES256
// Expected verification result: PASS
// Expected kid lookup: matches "aap-test-op-1" in test JWKS

23.3 Valid Consent Receipt — Expected to Pass

Input Claims{
  "iss":            "test-operator.aap.dev",
  "aud":            "https://test-service.aap.dev",
  "sub":            "user_test_001",
  "delegation_id":  "del_testk9x2",
  "session_id":     "sess_testabc",
  "intent":         "Schedule a meeting for next Monday",
  "intent_type":    "SCHEDULE_EVENT",
  "scopes":         ["calendar.read", "calendar.write"],
  "consent_method": "explicit_ui",
  "iat":            1748822400,
  "exp":            1748908800  // 24h window
}
// Signed with same test key; aud must match receiving service exactly

23.4 Failure Vectors

VectorModificationExpected Error
TV-F-01exp set to 1748822399 (1 second before iat)operator_jwt_expired
TV-F-02Signature corrupted (last byte flipped)operator_jwt_invalid
TV-F-03kid changed to "nonexistent-key"operator_not_found (after JWKS re-fetch)
TV-F-04iss domain has no agent-identity.jsonoperator_not_found
TV-F-05aud does not match receiving service URIoperator_jwt_invalid
TV-F-06DPoP jti reused within 5-minute windowdpop_replayed
TV-F-07Consent receipt aud is different serviceconsent_service_mismatch
TV-F-08mode field absent from register requestmode_missing
TV-F-09Mixed-mode session uses mode not declared at startmode_not_supported
TV-F-10Service account request touches resource outside granted_scope.resourcesboundary_violation
TV-F-11Aap-Version header value not in service's spec_versions_acceptedspec_version_unsupported
TV-F-12Destructive operation without X-Agent-Confirm on Tier F serviceirreversible_requires_confirm

A conformance test suite MUST verify all TV-F-01 through TV-F-12 failure cases in addition to the happy-path flow from §7. The full test suite with executable fixtures is maintained at https://aap.dev/conformance.


Glossary

Terms & Definitions

Every functional, technical, and protocol-specific term used in this specification. Written for three audiences: implementers building systems, product owners designing features, and project managers overseeing integrations.

A

AAP Agent Authentication Protocol

This specification. Defines how AI agents authenticate to third-party services, establish user authority, and maintain auditable records of their actions.

ImplementerThe full set of endpoints, token formats, headers, and validation rules described in §3–§23.
ProductThe standard your product adopts to let agents act on users' behalf safely and verifiably.
PMThe protocol that governs how AI agents get permission to do things. Think of it as the rulebook for agent access.
Access Token

A short-lived opaque credential issued by a service after successful registration. Presented on every API call as a Bearer or DPoP-bound token. Expires after credential_ttl seconds. Distinct from the delegation token — it is session-scoped, not long-lived.

ImplementerReturned by POST /agent/register. Include in Authorization: Bearer or Authorization: DPoP header on resource calls.
ProductThe temporary pass the agent uses to make API calls during a session. Expires regularly and must be renewed.
PMLike a day pass. The agent gets it at the start of a session and it expires after a few hours — unlike the delegation token which is the long-term permission.
Agent

An AI-powered automated system that takes actions in the real world on behalf of a user or organisation. Agents may call APIs, send messages, read and write data, or orchestrate other agents. In AAP, an agent is always operated by an identified operator and always acts under explicit delegated authority.

ImplementerThe client making AAP-authenticated requests. Responsible for managing token lifecycle, declaring mode, and carrying intent headers.
ProductThe AI system your product deploys to act on users' behalf — booking meetings, processing data, sending messages, etc.
PMThe automated AI that does the work. It needs permission (from the user or admin) before it can touch any system.
Agent Identity

The question of on whose behalf an agent acts and whose credentials it uses. AAP defines two distinct identity modes: user-delegated (acting as a specific person) and service account (acting as a fixed non-human identity). Not to be confused with the operator's identity, which is separate.

ImplementerDeclared via the mode field in registration. Governs which token chain is required and which audit rules apply.
ProductWhether your agent acts as each individual user (personalised results) or as a consistent system identity (same results for everyone).
PMDetermines what data the agent can see and who gave it permission. A key design decision with significant privacy and UX implications.
Admin Bootstrap

The one-time human-in-the-loop setup process for service account (Mode B) agents. An administrator authenticates to the service, reviews the exact scope being granted, and explicitly approves. The service issues an org-scoped delegation token. No per-user consent is needed after this point.

ImplementerHandled via POST /agent/delegate in an authenticated admin session. Token issued includes granted_scope and authorized_by fields.
ProductThe one-time setup an IT admin does to connect your agent to a service for the whole organisation.
PMThe IT equivalent of "sign up". Happens once per service. After this, the agent works for everyone in the org without individual users needing to authorise it.
ath claim

A claim inside a DPoP proof JWT. Contains the base64url-encoded SHA-256 hash of the access token being used. Binds the proof to a specific token, preventing an attacker from reusing a valid DPoP proof with a different stolen token.

Implementerbase64url(SHA-256(access_token_ascii)). Required on all resource calls where DPoP is used. Omit only on /agent/register where no access token yet exists.
ProductA security binding that ties each request to the specific token the agent was issued — preventing credential theft attacks.
PMPart of the DPoP security mechanism. Not something you configure — your cryptography library handles it.
Audit Trail

A chronological log of every action taken by an agent under a given delegation. Mandatory for all AAP-conformant services. Queryable by the user, operator, or admin. Includes timestamp, method, path, intent type, and (for Mode B with crosses_users: true) data subjects affected.

ImplementerServed at GET /agent/audit. Must support filtering by delegation_id and date range. Must be paginated. Must persist for the lifetime of the delegation.
ProductThe history log users and admins can review to see exactly what the agent did and why it claimed to be doing it.
PMThe paper trail. Essential for support, compliance, and building user trust. If something goes wrong, this is how you find out what happened.
Auto-Revoke Policy

A declarative set of conditions under which a delegation is automatically revoked without requiring explicit human action. Five trigger types: time-based expiry, task completion, inactivity timeout, lifecycle events (e.g. user offboarding), and usage budget exhaustion. The effective policy is the most restrictive combination of service, operator, and user policies computed at grant time.

ImplementerExpressed as effective_policy in the /agent/register response. Service must enforce all conditions. See §19.6 schema.
ProductAutomatic expiry rules that clean up agent access without users having to remember to revoke it manually.
PMHygiene automation. Prevents stale agent access from accumulating — particularly important when employees leave or projects end.

B

Bootstrap

The one-time human-in-the-loop step that roots the agent's authority chain. A human authenticates to the target service, reviews what they are granting, and approves. The service issues a delegation token. All subsequent agent activity derives authority from this moment. Cannot be bypassed.

ImplementerAgent detects missing delegation via 401 + WWW-Authenticate: Bearer agent_auth_required. Must surface to user rather than failing silently.
ProductThe "connect your account" moment. Happens once per service. After this the agent works autonomously.
PMThe setup step users or admins do once. Design it carefully — it's the moment that makes everything else possible and the moment where trust is established.
Boundary Violation

An error condition (HTTP 403, error code boundary_violation) returned when a Mode B service account request attempts to access a resource outside the granted_scope.resources declared in its delegation token. The agent is verified and authorised in general — but this specific resource is outside its declared scope.

ImplementerService must enforce resource boundaries declared in the org delegation token. Agent must not retry — this requires admin scope expansion.
ProductThe service blocked the agent from touching something it wasn't given access to at setup time.
PMAn access control enforcement event. Not a bug — it means the security model is working. Admin needs to expand the service account's scope if the access was legitimate.

C

Clock Skew

The difference in system time between the token issuer and the verifying service. AAP requires implementations to tolerate up to 300 seconds (5 minutes) of clock skew when validating iat and exp claims, to prevent valid tokens from being rejected due to minor time differences between systems.

ImplementerApply ±300s tolerance window to all JWT time validation. Do not reject tokens whose iat is up to 300s in the future or whose exp is up to 300s in the past.
ProductA tolerance built into the protocol so minor timing differences between systems don't cause unnecessary auth failures.
PMA technical detail that prevents mysterious auth failures caused by server clocks being slightly out of sync. Should be invisible to users.
Conformance Tier

One of three levels of AAP compliance: Core (minimum viable), Extended (production-grade), Full (high-assurance). Each tier is a strict superset of the previous. Services declare their tier in the discovery manifest. Tiers map to use case risk levels — Core for low-stakes APIs, Full for financial or regulated deployments.

ImplementerDetermines which endpoints, token types, and validation rules are required. Check §15 for the full feature matrix per tier.
ProductThe compliance level your service implements. Higher tiers unlock access to more security-conscious operators and regulated markets.
PMThink of it like a security certification level. Start with Core to get to market, upgrade to Extended or Full as your customer base demands it.
Consent Receipt

A signed JWT created by the operator's platform at the moment a user explicitly approves a specific task. Contains the intent, approved scopes, session ID, and expiry window. Bound to a specific service via the aud claim — cannot be replayed at a different service. Short-lived (hours to days). Required for T3+ trust tier.

ImplementerSigned by operator JWKS. Presented in POST /agent/register. Service verifies signature, aud, and exp. See §19.3 for full schema.
ProductThe record of a user saying "yes, do this specific thing". Created when a user approves a task in your agent's UI.
PMThe documented proof of user consent for each task. If something goes wrong, this is what demonstrates the user knowingly authorised the action.
crosses_users

A boolean field in the granted_scope object of a service account delegation token. true when the granted resources span more than one user's data. When true, services must log data_subjects in audit entries — identifying whose data was touched on each operation. Not a risk level indicator; purely a flag that triggers elevated audit rules.

ImplementerIf true in the delegation token, data_subjects array is REQUIRED in all audit log entries. If false, it may be omitted.
ProductTells the system whether the agent touches one user's data or multiple users' data — triggering stricter logging when it does.
PMIf your agent accesses data belonging to multiple people (e.g. a shared inbox), this flag ensures every action is traceable back to whose data was affected.

D

data_subjects

An array of user identifiers in Mode B audit log entries, recording whose data was accessed or modified by a specific agent action. Required when crosses_users: true in the delegation token. Enables users and admins to answer "did this agent touch my data?" even when the agent isn't acting for any named user.

ImplementerMust be populated by the service at time of logging, not by the agent. The service knows which resources were accessed and which users own them.
ProductThe list of users whose data a service account action touched. Critical for GDPR data subject access requests.
PMAnswers the compliance question "show me every time this agent touched data belonging to user X". Required for regulated industries.
Delegation Receipt

See Delegation Token. The term "delegation receipt" is used informally to emphasise the document's role as evidence of a user's approval act, rather than as a credential. The delegation token serves both functions.

Delegation Token

A long-lived JWT signed by the service (not the operator) after a successful bootstrap. Proves that a specific user (Mode A) or organisation (Mode B) authorised a specific operator's agent to access this service. Presented at every registration call. Cannot be used alone — must be accompanied by a valid operator JWT.

ImplementerService-signed. Contains sub (user or svc account), delegated_to (operator domain), scopes, and max_agent_ttl. See §19.4 schema.
ProductThe long-term permission slip. Issued once at bootstrap. Proves the user said "I trust this operator's agent to access my account here."
PMThe standing permission that lets the agent keep working without asking the user again. Can be revoked at any time to cut off access instantly.
Discovery Manifest

A JSON document hosted at /.well-known/agent-auth.json on a service's domain. Machine-readable description of how to authenticate agents to that service: supported modes, required trust tier, available scopes, endpoint URLs, conformance level, and disclosure strings. The first thing an agent fetches when encountering a new service.

ImplementerMust be publicly accessible, valid JSON, conforming to §19.1 schema. Agents cache it — keep it stable. Version it with spec field changes.
ProductYour service's agent-facing welcome page. Tells agent platforms what your service supports and how to connect.
PMLike an API directory listing, but for agents. Publish it once during implementation. Update it when you change your supported capabilities.
DNS-Anchored Identity

The trust model AAP uses for operator identity. An operator proves their identity by controlling a domain name — specifically by hosting a verifiable identity manifest and JWKS at well-known paths on that domain. The same trust model as TLS certificates. No central registry required.

ImplementerVerification: fetch https://operator.domain/.well-known/agent-identity.json, fetch JWKS from signing_keys URL, verify JWT signature. If domain is unreachable, reject.
ProductYour company's domain is your identity credential. No registration with a central authority needed — if you control the domain, you control the identity.
PMOperators prove who they are by owning their domain — the same way websites prove identity with HTTPS. No sign-up with a central registry.
DPoP Demonstrating Proof of Possession

An extension to OAuth (RFC 9449) that binds access tokens to a specific keypair. The agent generates an ephemeral keypair per session and proves it holds the private key on every request. Stolen access tokens become useless without the matching private key. Required for Tier E and above in AAP.

ImplementerGenerate ES256 keypair per session. Include DPoP: <proof_jwt> header with every request. Proof must include jti, htm, htu, iat, and ath claims. See §18.
ProductPrevents credential theft — even if an access token is intercepted, it can't be used without the private key that stays with the agent.
PMAn important security feature that makes stolen tokens useless. Required for production deployments handling user data. Your security team will want this.
Dry-Run Mode

A mode in which an agent asks a service "would this action succeed and what would it do?" without actually committing the operation. Allows agents to verify intent and surface expected outcomes to users before taking irreversible actions. Services supporting mutating operations are recommended to implement this endpoint.

ImplementerIndicated by X-Agent-Dry-Run: true header. Service processes the request logic but does not commit. Returns 200 with a preview of what would have changed.
ProductA preview feature for agents — lets them show users "here's what I'm about to do" before doing it.
PMThe "confirm before sending" step for agent actions. Reduces errors and builds user confidence. Especially valuable for actions that can't be undone.

E

Effective Policy

The computed auto-revoke policy that applies to a specific delegation, resolved at grant time as the most restrictive combination of service, operator, and user policies. Stored in the /agent/register response and in the delegation token so all parties can see what will actually happen without needing to recompute it.

ImplementerComputed as: min(service.max_duration, operator.max_duration, user.max_duration) for each policy dimension. Store it; do not recompute on each request.
ProductThe actual expiry rules for a specific agent connection, after all parties' preferences are combined.
PMThe "what actually governs this connection" summary. If your org has 14-day inactivity timeout but the service requires 30-day max duration, the effective policy uses 14 days.
Error Envelope

The standard JSON shape for all error responses across all AAP endpoints. Contains: error (machine-readable code), error_description (human-readable), hint (what to do next), and request_id. One shape everywhere — agents can parse errors programmatically without per-endpoint handling.

ImplementerReturn this shape on every 4xx and 5xx response. Never return raw exception text. The error field must be from the §16.2 catalogue.
ProductStandardised error messages that agent platforms can understand and act on — rather than trying to parse human-readable error text.
PMMakes integration debugging much easier. When something breaks, the error tells the agent exactly what went wrong and what to do next.
Execution Window

A time range (earliest / latest in ISO 8601) in the consent receipt that bounds when a background or offline agent task may execute. Treats consent as a window rather than a moment. The agent may only act within this window. The user sets it explicitly when approving the task.

ImplementerOptional field in consent receipt. If present, service must reject requests outside the window with consent_expired. Agent must abort if it detects it has run past latest.
ProductLets users say "run this tonight between 10pm and 6am" rather than just "run this now".
PMThe scheduled task permission. Particularly important for overnight batch jobs or anything that runs while the user is asleep.

G

granted_scope

An object in the service account delegation token that precisely describes what a Mode B agent was authorised to access at bootstrap time. Contains a human-readable description, an explicit list of resources, the permitted scopes, and the crosses_users flag. Authoritative — the agent may not exceed this scope regardless of what the service's general API permits.

ImplementerEnforced by the service on every Mode B request. If a resource is not in granted_scope.resources, return 403 boundary_violation. See §19.5.
ProductThe precise access boundary for a service account — could be one shared inbox or the whole org's data. Set by the admin at bootstrap.
PMWhat the IT admin actually approved. The agent cannot exceed this, no matter what. Expansion requires a new admin approval.

H

Heartbeat

A periodic status signal sent by an agent running a long-duration background task to inform the user that the task is still running and still within declared scope. Required for tasks expected to run longer than 30 minutes. The user must be able to abort from the heartbeat notification without being at a computer.

ImplementerInterval declared as heartbeat_interval (seconds) in the consent receipt. Delivery is the operator's responsibility — the protocol does not define the channel (push notification, email, etc.).
ProductThe "still running" ping your agent sends to users during long tasks, with an option to stop it.
PMKeeps users informed during overnight or multi-hour tasks. Prevents the "I forgot that agent was running" problem. Critical for user trust.

I

ID-JAG Identity Assertion for Agents

A token type defined in the WorkOS auth.md proposal (the precursor that inspired AAP). AAP does not use ID-JAG — it uses a standard JWT profile instead. Included here because implementers reading auth.md alongside this spec may encounter the term.

ImplementerNot used in AAP. If you see ID-JAG in another spec, it is not compatible with AAP tokens. The AAP operator JWT serves an equivalent purpose.
ProductA concept from a competing proposal. AAP chose standard JWTs over this format for tooling compatibility.
PMNot relevant to AAP implementation. Historical context only.
Identity Mode

The fundamental choice of how an agent presents itself: as a specific user (Mode A — User-Delegated) or as a fixed non-human identity (Mode B — Service Account). Must be declared in every registration request. No default. Governs the entire trust chain, bootstrap process, audit requirements, and user disclosures.

ImplementerDeclared via mode field in POST /agent/register. Values: "user_delegated" or "service_account". Absent mode returns 400 mode_missing.
ProductThe single most important architectural decision for your agent integration. Determines personalisation model, privacy posture, and admin vs user ownership.
PMDo users get personalised results (Mode A) or does everyone get the same thing (Mode B)? This choice has significant product, privacy, and compliance implications.
Intent / Intent Header

A human-readable description of why an agent is making a specific API call, carried in the X-Agent-Intent (Mode A, free text, operator-held) or X-Agent-Intent-Type (Mode B, structured vocabulary, service-logged) headers. Creates an auditable trail without the service needing to know the sensitive details of what the user asked for.

ImplementerMode A: free text, max 500 chars, stored operator-side only. Mode B: structured type from service-defined vocabulary. Services log the type; never the free text.
ProductThe "reason" field for each agent action. Enables users to understand why the agent did what it did when they review the audit log.
PMMakes the audit trail human-readable. "Booking standup Monday 9am" is far more useful than "POST /calendar/events". Essential for user trust and support.
Irreversible Operation

A class of operations (delete, send, pay, publish) that cannot be undone or have significant consequences if performed in error. AAP Tier F requires a pre-action confirmation signal (X-Agent-Confirm: true) for irreversible operations, even if the scope is already granted. Undo windows (30s) apply where the service supports them.

ImplementerService declares which operations are irreversible in scope definitions. For Tier F, service returns 403 irreversible_requires_confirm without the confirm header. See §14.1.
ProductDestructive or consequential actions that the agent must explicitly confirm before executing, even when authorised to do so.
PMThe "are you sure?" moment for agents. Protects users from agents acting on misunderstood instructions for actions that can't be taken back.

J

JWKS JSON Web Key Set

A JSON document containing one or more public keys used to verify JWT signatures. Operators host their JWKS at the URL declared in their identity manifest's signing_keys field. Services fetch and cache this to verify operator JWTs. During key rotation, both old and new keys must coexist in the JWKS for at least 2× the service's cache TTL.

ImplementerEach key must have a kid. Services cache with max 1-hour TTL. On kid mismatch, re-fetch once before rejecting. Use ES256 keys recommended. See §20.
ProductThe operator's public key store — how services verify that tokens actually came from your platform.
PMYour platform's cryptographic identity document. Needs to stay available and be updated carefully during key rotations. Downtime here breaks all agent authentications.
JWT JSON Web Token

The token format used for all AAP credentials: operator JWTs, delegation tokens, consent receipts, and DPoP proofs. A JWT is a base64url-encoded JSON payload with a cryptographic signature. The signature can be verified by anyone with the signer's public key — no call back to the issuer needed.

ImplementerRFC 7519. Use a well-maintained library — do not implement JWT verification from scratch. Always validate: signature, exp, iat, iss, aud. Reject unsigned tokens.
ProductThe standard credential format underlying all AAP tokens. Widely supported across languages and platforms.
PMIndustry-standard secure tokens. Your engineering team will be familiar with these. The building block of the entire AAP security model.

L

Liability Disclosure

A plain-language statement shown to users or admins at bootstrap time, answering: what can this agent do, what can't it do, and who do you contact if something goes wrong. Required for Tier F. Must be under a defined word limit and written in plain language — not legal boilerplate. Returned in the /agent/delegate response and displayed before the delegation token is issued.

ImplementerPlain text string in /agent/delegate response. Must be shown to the user before they can approve. Service decides content; operator displays it.
ProductThe honest, human-readable "what you're agreeing to" statement. Not legal disclaimers — actually useful information about what the agent will do.
PMManages user expectations and documents informed consent. In a dispute or audit, this is evidence that users were clearly told what they were authorising.

M

Mixed-Mode Session

A session in which a single agent task uses both Mode A (user-delegated) and Mode B (service account) credentials for different API calls. Both modes must be declared and registered at session start using the same session_id. Each request must carry X-Agent-Mode. The audit log correlates all actions under the shared session ID.

ImplementerCall /agent/register once per mode with the same session_id. Modes not declared at start are rejected. Partial revocation does not terminate the whole session. See §21.
ProductWhen your agent reads a shared document (service account) then sends a personal email (user-delegated) in the same task flow.
PMAn agent using both its "company hat" and its "user hat" within one task. Common in real workflows — needs to be planned for explicitly.
Mode A — User-Delegated

An identity mode in which the agent acts as a specific named user, using that user's delegated credentials. The agent sees only what that user can see. Different users get different responses. Requires per-user bootstrap and consent receipt. Revocable by the user.

Implementermode: "user_delegated". Requires delegation token with user sub, consent receipt with user sub, and operator JWT. See §11.
ProductPersonalised agent access. The agent is effectively "logged in as the user" with their explicit permission.
PMThe "acting as me" mode. Each user gets their own experience because the agent uses their credentials. Users control their own access.
Mode B — Service Account

An identity mode in which the agent uses fixed, non-human credentials authorised by an admin. All users interacting with the agent get consistent responses. Scope is defined precisely at bootstrap — may be narrow or wide. Not inherently org-wide. Revocable only by an admin.

Implementermode: "service_account". Requires org delegation token with granted_scope object and crosses_users flag. No consent receipt. See §11.
ProductConsistent agent access defined by IT. Like a shared system user — the same access regardless of which human is interacting.
PMThe "company account" mode. Set up once by IT, works for everyone. Good for shared resources; not appropriate where personalisation or individual privacy matters.

O

Operator

The company or developer who built and deployed the agent. Identified by their domain name (DNS-anchored). Responsible for the agent's actions. Holds the signing keys used to produce operator JWTs and consent receipts. The accountability anchor in the AAP trust chain — the party that can be contacted, held responsible, and whose access can be terminated.

ImplementerMust host /.well-known/agent-identity.json and /.well-known/agent-jwks.json. Must sign operator JWTs and consent receipts with declared keys. See §4.
ProductYour company. You are the operator when you deploy an agent built on an AI model.
PMThe accountable party. If an agent does something wrong, the operator is who the service and user can hold responsible.
Operator JWT

A short-lived JWT signed by the operator's private key, presented at every /agent/register call. Proves the request genuinely originates from the declared operator domain. Verified by the service against the operator's JWKS. Contains iss (operator domain), aud (target service), kid, iat, and exp.

ImplementerGenerated by the operator platform per request (short-lived). Service fetches JWKS, matches kid, verifies signature. Invalid signature returns 401 operator_jwt_invalid.
ProductYour platform's "this is really us" credential, presented on every agent session start.
PMThe operator's authentication token — like an API key but cryptographically tied to your domain and automatically expiring.
Org-Scoped Delegation

A delegation token issued for a Mode B service account, where the subject is an organisation (via org_id) rather than an individual user. The scope is defined by granted_scope and may be narrow or wide. Distinct from a user delegation token — no individual user's identity is asserted.

ImplementerToken sub is the service account ID (svc_* pattern). authorized_by records the admin email. Revocable via /agent/revoke by admin only. See §19.5.
ProductThe service's record that an admin approved this agent for this organisation, with a specific access boundary.
PMThe company-level permission slip, as distinct from individual user permissions. Issued to the organisation, not to a person.

P

Perception Gap

The distance between formal consent (a user tapped approve) and informed consent (a user understood what they were approving). AAP's protocol layer can enforce that disclosures were presented; it cannot enforce that they were read or understood. Closing the perception gap requires UX design, progressive disclosure, and comprehension signals — elements that are recommended but not protocol-enforceable.

ImplementerUse comprehension signals over acknowledgement buttons for high-risk scopes. Scale friction to consequence.
ProductThe UX challenge of making consent meaningful rather than just a friction point users dismiss. Critical for trust and for genuine accountability.
PMThe hardest problem in agent UX. Your consent screens need to communicate clearly — not just tick a legal box. Invest in testing that real users understand what they're agreeing to.
Provider Registry

An optional JSON document hosted by a model provider (e.g. Anthropic, OpenAI) at /.well-known/agent-operators.json, listing operators they have verified are legitimately using their API. Services requiring T4 trust can cross-reference this list. Providers are not required to participate — T4 is an optional upgrade, not a baseline requirement.

ImplementerFetch and cache alongside operator JWKS for T4 verification. Check standing field — reject operators with "suspended" or "revoked" status.
ProductAn extra layer of vetting — your model provider vouches that you're a legitimate operator. Unlocks access to the most security-sensitive services.
PMOptional accreditation from your AI provider. Think of it as a trust seal that high-security customers (banks, healthcare) may require.

R

Revocation

The act of cancelling an agent's delegated authority, preventing all further access until re-authorised. In AAP, revocation is first-class and designed for speed: short-lived access tokens mean revocation propagates within one TTL window without push infrastructure. Explicit revocation via /agent/revoke is also supported. Auto-revoke policies provide declarative revocation without human action.

ImplementerImplement /agent/revoke as idempotent. On refresh attempt with revoked delegation, return 401 delegation_revoked. Notify operator via webhook (Tier F). See §8.
ProductThe "disconnect this agent" capability. Users and admins must be able to cut off agent access immediately, from anywhere.
PMThe emergency stop. Every agent integration needs a clear, fast, reliable way to turn it off. This is non-negotiable for user trust and incident response.

S

Scope

A named permission that grants an agent the ability to perform a class of operations. Defined by the service in the discovery manifest with explicit allows and explicitly_excludes action enumerations. Service scope definitions are authoritative — operators may narrow them but not redefine them. Any action not in allows is implicitly excluded.

ImplementerScopes follow the pattern [resource].[action] (e.g. calendar.write). Must enumerate allowed actions explicitly — not just a label. See §12.3 and §19.1.
ProductThe specific permissions your agent requests. Define them narrowly — the principle of least privilege makes agents safer and easier for users to trust.
PMWhat the agent is allowed to do. Narrow scopes = easier user approval + lower risk. Broad scopes = more friction and more exposure if something goes wrong.
Scope Expansion

When an agent mid-task determines it needs a scope beyond what the current consent receipt granted. Behaviour is governed by the service's declared scope_expansion policy: reject (return 403), notify (push notification to user, agent polls for approval), or silent (grant if within delegation token scopes, log only). Default is notify.

ImplementerAgent receives 403 consent_scope_exceeded. If policy is notify, agent must poll /agent/scope-approval?session_id= for user response before retrying.
ProductThe agent asking for more permissions partway through a task. Must be surfaced to the user — never granted silently by default.
PMWhen an agent hits the edge of what it was approved to do and needs to ask for more. How you handle this is a key product decision — it can interrupt the user experience.
Service Account

A non-human identity used by a Mode B agent. Has fixed credentials not tied to any individual user. Authorised by an admin. Its scope is precisely defined at bootstrap via granted_scope. All callers get consistent results because the agent always operates with the same credentials. Not inherently org-wide — scope is whatever the admin approved.

ImplementerIdentified by sub matching ^svc_[a-z0-9_]{3,64}$ pattern in delegation token. Revocable by admin only. Audit entries may omit user context but must include data_subjects when crosses_users: true.
ProductA bot account for your agent — consistent access independent of which user is interacting with it.
PMLike a shared company email account. Everyone uses it the same way. Controlled by IT, not by individual users.
Session ID

A cryptographically random identifier that ties all API calls within a single agent task together. Stable for the lifetime of the consent receipt. Used for audit correlation — especially important in mixed-mode sessions where both Mode A and Mode B calls share the same session ID. Must be unguessable and not reusable across different users or delegation IDs.

ImplementerUUID v4 or equivalent. Generated by operator per task. Carried in X-Agent-Session header on every call. Included in all audit log entries.
ProductThe unique ID for a single agent task — lets you reconstruct everything that happened during "book a meeting with Sarah".
PMThe task reference number. Lets support teams pull up the full history of exactly what an agent did during a specific job.

T

Token Binding

The cryptographic binding of an access token to a specific keypair (via DPoP), so that the token cannot be used by anyone who doesn't hold the corresponding private key. Prevents bearer token replay attacks — an attacker who intercepts a token cannot use it without the private key that stays with the legitimate agent. Required from Tier E.

ImplementerImplemented via DPoP (§18). Access tokens are issued as token_type: "DPoP" and bound to the DPoP public key presented at registration.
ProductMakes stolen tokens useless — the attacker also needs the private key, which never leaves the agent.
PMAn important security upgrade over standard bearer tokens. Required for any production deployment handling real user data.
Trust Anchor

The root of a verification chain — the thing whose trustworthiness everything else depends on. AAP has three trust anchors: DNS control (for operator identity), service-issued tokens (for user delegation), and operator-signed receipts (for consent). An optional fourth anchor — model provider registries — is available for T4.

ImplementerEach trust anchor corresponds to a verification step in the registration flow. All three required anchors must pass before an access token is issued.
ProductThe foundations of the trust model. Everything else in the protocol is built on top of these three verifiable claims.
PMThe "who vouches for this?" chain. DNS for the operator, the service for the user, the operator for the task. Each one independently verifiable.
Trust Tier

One of four levels (T1–T4) describing how much of the AAP trust chain has been verified for a given interaction. T1: operator identity only. T2: operator + user delegation. T3: operator + delegation + consent receipt. T4: T3 + model provider registry. Services declare their required minimum tier. Higher tiers provide stronger guarantees at the cost of more setup.

ImplementerDeclared as minimum_tier (1–4) in the discovery manifest. Requests not meeting the minimum tier are rejected with appropriate 401/403 errors.
ProductYour service's security bar for agent access. Higher tiers unlock stronger verification at the cost of more implementation work for operators.
PMThe security level required to connect. T1 is quick to integrate; T3–T4 takes more work but is required for sensitive data. Match to your compliance requirements.

U

Undo Window

A short period (default 30 seconds) after a write operation during which the action can be reversed by the agent or user. Similar to "undo send" in email. Services supporting undo windows must expose a cancel endpoint for the specific resource created or modified. Required for Tier E+ on supported operation types.

ImplementerService returns an undo_url in the response body of eligible write operations. Agent surfaces the undo option to the user for the window duration. See §14.1.
ProductA grace period for mistakes. The agent did something the user didn't intend — the undo window gives them a moment to correct it.
PMSafety net for agent errors. Users feel safer knowing actions aren't instant and permanent. Important for adoption of write-capable agents.
Usage Limits

Optional constraints on a consent receipt that cap how much an agent can do within its authorised scope: requests_per_hour, writes_per_session, max_data_egress_kb. Prevents a misbehaving or compromised agent from causing damage at scale even with valid credentials. Exhausting limits returns 429 usage_limit_reached and triggers re-consent.

ImplementerEnforced by the service against counts tracked per delegation_id. On exhaustion: return 429 usage_limit_reached with a Retry-After header indicating window reset time.
ProductA budget for each authorised task. Even if the agent has permission to send emails, it can only send 10 per session — not 10,000.
PMRate limiting at the intent level. Protects both the user and the service from runaway agents. Set sensible defaults and let users adjust them.
User-Delegated see Mode A

V

Version Negotiation

The mechanism by which agents and services agree on which AAP version to use. Agents declare their version in the Aap-Version request header. Services respond with Aap-Version-Served and may advertise all accepted versions via Aap-Version-Accepted. Version mismatches return 400 spec_version_unsupported — never silently degrade.

ImplementerInclude Aap-Version: 2.0 on all requests. Handle 400 spec_version_unsupported by checking Aap-Version-Accepted header and retrying at a compatible version. See §22.
ProductEnsures your agent platform and the service it's connecting to are speaking the same protocol version.
PMPrevents silent compatibility failures as the spec evolves. When you upgrade your agent platform, version negotiation ensures existing integrations don't break quietly.

W

Webhook (Auto-Revoke)

A push notification from the service to the operator when an auto-revoke policy triggers. Delivered to the webhook_url in the operator's identity manifest. Payload signed with HMAC-SHA256 using a shared secret. Required for Tier F. Polling /agent/audit is the fallback for Tier C and E.

ImplementerService retries with exponential backoff on failure. Operator must respond 200 within 5 seconds. Verify signature before processing: HMAC-SHA256(timestamp + "." + body). See §17.8.
ProductThe notification your platform receives when a service automatically cuts off an agent's access — so you can inform the user and take action.
PMThe alert system for automatic disconnections. Without this (Tier F), you'd only discover a revocation when the next API call fails. With it, you know immediately.
.well-known

A standardised path prefix (RFC 8615) for hosting machine-readable metadata about a domain. AAP uses three well-known paths: /.well-known/agent-auth.json (service discovery manifest), /.well-known/agent-identity.json (operator identity manifest), and /.well-known/agent-jwks.json (operator signing keys). The same convention used by OpenID Connect and OAuth metadata.

ImplementerAll three paths must be publicly accessible over HTTPS, return correct Content-Type (application/json), and be served without authentication. Cache-Control headers recommended.
ProductStandard locations where your service or operator platform publishes its AAP configuration — discoverable by any agent without prior coordination.
PMThe "phone book entries" for your AAP integration. Publish once during setup. Keep them available — if they go down, all agent authentications fail.