AgentPKI Protocol v0.1
Status: Draft
Date: 2026-05-21
Editors: AgentPKI Project
License: Apache License 2.0
Repository: github.com/agentpki/spec (planned)
Abstract
The AgentPKI Protocol defines a cryptographic identity layer for autonomous AI agents acting on the public web. It specifies a passport token format, an issuance and trust-tier model, a verification API suitable for sub-50ms edge deployment, a revocation mechanism, a capability-scoping vocabulary, and an abuse-reporting feedback loop. The protocol is chain-agnostic, vendor-neutral, and designed to slot underneath existing bot-defense systems (e.g., Cloudflare, DataDome, hCaptcha, Arkose) so that legitimate AI agents may be distinguished from anonymous traffic without requiring sites to trust any single agent vendor.
AgentPKI deliberately does not define a payment, settlement, or commerce layer; passports may be used as the principal identifier by such layers (including Kite Agent Passport, Stripe MPP, x402, Google AP2) but those layers are out of scope of this specification.
Status of this Document
This is a v0.1 working draft published for community feedback. It is not yet a stable specification. Implementations following this draft SHOULD pin to the exact draft version and expect breaking changes prior to v1.0. After v1.0, the protocol follows semantic versioning: backward-incompatible changes increment the major version.
The latest version, errata, and conformance test vectors are maintained at:
https://spec.agentpki.dev/v0.1/
1. Conventions and Terminology
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in [RFC 2119] and [RFC 8174] when, and only when, they appear in all capitals.
The following terms are used throughout:
| Term | Definition |
|---|---|
| Agent | An autonomous software process acting on behalf of a human or organization that issues HTTP requests to third-party services. |
| Issuer | An entity (typically an agent platform vendor, a frontier model lab, or an enterprise) that mints passports for one or more agents. Identified by a DNS name (e.g., anthropic.com). |
| Passport | A short-lived signed token asserting the identity, trust tier, capabilities, and constraints of an agent. Defined in §4. |
| Holder | The agent in possession of a passport, presenting it to verifiers as a bearer credential or as a key for HTTP Message Signatures. |
| Verifier | A service (typically operated by AgentPKI or a bot-defense vendor) that validates a passport and returns a structured verdict to a relying site. |
| Relying site | A web service that delegates passport verification to a Verifier and uses the verdict to make access, throttling, or routing decisions. |
| Trust tier | One of three identity-assurance levels (T1 DNS, T2 KYB, T3 hardware-attested) defined in §5.2. |
| Capability scope | A namespaced string asserting an action the passport authorizes the agent to take, e.g., read:articles, purchase:up-to-100usd. |
| Root directory | A curated, signed list of vetted issuers and their current public keys, maintained by AgentPKI. Conceptually analogous to the CA/Browser Forum root store. |
2. Architecture Overview
┌─────────────────┠┌──────────────────┠┌─────────────────â”
│ Issuer │ │ Holder │ │ Relying Site │
│ (e.g. Anthropic)│ │ (the agent) │ │ (e.g. Reuters) │
└────────┬────────┘ └────────┬─────────┘ └────────┬────────┘
│ 1. mint passport │ │
├─────────────────────────►│ │
│ │ 2. HTTPS request + │
│ │ passport (Mode A or B)│
│ ├─────────────────────────►│
│ │ │
│ │ │ 3. verify
│ │ ▼
│ │ ┌─────────────────────â”
│ │ │ Verifier │
│ │ │ (AgentPKI edge or │
│ │ │ bot-defense vendor)│
│ │ └──────────┬──────────┘
│ │ │
│ 4. pubkey lookup (cached)│ │
│◄─────────────────────────┼─────────────────────────┤
│ │ │
│ │ 5. verdict {verified, │
│ │ tier, scope, abuse} │
│ │◄────────────────────────┤
│ │
│ │ 6. allow / throttle / deny
│ │
┌────────┴────────┠┌─────────────────────â”
│ Issuer Directory│◄────── curated trust list ─────│ Root Directory │
│ (.well-known) │ │ directory.agentpki │
└─────────────────┘ └─────────────────────┘
Five participants:
- Issuer — establishes its identity once (§5.1), publishes a directory document at a well-known URL (§6), and mints passports for its agents (§5.4).
- Holder (agent) — receives passports from its issuer and presents them to relying sites either as a bearer header (Mode A, §7.1) or via HTTP Message Signatures (Mode B, §7.2).
- Relying site — delegates verification to a Verifier and acts on the verdict.
- Verifier — runs the verification procedure of §8, returns a structured verdict, and maintains edge caches of issuer public keys and revocation state.
- Root directory — AgentPKI-operated curated list of vetted issuers and their current key material, signed by the AgentPKI root.
3. Design Goals and Non-Goals
3.1 Design Goals
- G1. Sub-50ms p99 verification globally. Edge-deployable in stateless functions (Cloudflare Workers, Fastly Compute, AWS Lambda@Edge).
- G2. Cross-vendor neutral. No dependency on any single agent platform, foundation model vendor, or settlement layer.
- G3. Chain-agnostic. No requirement for blockchain anchoring or on-chain settlement.
- G4. Asymmetric crypto only. No shared secrets transmitted; relying sites verify signatures using issuer public keys retrieved over HTTPS.
- G5. Standard-stack first. Built on PASETO v4 [PASETO], Ed25519 [RFC 8032], HTTP Message Signatures [RFC 9421], and JSON. No novel cryptography.
- G6. Bot-defense vendor friendly. Verdict payload designed to slot into existing bot-defense decision pipelines without protocol-specific UX.
- G7. Forward-compatible with W3C Verifiable Credentials. Spec carves out a credential-envelope abstraction (§14) so a VC-mode can be added without breaking changes.
3.2 Non-Goals
- NG1. Payment, settlement, or escrow. Passports MAY be used as the principal identifier by payment systems but the protocol does not move money.
- NG2. Agent discovery or naming-service. Discovery is handled by complementary protocols such as OWASP Agent Name Service.
- NG3. Internal workload identity. SPIFFE/SPIRE remains the recommended tool for service-to-service trust inside an organization; AgentPKI is for cross-organization (public-internet) identity.
- NG4. Human user identity. Passports identify agents, not the humans they act for. Linking a passport to a verified human is supported via the
act:on-behalf-of:user:<id>scope (§9.2) but the human-identity verification itself is out of scope. - NG5. Content authenticity (C2PA-style). Passports authenticate the requestor, not the content.
4. Passport Token Format
4.1 Container
A passport MUST be encoded as a PASETO v4.public token [PASETO]. The token is structured as:
v4.public.<base64url(payload || signature)>.<base64url(footer)>
- The payload is a UTF-8 JSON object as specified in §4.2.
- The signature is an Ed25519 signature over the payload and footer, as defined by PASETO v4.public.
- The footer is an OPTIONAL UTF-8 JSON object containing non-authenticated key identifier metadata as specified in §4.3.
Implementations MUST use a PASETO v4 library that has passed the project conformance vectors. Implementations MUST NOT parse or trust the payload or footer prior to successful signature verification.
4.2 Payload Claims
The payload MUST be a JSON object containing the following members.
4.2.1 Required Claims
| Claim | Type | Description |
|---|---|---|
v | integer | Protocol major version. MUST be 1 for tokens conforming to this spec. |
iss | string | Issuer DNS name in lower-case (e.g., "anthropic.com"). |
sub | string | Agent identifier, assigned by the issuer. RECOMMENDED form: agent:<iss>/<local-name> (e.g., "agent:anthropic.com/research-bot-v3"). MUST be stable across passport rotations for the same logical agent. |
iat | integer | Issued-at, UNIX seconds. |
exp | integer | Expiry, UNIX seconds. MUST be ≤ iat + 86400 for v0.1 (24-hour maximum lifetime). |
jti | string | Unique token identifier. MUST be at least 128 bits of entropy, encoded as lower-case hex or base32. Used for revocation and replay-protection. |
tier | integer | Trust tier: 1, 2, or 3 (§5.2). |
4.2.2 Optional Claims
| Claim | Type | Description |
|---|---|---|
aud | string | array | Intended audience: a single domain, an array of domains, or "*" for any. If present and non-"*", verifiers SHOULD reject if the relying site’s domain is not in the set. Default: "*". |
nbf | integer | Not-before, UNIX seconds. If present, verifiers MUST reject tokens with now < nbf. |
scope | array of strings | Capability scopes asserted by the issuer. See §9. Default: [] (no capabilities asserted). |
rate | object | Issuer-suggested rate limit hint: { "rpm": <int>, "daily": <int> }. Advisory; relying sites MAY ignore. |
cnf | object | Confirmation key for Mode B (HTTP Message Signatures). See §7.2. |
ext | object | Issuer-specific extension data. Keys MUST be namespaced under a domain the issuer controls (e.g., "anthropic.com/internal-id"). Verifiers MUST ignore unknown extensions. |
4.2.3 Example Payload
{
"v": 1,
"iss": "anthropic.com",
"sub": "agent:anthropic.com/research-bot-v3",
"iat": 1747857600,
"exp": 1747861200,
"jti": "0e4f8a2c91b34e7b9c5d8a1e2f3b4c5d",
"tier": 2,
"aud": "*",
"scope": ["read:articles", "read:public-data"],
"rate": { "rpm": 60, "daily": 10000 }
}
Resulting in a token of roughly 380–450 bytes including signature and base64url overhead.
4.3 Footer
The footer is OPTIONAL. If present, it MUST be a JSON object containing only:
{ "kid": "anthropic-2026-q2" }
The kid (key identifier) selects which of the issuer’s currently-published public keys (§6.2) was used to sign this passport. If absent, the verifier MUST attempt verification against each non-revoked key in the issuer’s directory document, in valid_from-descending order.
The footer MUST NOT contain authenticated security material. Per PASETO v4, the footer is signed but not encrypted; it must not be relied upon for authorization decisions until full verification succeeds.
5. Issuance
5.1 Issuer Identity Establishment
An issuer is identified by a DNS name it controls. To establish itself, an issuer:
-
MUST publish an issuer directory document at
https://<issuer-domain>/.well-known/agentpki-issuer.json(§6). -
MUST prove control of the domain by either:
- DNS TXT verification (T1): publishing a TXT record at
_agentpki.<issuer-domain>containing the SHA-256 hex of the issuer’s primary public key. - TLS certificate verification (implicit): serving the well-known endpoint over HTTPS with a publicly-trusted certificate matching the issuer domain.
Both SHOULD be performed; T1 issuers MUST satisfy at least one.
- DNS TXT verification (T1): publishing a TXT record at
-
MAY submit to the AgentPKI Root Directory (§6.4) for inclusion in the curated trust list, which is a prerequisite for T2 and T3.
5.2 Trust Tiers
| Tier | Name | Requirements |
|---|---|---|
| T1 | Domain-verified | DNS TXT or TLS-served well-known. Self-serve. No KYB. |
| T2 | KYB-verified | T1 + business identity verification (KYB) by an AgentPKI-approved provider. Legal entity name and jurisdiction published in the directory document. |
| T3 | Hardware-attested | T2 + cryptographic attestation that the agent’s signing key material is held in a Trusted Execution Environment (TEE) such as AWS Nitro Enclaves, Azure Confidential Computing, GCP Confidential Space, or comparable. Attestation document published alongside the passport in the ext.agentpki.dev/tee-attestation field. |
Relying sites declare a minimum tier in their site policy (§8.1). Verifiers MUST reject passports below the required tier even if otherwise valid.
5.3 Issuer Key Management
Issuers MUST:
- Use Ed25519 [RFC 8032] for all passport signing keys.
- Maintain at least one current key and MAY publish up to four (rotation overlap).
- Rotate signing keys at least every 12 months (RECOMMENDED: 90 days).
- Publish revoked keys in the
revoked_keysarray of the directory document for at least 90 days after revocation. - Store private key material in a Hardware Security Module (HSM), cloud KMS with FIPS 140-2 Level 3 or higher backing, or equivalent. For T3, attestable TEE storage is REQUIRED.
Issuers SHOULD NOT reuse signing keys across protocol versions or across distinct logical agent fleets.
5.4 Passport Minting
To mint a passport, the issuer:
- Selects an agent (
sub) and determines the appropriate scopes, rate hints, and audience. - Selects a current signing key.
- Generates 128+ bits of entropy as
jti. - Constructs the payload per §4.2, signs per PASETO v4.public, and emits the token.
- SHOULD include the
kidfooter to enable key-selective verification. - Delivers the token to the agent over an authenticated channel (out of scope of this spec; typically the agent SDK retrieves it from the issuer’s authenticated API).
5.5 Passport Rotation
Passports MUST have exp - iat ≤ 86400 (24h). Agents SHOULD request a fresh passport when the current one has less than 25% of its lifetime remaining. Issuers SHOULD provide a low-latency mint endpoint to support short-lived passports (60-300s lifetimes are RECOMMENDED for high-volume agents).
6. Issuer Directory
6.1 Well-Known Endpoint
Each issuer MUST publish a directory document at:
https://<issuer-domain>/.well-known/agentpki-issuer.json
The endpoint MUST serve Content-Type: application/json and SHOULD set Cache-Control: public, max-age=300, stale-while-revalidate=3600.
6.2 Document Format
{
"v": 1,
"issuer": "anthropic.com",
"name": "Anthropic, PBC",
"tier": 2,
"current_keys": [
{
"kid": "anthropic-2026-q2",
"alg": "Ed25519",
"pubkey": "MCowBQYDK2VwAyEA...",
"valid_from": 1714521600,
"valid_to": 1722384000
}
],
"revoked_keys": [
{
"kid": "anthropic-2026-q1",
"revoked_at": 1714521600,
"reason": "scheduled-rotation"
}
],
"kyb": {
"verified_by": "agentpki-root",
"verified_at": 1714521600,
"legal_name": "Anthropic, PBC",
"jurisdiction": "US-DE"
},
"crl_url": "https://anthropic.com/.well-known/agentpki-crl.json",
"abuse_report_url": "https://anthropic.com/.well-known/agentpki-abuse",
"contact": {
"abuse": "mailto:[email protected]",
"security": "mailto:[email protected]"
},
"signed_by_root": "v4.public.eyJp...."
}
Field reference:
| Field | Required | Description |
|---|---|---|
v | yes | Document schema version. MUST be 1. |
issuer | yes | Lower-case DNS name; MUST equal the host serving the document. |
name | yes | Human-readable name of the issuer. |
tier | yes | The issuer’s claimed maximum tier (1, 2, or 3). |
current_keys | yes | Array of currently-valid signing keys. MUST contain ≥1. |
current_keys[].kid | yes | Key identifier; MUST be unique across current_keys and revoked_keys. |
current_keys[].alg | yes | MUST be "Ed25519" for this protocol version. |
current_keys[].pubkey | yes | Base64-encoded SubjectPublicKeyInfo (DER) per RFC 8410. |
current_keys[].valid_from/valid_to | yes | UNIX seconds; verifiers SHOULD reject tokens with iat outside this range. |
revoked_keys | no | Array of revoked keys with kid, revoked_at, and reason. |
kyb | conditional | REQUIRED for T2 and T3 issuers. |
crl_url | yes | URL of the issuer’s certificate revocation list (§10). |
abuse_report_url | yes | HTTPS endpoint accepting POST submissions per §11. |
contact | yes | RFC 5322 mailto URIs for abuse and security. |
signed_by_root | conditional | REQUIRED for T2+ issuers; PASETO v4.public signature over the document (excluding this field) by the AgentPKI root key. |
6.3 Caching and Freshness
Verifiers MUST cache issuer directory documents subject to the Cache-Control header but in no case longer than 1 hour. Verifiers SHOULD asynchronously refresh documents that are within 25% of TTL expiry. On cache miss, verifiers MUST complete fetch + validation within the verification SLA or return unknown_issuer and let the relying site decide.
6.4 Root Directory
AgentPKI maintains a curated root directory at:
https://directory.agentpki.dev/v1/issuers.json
It is a signed JSON document listing T2 and T3 issuers, their fingerprints, and KYB metadata. The document is signed by the AgentPKI root key, whose public component is published at:
https://directory.agentpki.dev/v1/root-key.json
The root key is rotated on a published schedule with overlap; clients SHOULD pin the root public key but MUST support rotation via the published schedule. Compromise of the root key invalidates all T2/T3 trust and triggers an emergency rotation procedure (out of scope; documented separately at https://policy.agentpki.dev/root-compromise).
T1 issuers are not enumerated in the root directory; they self-attest via DNS and are accepted by verifiers configured to allow T1.
7. Wire Formats
The protocol defines two wire formats. Implementations MUST support both; relying sites select per-request which to accept via site policy.
7.1 Mode A — Bearer Header
The agent attaches the passport as a single HTTP header on outbound requests:
AgentPKI-Token: v4.public.eyJ2IjoxLCJpc3MiOiJhbn...kY=
The header name AgentPKI-Token is case-insensitive per RFC 7230. Tokens MUST NOT be split across multiple headers.
Mode A is simple but vulnerable to replay if the token is captured. It is RECOMMENDED for:
- Development and integration testing
- Low-stakes read-only requests
- Sites that already verify TLS pinning end-to-end
7.2 Mode B — HTTP Message Signatures (RFC 9421)
The agent signs each outbound request using HTTP Message Signatures, with the passport carried in the keyid parameter of the Signature-Input header.
Required:
Signature-Inputheader MUST cover at minimum:@method,@target-uri,content-digest(if body present), and@signature-paramsMUST includecreatedandexpiresparameters.keyidMUST be the full passport token.algMUST be"ed25519".- The signing key MUST match the public key bound to the passport’s
cnfclaim (§4.2.2). createdMUST be within ±60 seconds of the verifier’s clock;expiresMUST be ≤created + 300.
Example:
AgentPKI-Token: v4.public.eyJ2IjoxLCJp...
Content-Digest: sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:
Signature-Input: sig1=("@method" "@target-uri" "content-digest");\
created=1747857600;expires=1747857900;\
keyid="v4.public.eyJ2IjoxLCJp...";alg="ed25519"
Signature: sig1=:wqarAhRgT...:
The cnf claim in the passport payload binds the passport to a specific signing key:
"cnf": {
"jwk": {
"kty": "OKP",
"crv": "Ed25519",
"x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
}
}
Mode B is replay-resistant, MITM-resistant within the signed window, and is REQUIRED for:
- T3 (hardware-attested) issuance
- Capability scopes containing
purchase:,act:, oradmin:prefixes - Any relying site that declares
require_signed: truein site policy
7.3 Mode Selection
Relying sites communicate which mode(s) they accept via the Accept-AgentPKI response header on the first request (typically a 401 challenge):
HTTP/1.1 401 Unauthorized
Accept-AgentPKI: mode=A,B; min_tier=2; required_scopes="read:articles"
WWW-Authenticate: AgentPKI realm="reuters.com"
Agents SHOULD prefer Mode B when offered.
8. Verification
8.1 Verifier API
Verifiers expose a single endpoint:
POST /v1/verify
Content-Type: application/json
8.1.1 Request
{
"token": "v4.public.eyJ2IjoxLCJp...",
"mode": "B",
"request": {
"method": "GET",
"url": "https://reuters.com/api/article/123",
"body_sha256": null,
"signature_input": "sig1=...",
"signature": "sig1=:wqar...:",
"headers": {
"host": "reuters.com",
"content-digest": null
}
},
"site_policy": {
"min_tier": 2,
"required_scopes": ["read:articles"],
"max_abuse_score": 0.5,
"require_signed": false,
"allow_t1": false
}
}
modeMUST be"A"or"B". Verifier rejects mismatched modes per site policy.requestMUST be present whenmode = "B"; the verifier reconstructs the signature base per RFC 9421 and verifies.site_policyis OPTIONAL. If omitted, verifier returns a raw verdict without policy enforcement and lets the relying site evaluate.
8.1.2 Response
{
"verified": true,
"passport": {
"issuer": "anthropic.com",
"issuer_name": "Anthropic, PBC",
"agent_id": "agent:anthropic.com/research-bot-v3",
"scopes": ["read:articles", "read:public-data"],
"tier": 2,
"issued_at": 1747857600,
"expires_at": 1747861200,
"jti": "0e4f8a2c91b34e7b9c5d8a1e2f3b4c5d"
},
"abuse_score": 0.02,
"rate_limit": { "rpm": 60, "daily": 10000 },
"policy_match": {
"min_tier": true,
"scopes": true,
"abuse": true,
"signed_mode": true
},
"verdict": "allow",
"cached_until": 1747857720,
"verifier_id": "agentpki-edge-iad-7"
}
verdict MUST be one of: "allow", "throttle", "deny", "unknown". Semantics:
allow— passport valid, all policy gates passed.throttle— passport valid but abuse_score or rate context suggests rate-limiting.deny— verification failed OR policy gate failed.failure_reasonfield MUST be populated.unknown— verifier cannot resolve issuer within the SLA; relying site decides.
8.1.3 Error Response
On verification failure, the response MUST include:
{
"verified": false,
"verdict": "deny",
"failure_reason": "expired",
"failure_detail": "exp=1747861200 < now=1747861300",
"verifier_id": "agentpki-edge-iad-7"
}
Standard failure_reason values:
| Reason | Meaning |
|---|---|
malformed | Token did not parse as PASETO v4.public. |
bad_signature | Signature did not verify against any current issuer key. |
expired | exp < now. |
not_yet_valid | nbf > now. |
unknown_issuer | Issuer directory unreachable, malformed, or not present in root directory (when required). |
revoked | jti present in issuer’s CRL. |
revoked_key | Signing kid is in the issuer’s revoked_keys. |
tier_too_low | Passport tier below site’s min_tier. |
missing_scope | Required scope not present in scope claim. |
audience_mismatch | Site domain not in aud. |
signature_mode_required | Site requires Mode B; Mode A presented. |
signature_invalid | RFC 9421 signature failed verification. |
abuse_threshold_exceeded | Issuer’s or agent’s abuse_score above site’s max_abuse_score. |
replay_detected | jti seen recently with conflicting request hash. |
8.2 Edge Verification Procedure
Verifiers MUST execute the following steps in order. Each step’s failure produces the corresponding failure_reason.
1. Parse: decode PASETO v4 envelope; reject if malformed.
2. Extract footer.kid (if present) and payload.iss.
3. Resolve issuer:
a. Lookup issuer directory in edge cache.
b. If miss or stale, fetch /.well-known/agentpki-issuer.json.
c. Validate signed_by_root if site_policy requires T2+.
d. If unresolvable within SLA, return unknown_issuer.
4. Select pubkey:
a. If footer.kid present, look up by kid.
b. If kid in revoked_keys, return revoked_key.
c. Else iterate current_keys by valid_from desc.
5. Verify PASETO signature; reject if fails (bad_signature).
6. Verify temporal claims (iat, exp, nbf); reject if out of bounds.
7. Verify audience (aud) against site domain; reject if mismatch.
8. Check revocation list:
a. Edge bloom filter quick check; on positive, do authoritative lookup.
b. If jti in CRL, return revoked.
9. If mode = B:
a. Reconstruct RFC 9421 signature base from request fields.
b. Verify signature against cnf.jwk.
c. Verify created/expires within window.
d. Check replay cache for (jti, signature) tuple.
10. Apply site_policy gates: tier, scopes, abuse_score, signed mode.
11. Compute verdict, populate response.
12. Emit verification record to audit log (async).
Steps 1, 2, 5, 6, 9b, 9c MUST complete in constant time relative to secret-dependent inputs (timing-attack resistance).
8.3 Caching and SLA
Verifiers SHOULD cache verification results for up to min(exp - now, 60s) keyed on (jti, mode, request signature hash if B, site_policy hash). Cache hits MUST NOT bypass revocation checks; bloom-filter revocation lookup MUST occur on every request.
The verifier’s p99 latency target is 50ms for cache misses requiring a fresh issuer directory fetch, and 5ms for cache hits.
9. Capability Scoping
9.1 Scope Grammar
A scope is an ASCII string matching:
scope = action ":" resource [ ":" constraint ]
action = ALPHA *( ALPHA / DIGIT / "-" )
resource = ALPHA *( ALPHA / DIGIT / "-" / "/" / "*" )
constraint = 1*( ALPHA / DIGIT / "-" / ":" / "." / "*" )
The wildcard * matches any sub-resource at its position. Constraints are action-specific (see §9.2).
9.2 Standard Scope Vocabulary (v0.1)
The following prefixes are reserved by this specification. Issuers MAY define additional scopes under their own DNS-namespaced prefix (e.g., anthropic.com/internal/...).
| Prefix | Semantics | Example |
|---|---|---|
read: | Retrieve information without side effects. | read:articles, read:public-data, read:* |
write: | Create or modify content. | write:comments, write:reviews:1 |
purchase: | Initiate or commit to a financial transaction. Constraint REQUIRED. | purchase:up-to-100usd, purchase:up-to-50eur:per-day |
schedule: | Book, modify, or cancel calendar/appointment resources. | schedule:appointments, schedule:travel |
act: | Take action on behalf of a named principal. | act:on-behalf-of:user:u_abc123 |
admin: | Administrative actions on the agent’s own configuration. | admin:rotate-key |
9.3 Enforcement
Relying sites enumerate required scopes in site policy. The verifier returns policy_match.scopes = false and failure_reason = "missing_scope" if any required scope is not present in passport.scope. Exact string match is REQUIRED; wildcard expansion is the issuer’s responsibility (e.g., read:* matches all read: resources by issuer assertion, not by verifier inference).
Sites SHOULD require the most specific scope for the action being performed. purchase: scopes without a constraint MUST be rejected.
10. Revocation
10.1 Revocation List Format
Each issuer publishes a CRL at the URL declared in its directory document (crl_url). The CRL is a JSON document:
{
"v": 1,
"issuer": "anthropic.com",
"generated_at": 1747857600,
"next_update": 1747861200,
"revoked": [
{
"jti": "abc123...",
"revoked_at": 1747850000,
"reason": "suspected-compromise"
}
],
"signature": "v4.public.eyJ..."
}
next_updateMUST be ≤generated_at + 3600(CRL freshness max 1h).signatureMUST be a PASETO v4.public signature over the document (excluding the signature field) by the issuer’s current signing key.- The list MAY be sharded; if so,
revokedcontains pointers to shards viashard_url. Shard format is documented inhttps://spec.agentpki.dev/v0.1/crl-sharding.md.
10.2 Reasons
Standard reason codes:
| Code | Meaning |
|---|---|
suspected-compromise | Key or token material believed exposed. |
superseded | Replaced by a newer passport for the same agent. |
agent-decommissioned | Agent no longer in service. |
policy-violation | Passport revoked due to abuse or terms violation. |
scheduled-rotation | Routine rotation; not security-sensitive. |
other | Free-form reason MAY be supplied in reason_detail. |
10.3 Edge Distribution
Verifiers MUST maintain a Bloom filter built from the most recent CRL fetch per issuer, parameterized for ≤1% false-positive rate. On Bloom positive, the verifier MUST perform an authoritative lookup against the CRL before returning a verdict. Bloom filters MUST be rebuilt at least every 5 minutes.
For passport revocation with sub-second propagation, issuers MAY POST to:
POST https://verify.agentpki.dev/v1/revoke
Authorization: Bearer <issuer-api-key>
with { jti, reason }. The hosted AgentPKI verifier propagates this to all edge nodes within 5 seconds.
10.4 OCSP-Style On-Demand Check
Verifiers SHOULD support a probe endpoint for individual revocation lookups when the Bloom filter is unavailable:
GET https://<issuer-domain>/.well-known/agentpki-revoked/<jti>
200 { revoked: true, ... } or 404 indicates revocation status. Cacheable per Cache-Control.
11. Abuse Reporting
11.1 Submission
Any relying site or verifier MAY submit an abuse report:
POST https://<issuer-domain>/.well-known/agentpki-abuse
Content-Type: application/json
{
"v": 1,
"reporter": "reuters.com",
"passport_jti": "0e4f8a2c...",
"agent_id": "agent:anthropic.com/research-bot-v3",
"category": "rate-abuse",
"severity": "medium",
"occurred_at": 1747857600,
"evidence_urls": ["https://reuters.com/abuse-evidence/abc"],
"description": "Sustained 1000 rpm against /api/article, exceeding stated rate hint of 60 rpm.",
"requested_action": "warn"
}
Issuers MUST acknowledge with HTTP 202 within 5 seconds. Issuers SHOULD investigate within 24 hours for severity ≥ medium.
In parallel, reports MAY be POSTed to the AgentPKI aggregation endpoint:
POST https://abuse.agentpki.dev/v1/report
which aggregates across issuers and feeds the network-wide abuse_score.
11.2 Scoring
abuse_score is a float in [0.0, 1.0] returned by the verifier. The score is computed across:
- Per-passport recent reports (60% weight)
- Per-agent (
sub) historical reports (30% weight) - Per-issuer aggregate posture (10% weight)
Decay half-life: 14 days. Score is advisory; relying sites set their own thresholds via site_policy.max_abuse_score.
The exact scoring function is published at https://policy.agentpki.dev/abuse-scoring.md and is versioned independently.
12. Replay Protection
Mode A passports are bearer credentials and are subject to replay if intercepted. Verifiers SHOULD enforce per-jti rate limits but cannot detect replay across multiple verifiers without coordination.
Mode B passports are cryptographically bound to specific requests via RFC 9421. Verifiers MUST maintain a replay cache keyed on (jti, signature) for at least 300 seconds (matching the maximum signature expiry window). Cache hits with conflicting (method, url, body_sha256) MUST return replay_detected.
Sites requiring strong replay protection MUST require Mode B.
13. Bridges to Adjacent Protocols (Informative)
This section is informative; mappings are described separately in companion documents.
13.1 MCP
Anthropic Model Context Protocol [MCP] defines authentication between MCP clients and MCP servers. AgentPKI passports MAY be carried as the MCP authentication token. Mapping: passport sub ↔ MCP client identity, passport scope ↔ MCP capability negotiation.
13.2 Google A2A
Google Agent-to-Agent (A2A) defines identity for inter-agent calls. AgentPKI passports map onto A2A identity assertions; mapping documented at https://spec.agentpki.dev/v0.1/bridges/a2a.md.
13.3 Kite Agent Passport
Kite Agent Passport is a commerce-focused identity and settlement layer on Kite Chain. AgentPKI is complementary: Kite MAY accept an AgentPKI passport as proof-of-identity for the agent initiating a transaction. Mapping: passport sub and cnf ↔ Kite Passport principal; passport scope containing purchase: constraints ↔ Kite spending limits.
13.4 SPIFFE / SPIRE
SPIFFE [SPIFFE] handles internal workload identity within an organization. AgentPKI handles cross-organization (public-internet) identity. An agent MAY hold both: a SPIFFE SVID for internal calls and an AgentPKI passport for external calls. The two are not interchangeable.
13.5 OWASP ANS
OWASP Agent Name Service provides discovery (mapping human-readable agent names to endpoints + keys). AgentPKI provides authentication (proving the agent at an endpoint is who it claims to be). They are complementary; ANS records MAY embed AgentPKI issuer DNS names for trust resolution.
14. Credential Envelope (Forward-Compatibility for W3C VC)
This section defines an abstract envelope that allows future protocol versions to carry W3C Verifiable Credentials [VC-DATA-MODEL] without breaking changes.
In v0.1, the envelope is implicitly the PASETO v4.public token itself. v1.0+ MAY introduce an explicit envelope claim:
{
"v": 2,
"envelope": "vc-jwt",
"credential": "<W3C VC JWT>"
}
with envelope values registered in the IANA-style registry (§15).
Verifiers conforming to v0.1 MUST reject tokens with v > 1 rather than attempting to interpret them. This forward-rejection ensures clean version negotiation.
15. Registries
The following registries are maintained by the AgentPKI project at https://spec.agentpki.dev/registries/.
15.1 Claim Names
Initial registrations (this document): v, iss, sub, aud, iat, exp, nbf, jti, tier, scope, rate, cnf, ext.
New claim names: register via PR to the spec repo; require two implementations and 14-day review window.
15.2 Scope Prefixes
Initial registrations: read:, write:, purchase:, schedule:, act:, admin:. Issuer-namespaced scopes (<domain>/...) do not require registration.
15.3 Tier Identifiers
1, 2, 3 defined in §5.2. Reserved: 0 (unverified, for testing only, MUST NOT be used in production).
15.4 Revocation Reasons
Defined in §10.2.
15.5 Failure Reasons
Defined in §8.1.3.
15.6 Envelope Formats (v1.0+)
paseto-v4-public (implicit, v0.1), vc-jwt, vc-jwt-sd, cose-cwt are anticipated registrations; not yet allocated.
16. Security Considerations
16.1 Issuer Key Compromise
Compromise of an issuer’s signing key allows minting of arbitrary valid passports until detection and key revocation. Mitigations:
- Hardware-backed key storage (REQUIRED for all tiers).
- Frequent rotation (90-day RECOMMENDED).
- Real-time CRL distribution (§10.3).
- Compromised
kidpublished inrevoked_keys; all passports signed by thatkidMUST be rejected afterrevoked_at.
16.2 Root Key Compromise
Compromise of the AgentPKI root key invalidates the signed_by_root assertion across all T2/T3 issuers. The root key MUST be stored in an HSM with no internet-connected signing path; root signatures are produced via an offline ceremony. Compromise triggers the procedure documented at https://policy.agentpki.dev/root-compromise.
Clients SHOULD pin the root public key fingerprint and refresh via signed rotation announcements.
16.3 Token Theft (Mode A)
Mode A tokens are bearer credentials. Theft permits impersonation until expiry. Mitigations:
- Short lifetimes (≤ 5 min RECOMMENDED for high-value scopes).
- TLS pinning at the relying site.
- Site policy requiring Mode B for sensitive scopes.
16.4 Replay (Mode B)
Mode B mitigates replay via signed (method, url, body, created). Verifiers MUST maintain the replay cache of §12 to detect identical re-submissions within the signature window.
16.5 Verifier Impersonation
Relying sites contacting a malicious verifier could receive spoofed verdicts. Sites SHOULD pin the verifier’s TLS certificate fingerprint or use mTLS for verifier connections.
16.6 Issuer Directory Tampering
The directory document is fetched over HTTPS, and for T2+ is signed by the root. T1 issuers rely solely on HTTPS for integrity; compromise of the issuer’s web hosting permits passport-key substitution. T1 issuers SHOULD additionally serve the directory document with HTTP Expect-CT and consider SCT-pinning.
16.7 Audience Confusion
Tokens with aud: "*" may be presented to any site. Issuers SHOULD scope aud to the smallest set of intended audiences, especially for purchase: and act: scopes.
16.8 Side-Channel Resistance
PASETO v4 verification, RFC 9421 signature reconstruction, and jti lookup MUST execute in constant time with respect to secret inputs. Implementations SHOULD use vetted libraries (libsodium, Go’s crypto/ed25519, BoringSSL).
17. Privacy Considerations
17.1 Tracking
A persistent sub allows relying sites to track an agent across sessions. Issuers offering enhanced privacy MAY mint passports with rotating sub values; doing so weakens abuse reporting fidelity. The privacy/abuse tradeoff is the issuer’s policy choice; this spec does not mandate either direction.
17.2 PII Exposure
Passports MUST NOT contain personal data of the human acting through the agent. The act:on-behalf-of:user:<id> scope SHOULD use opaque identifiers, not email addresses or legal names. KYB metadata in the issuer directory is intentionally public (it’s the legal entity behind the issuer, not end-users).
17.3 Logging
Verifiers log every verification with jti, sub, iss, request URL host, and verdict. Logs MUST be retained for at least 90 days for audit; sites and issuers MAY request log extracts for incident response. Verifier operators MUST publish a privacy policy describing retention and access.
17.4 Cross-Verifier Correlation
If multiple verifiers (e.g., AgentPKI hosted + a bot-defense vendor’s own) verify the same passport, they may correlate via jti. This is by design (it enables abuse-score aggregation) but is a privacy consideration sites should disclose.
18. Versioning
- Major version (
v) increments on breaking changes. - Minor versions (documented in
https://spec.agentpki.dev/) MAY add OPTIONAL claims, scope prefixes, or failure reasons. - Verifiers MUST ignore unknown OPTIONAL claims and unknown failure-reason values they receive in upstream calls.
19. Conformance
A conforming verifier MUST:
- Implement §4 (parsing), §5.3 (key handling), §6 (issuer directory), §8 (verification), §10 (revocation), §16 (security).
- Pass the conformance test vectors at
https://spec.agentpki.dev/v0.1/test-vectors/.
A conforming issuer MUST:
- Implement §5 (issuance), §6 (directory), §10 (revocation list), §11 (abuse endpoint).
- Use Ed25519 signing keys stored in qualifying hardware (§5.3).
A conforming SDK (holder-side) MUST:
- Implement §7.1 (Mode A) and §7.2 (Mode B) on outbound HTTP.
- Auto-refresh passports per §5.5.
- Surface verifier error responses to the caller.
20. References
20.1 Normative
- [RFC 2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
- [RFC 8174] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, May 2017.
- [RFC 8032] Josefsson, S. and I. Liusvaara, “Edwards-Curve Digital Signature Algorithm (EdDSA)”, RFC 8032, January 2017.
- [RFC 8410] Josefsson, S. and J. Schaad, “Algorithm Identifiers for Ed25519, Ed448, X25519, and X448 for Use in the Internet X.509 Public Key Infrastructure”, RFC 8410, August 2018.
- [RFC 9421] Backman, A., Richer, J., and M. Sporny, “HTTP Message Signatures”, RFC 9421, February 2024.
- [PASETO] Paragon Initiative, “Platform-Agnostic Security Tokens”, https://github.com/paseto-standard/paseto-spec, Version 4.
20.2 Informative
- [MCP] Anthropic, “Model Context Protocol Specification”, https://modelcontextprotocol.io/specification.
- [A2A] Google, “Agent-to-Agent Protocol”, https://google.github.io/A2A/.
- [SPIFFE] SPIFFE Project, “Secure Production Identity Framework for Everyone”, https://spiffe.io/.
- [VC-DATA-MODEL] Sporny, M. et al., “Verifiable Credentials Data Model 2.0”, W3C Recommendation, May 2025.
- [ANS] OWASP Foundation, “Agent Name Service”, draft, 2026.
Appendix A: Example End-to-End Flow
Scenario: An Anthropic research agent fetches an article from Reuters.
-
Issuance. The agent calls Anthropic’s internal mint API and receives:
v4.public.eyJ2IjoxLCJpc3MiOiJhbnRocm9waWMuY29tIiwic3ViIjoiYWdlbnQ6YW50aHJvcGljLmNvbS9yZXNlYXJjaC1ib3QtdjMiLCJpYXQiOjE3NDc4NTc2MDAsImV4cCI6MTc0Nzg2MTIwMCwianRpIjoiMGU0ZjhhMmM5MWIzNGU3YjljNWQ4YTFlMmYzYjRjNWQiLCJ0aWVyIjoyLCJzY29wZSI6WyJyZWFkOmFydGljbGVzIl0sImNuZiI6eyJqd2siOnsia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiIxMXFZQVlLeENyZlZTXzdUeVdRSE9nN2hjdlBhcGlNbHJ3SWFhUGNIVVJvIn19fQ.SIGNATURE.eyJraWQiOiJhbnRocm9waWMtMjAyNi1xMiJ9 -
Discovery. The agent issues an unauthenticated GET to
https://reuters.com/api/article/123. Reuters responds:HTTP/1.1 401 Unauthorized Accept-AgentPKI: mode=A,B; min_tier=2; required_scopes="read:articles" WWW-Authenticate: AgentPKI realm="reuters.com" -
Retry with Mode B. The agent attaches the passport and signs the request:
GET /api/article/123 HTTP/1.1 Host: reuters.com AgentPKI-Token: v4.public.eyJ... Signature-Input: sig1=("@method" "@target-uri");\ created=1747857650;expires=1747857950;\ keyid="v4.public.eyJ...";alg="ed25519" Signature: sig1=:wqarAhRgT...: -
Verification. Reuters’ edge calls the verifier:
POST https://verify.agentpki.dev/v1/verify { "token": "v4.public.eyJ...", "mode": "B", "request": {...}, "site_policy": {...} }Verifier returns:
{ "verified": true, "verdict": "allow", "passport": { "tier": 2, "scopes": ["read:articles"], ... }, "abuse_score": 0.02, "policy_match": { "min_tier": true, "scopes": true, "abuse": true, "signed_mode": true }, "cached_until": 1747857710 } -
Service. Reuters returns the article.
Appendix B: Open Questions for v0.2
- Should the protocol support delegated minting (issuer A signs a sub-issuance authority to issuer B)?
- Should
cnfsupport post-quantum keys (e.g., ML-DSA) ahead of Ed25519 deprecation? - Should the abuse-reporting feedback loop be standardized for automated machine-to-machine submission, or remain a human-mediated path?
- Should there be a “soft revocation” tier (warn but don’t block) for issuer-suggested degradation?
- Should the spec define a
delegated_act:scope grammar for chain-of-agency cases (agent A invokes agent B which invokes agent C)?
Feedback on these and other questions: https://github.com/agentpki/spec/discussions.
End of AgentPKI Protocol v0.1.