The Handshake Protocol
0. Implementer's quickstart
Three steps. Five minutes from zero to a verifiable handshake. (Assumes you have an existing agent codebase you are wrapping.)
1. Install the SDK. Reference implementations are MIT-licensed.
# Python pip install handshake-sdk # TypeScript / Node npm install @handshake/sdk # Go go get github.com/handshake-protocol/handshake-go
2. Generate a deployer identity. One-time per organization. Store the private key in your KMS or HSM (see Implementation Guide for production patterns).
from handshake import Identity deployer = Identity.generate(kind="org", domain="acme.com") # prints: did:hsk:org:z6Mk… (Ed25519 keypair) deployer.save("./acme-deployer.key") # DO NOT COMMIT deployer.publish_did_document("./public/.well-known/did.json")
3. Wrap an agent call. Issue a delegation, perform a handshake, get a signed receipt.
from handshake import Identity, Agent, Capability deployer = Identity.load("./acme-deployer.key") agent = deployer.spawn_agent(model="claude-sonnet-4-5", instance="job-7f3a") # Issue a delegation from a user to this agent (in a real app, the user signs) delegation = deployer.delegate( to=agent, capabilities=[Capability("billing.invoices.read", max_invoices=100)], ttl_seconds=600, ) async with agent.handshake_with( service="https://billing.acme.com/mcp", capability="billing.invoices.read", delegation=delegation, ) as session: invoices = await session.call("invoices.list") receipt = session.receipt() # signed by the service assert receipt.verify() # Ed25519 over JCS-canonicalized JSON
What just happened: you generated an Ed25519 identity, signed a delegation token, sent a signed handshake message to a service, the service verified your delegation chain and accepted, executed the action, and returned a signed receipt that anyone with the service's public key can verify offline. The full algorithmic and cryptographic specification follows.
1. Status & change log
This is a working draft of the Handshake Protocol, published as part of the Early Access program. The protocol is not yet stable; minor versions in the v0.x series may include breaking changes. v1.0 stable freeze is targeted for 2027 ahead of IETF submission.
Implementers using v0.2.3 in production SHOULD coordinate with Handshake AI via spec@handshake.ai to receive deprecation notices and migration guidance.
Change log (recent):
- v0.2.3 (2026-04-29), Added explicit
aud(audience) binding to all signed messages. Added timing-attack resistance requirement (constant-time signature verification). Reorganized cryptographic profile (§6) to reference RFCs explicitly. - v0.2.2 (2026-04-12), Tightened JCS canonicalization requirement to MUST for all signed payloads. Clarified
delegablesemantics for sub-delegation. - v0.2.1 (2026-03-28), Added refusal signing requirement. Receipt result hash algorithm fixed to SHA-256.
- v0.2.0 (2026-03-15), First Early Access release. Renamed
scope.ttltoscope.ttl_secondsfor clarity. - v0.1.x (Q1 2026), Closed design-partner releases.
2. Abstract
The Handshake Protocol defines how AI agents establish verifiable trust with the services they interact with and with each other. It produces tamper-evident, signed records of who authorized what action, on whose authority, with what constraints, and what actually happened. Handshake is transport-agnostic and designed to compose with the agent communication protocols enterprises already use, MCP, A2A, OAuth 2.1, and AP2. It is built from boring, well-understood cryptographic primitives (Ed25519, SHA-256, JCS-canonicalized JSON, JOSE envelopes) chosen for shippability and security review survivability.
3. Conventions
The keywords 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, as shown here.
Defined terms:
- Principal. Any entity identified by a Handshake DID. Includes users, agents, services, and organizations.
- Agent. An autonomous or semi-autonomous AI system that takes action on behalf of a principal.
- Service. Any system that exposes capabilities for agents to invoke.
- Deployer. The organizational principal responsible for an agent's deployment, code, and policy posture.
- Capability. A namespaced, typed identifier for a specific action a service offers, with optional typed constraints.
- Delegation. A signed assertion by a granting principal that a receiving principal may exercise specified capabilities.
- Handshake. The signed message exchange in which an agent presents a delegation chain and a service accepts or refuses to execute the requested action.
- Receipt. A signed assertion by a service of what action was executed, with what result, under what authorizing handshake.
- Registry. An optional tamper-evident log to which receipts may be anchored for additional verification guarantees.
4. Architecture
A Handshake interaction involves four roles. Each role's identity is independently verifiable against its DID Document.
Principal (User/Org)
| signs DelegationToken[A] ---> gives Agent A authority over Capability X
v
Agent A
| signs HandshakeRequest ---> presents identity + chain + scope
v
Service S
| verifies signatures, walks chain, checks scope
| (refuses + signs RefusalNotice on failure)
| executes action
v
Receipt (signed by S)
| optionally anchored to Registry
v
Verifier (anyone with public keys)
verifies signatures + Merkle inclusion + chain
Three properties are load-bearing:
- Verification is stateless and offline-capable. A verifier needs only the relevant public keys; no central lookup is required to validate a receipt.
- The Registry is optional. It provides additional tamper-evidence (Certificate-Transparency-style) but signed receipts are independently verifiable without it.
- Delegation is attenuating. No principal in a chain can grant authority it does not itself hold.
5. Identifiers, the did:hsk method
Every Handshake principal is identified by a Decentralized Identifier (DID) under the did:hsk method. This method conforms to W3C DID Core 1.0.
Format: did:hsk:<type>:<identifier>
did:hsk:user:<handle>, a human principal (typicallyhandle= email or OIDC subject identifier)did:hsk:agent:<multibase-pubkey-hash>, an agent instance, identifier MUST be base58btc-encoded SHA-256 of the agent's Ed25519 public keydid:hsk:svc:<multibase-pubkey-hash>, a service or tool endpoint, same encoding as agentdid:hsk:org:<multibase-pubkey-hash>, an organizational principal (deployer)
5.1 DID resolution
DID resolution MUST proceed by one of two mechanisms:
- Well-known HTTPS resolution. If the principal type is
org, the DID Document MAY be fetched athttps://<domain>/.well-known/handshake/did.json. The connection MUST use TLS 1.3 or later. - Registry resolution. A Handshake Registry MAY publish DID Documents for principals it has observed. Registry-resolved DID Documents MUST include the Registry's signature alongside the principal's.
5.2 DID Document structure
A Handshake DID Document conforms to the W3C DID Core JSON-LD representation and MUST include:
id, the DIDverificationMethod, at least one Ed25519 public key in JWK format (per RFC 8037)authentication, references to verification methods authorized for signinghandshake:credentials(extension), Verifiable Credentials issued by the deployer attesting to model, code hash, deployment environmenthandshake:revocation(extension), endpoint URI for revocation list lookup
5.3 Key rotation
DID Documents are versioned. Key rotation produces a new DID Document with an incremented versionId. The new document MUST be signed by the previous version's authentication key. Verifiers MUST accept signatures from any historical key version when validating receipts whose signing time falls within that version's validity window.
6. Cryptographic profile
All choices are deliberately conservative. No novel cryptography. Boring, well-understood primitives chosen for shippability and adversarial review survivability.
6.1 Signing algorithms
- Ed25519 (per RFC 8032), REQUIRED in v0.2.x. Pure EdDSA over edwards25519 with SHA-512.
- ML-DSA-65 (per FIPS 204), RECOMMENDED for negotiation in v0.3+. Post-quantum signature scheme.
- Hybrid signatures. v0.3 will define a hybrid Ed25519 + ML-DSA-65 mode for transition. Receivers compliant with hybrid MUST verify both signatures.
6.2 Hashing
- SHA-256 (per FIPS 180-4), REQUIRED for all hashing operations (result hashes, Merkle nodes, key fingerprints).
- SHA3-256 (per FIPS 202), OPTIONAL alternative for receipts where SHA-3 is preferred for organizational policy reasons. Receipts MUST declare hash algorithm in the
algfield.
6.3 Canonicalization (CRITICAL)
All signed payloads MUST be canonicalized using JSON Canonicalization Scheme (JCS) per RFC 8785 before signing or signature verification.
handshake_sdk.canonicalize.jcs(obj).
6.4 Encoding
- Binary fields (signatures, key hashes, nonces): base64url per RFC 4648 §5, no padding.
- Multibase identifiers (DIDs, key hashes): base58btc with leading
zprefix per multibase spec. - Timestamps: RFC 3339 with mandatory timezone offset (UTC
ZRECOMMENDED).
6.5 Random number generation
Nonces and ephemeral key generation MUST use a cryptographically secure random source. Implementations SHOULD follow the recommendations in RFC 8937 for combining randomness sources where the platform RNG strength is uncertain.
6.6 Constant-time operations
Signature verification implementations SHOULD use constant-time primitives to resist timing-attack-based key recovery. Use vetted libraries (libsodium, Tink, Noble) rather than implementing Ed25519 directly.
6.7 Audience binding
Every signed message MUST include an aud (audience) field naming the intended verifier's DID. Receivers MUST reject messages where aud does not match their own DID. This prevents valid signatures from being replayed against unintended audiences.
7. Cryptographic operations, where the crypto lives
This section enumerates every cryptographic operation the protocol performs. For implementers, security reviewers, and auditors: this is the complete map of where crypto happens, what it operates on, and what algorithm is used.
| Operation | Algorithm | Input (canonicalized) | Verifiable by |
|---|---|---|---|
| Identity creation | Ed25519 keygen | CSPRNG output | (self) |
| DID Document signing | Ed25519 sign + JCS | DIDDocument JSON | Any resolver |
| Delegation issuance | Ed25519 sign + JCS | DelegationToken JSON | Recipient + chain validators |
| Handshake signing | Ed25519 sign + JCS | HandshakeRequest JSON | Receiving service |
| Handshake verification | Ed25519 verify + JCS + chain walk | Request + chain | (verifier itself) |
| Refusal signing | Ed25519 sign + JCS | RefusalNotice JSON | Initiator + auditors |
| Result hashing | SHA-256 | Canonicalized result body | Anyone |
| Receipt signing | Ed25519 sign + JCS | Receipt JSON | Anyone with svc public key |
| Registry anchoring | SHA-256 + Merkle | Receipt hash + tree | Anyone with tree root |
| Inclusion proof | Merkle path | Path siblings | Anyone |
| Key rotation | Ed25519 sign (old key) | New DIDDocument | DID resolvers |
| Revocation | Ed25519 sign + JCS | RevocationStatement JSON | Verifiers checking chain |
Every operation in this table SHOULD use a vetted cryptographic library (libsodium, Tink, Noble Crypto, BoringSSL) rather than custom code. Implementations MUST NOT implement Ed25519 from scratch.
8. Message formats
All messages are JSON objects, JCS-canonicalized for signing per §6.3. JSON Schemas for every message type are published at github.com/handshake-protocol/spec/schemas/v0.2.3/. The schemas are normative; the prose in this document is informative.
8.1 DelegationToken
A DelegationToken is a signed assertion by a granting principal that a receiving principal may exercise specified capabilities under specified constraints during a specified time window.
{ "version": "0.2.3", "kind": "DelegationToken", "id": "dt_01HK4ZQ7M3X9R5N2P8V0YJF7B3", "iss": "did:hsk:user:bob@acme.com", // granter "sub": "did:hsk:agent:z6MkfTr3…", // recipient "aud": "did:hsk:agent:z6MkfTr3…", // audience binding "iat": "2026-04-29T14:02:11Z", "nbf": "2026-04-29T14:02:11Z", "exp": "2026-04-29T14:12:11Z", // 600s TTL "capabilities": [ { "name": "billing.invoices.read", "constraints": { "max_invoices": 100, "date_range": ["2026-01-01", "2026-04-29"] }, "delegable": false // no sub-delegation } ], "sub_delegation_depth_remaining": 0, "alg": "EdDSA", "signature": "r3vK7pQ9…" // base64url }
8.2 HandshakeRequest
A HandshakeRequest is the message an agent sends to a service before performing an action. It includes the agent's identity, the requested capability, the delegation chain proving authority, and a nonce for replay protection.
{ "version": "0.2.3", "kind": "HandshakeRequest", "id": "hs_01HK4ZQ8N4Y0S6P3Q9W1ZK8C4", "iss": "did:hsk:agent:z6MkfTr3…", "aud": "did:hsk:svc:z6MkmW9…", // audience binding "iat": "2026-04-29T14:14:32Z", "nonce": "k7nQ9pX3vR2…", // 128-bit, base64url "agent_attestation": { "deployer": "did:hsk:org:z6MkqA1…", "model": "claude-sonnet-4-5", "instance_id": "job-7f3a", "code_hash": { "alg": "sha-256", "value": "e3b0c44…" } }, "capability": { "name": "billing.invoices.read", "constraints": { "max_invoices": 100 } }, "delegation_chain": [ // One or more DelegationTokens, ordered root → leaf /* full DelegationToken object, see §8.1 for schema */ ], "alg": "EdDSA", "signature": "x9pV4qR8…" }
8.3 HandshakeResponse, Acceptance
On successful verification, the service signs and returns an Acceptance bound to the request.
{ "version": "0.2.3", "kind": "Acceptance", "request_id": "hs_01HK4ZQ8N4Y0S6P3Q9W1ZK8C4", "iss": "did:hsk:svc:z6MkmW9…", "aud": "did:hsk:agent:z6MkfTr3…", "iat": "2026-04-29T14:14:33Z", "effective_scope": { "capability": "billing.invoices.read", "constraints": { "max_invoices": 100 } // after intersection }, "alg": "EdDSA", "signature": "a4nT8qZ2…" }
8.4 HandshakeResponse, Refusal
On verification failure, the service signs and returns a Refusal with a typed reason. Refusals are themselves auditable.
{ "version": "0.2.3", "kind": "Refusal", "request_id": "hs_01HK4ZQ8N4Y0S6P3Q9W1ZK8C4", "iss": "did:hsk:svc:z6MkmW9…", "aud": "did:hsk:agent:z6MkfTr3…", "iat": "2026-04-29T14:14:33Z", "reason": { "code": "scope_exceeded", // see §14 "detail": "Requested 500 invoices; delegation max is 100" }, "alg": "EdDSA", "signature": "b5oU9rA3…" }
8.5 Receipt
After the action executes, the service produces a signed receipt.
{ "version": "0.2.3", "kind": "Receipt", "id": "rc_01HK4ZQ9P5Z1T7Q4R0X2AL9D5", "handshake_id": "hs_01HK4ZQ8N4Y0S6P3Q9W1ZK8C4", "iss": "did:hsk:svc:z6MkmW9…", "sub": "did:hsk:agent:z6MkfTr3…", "action": "billing.invoices.read", "executed_at": "2026-04-29T14:14:35Z", "result": "ok", // ok | error | partial "result_hash": { "alg": "sha-256", "value": "f3a2c8e1…" // hex of canonicalized result }, "upstream_receipts": [], // for receipt-graph composition "alg": "EdDSA", "signature": "c6pV0sB4…" }
9. Wire flows
Three reference flows. Each is a complete, implementable interaction. Conformance test vectors for each are published at github.com/handshake-protocol/spec/test-vectors/v0.2.3/.
9.1 Cold handshake (full chain walk)
- Agent constructs a HandshakeRequest, including the full delegation chain.
- Agent signs the request (Ed25519 over JCS-canonicalized payload).
- Agent transmits the request to the service over the underlying transport (HTTPS, MCP, A2A, etc.).
- Service verifies the request signature using the agent's public key (resolved from the agent's DID).
- Service walks the delegation chain root → leaf, verifying each link's signature.
- Service computes the effective scope (intersection of all delegation scopes).
- Service checks the requested capability falls within effective scope.
- Service signs and returns an Acceptance, OR signs and returns a Refusal.
- If accepted, service executes the action.
- Service computes
result_hash = SHA-256(JCS(result)). - Service constructs and signs a Receipt.
- Service returns the Receipt to the agent and (optionally) anchors it to the Registry.
9.2 Warm handshake (cached delegation)
For agents holding session state with a service, repeated handshakes within a TTL window MAY use a session cache to skip full chain walk. The agent presents only a session token (issued in the prior Acceptance) plus a fresh nonce. Cache TTL is set by the service in the Acceptance.
9.3 Multi-step delegation (sub-delegation)
When agent A delegates to sub-agent B, the chain extends: User → A → B. B presents both delegations in the chain to the service. Sub-delegation requires the parent delegation's delegable: true flag and decrements sub_delegation_depth_remaining.
10. Capability semantics
Format. Capabilities are dotted lowercase ASCII strings. Reverse-domain or service-rooted naming is RECOMMENDED: billing.invoices.read, email.send, files.write:/projects/*, pay.transfer:bank.acme.
Reserved namespaces. The handshake.* namespace is reserved for protocol use. The x.* namespace is reserved for experimental extensions. Implementations MUST NOT use either for production capabilities.
Discovery. Services SHOULD publish their capability schemas at https://<service>/.well-known/handshake/capabilities.json, listing each capability with its constraint schema and human-readable description.
Constraint typing. Constraints are typed JSON values. Standard constraint types defined in v0.2.3:
numeric_max/numeric_min, bounds on integer or decimal valuesstring_pattern, regex matching (RE2 syntax, anchored)enum, allow-list of permissible valuestime_window, RFC 3339 [start, end] inclusive rangerate_limit, operations per time windowresource_path, Unix-glob matching for resource identifiers
Constraint algebra. When delegations chain, constraints intersect. Numeric maxes use the lower bound; numeric mins use the upper bound; enums and patterns intersect set-theoretically; time windows intersect to the overlap. The receiving service MUST reject any handshake whose requested constraints exceed the chain-intersected effective scope.
11. Delegation chain semantics
Attenuating principle. A child delegation's effective scope is the intersection of its declared scope and its parent's scope. No child can broaden its parent's scope. This MUST be enforced by every verifier, the service does not need to trust intermediate principals for this property to hold.
Validation algorithm.
- Verify each delegation's signature against the issuer's resolved DID.
- Verify each delegation's
iat≤now≤exp. - Verify each delegation's
audmatches the next delegation'siss(or, for the leaf, the request'siss). - Verify each delegation's
isshas not been revoked (consulthandshake:revocationendpoint). - Compute effective scope as the intersection of all delegations.
- Verify the request's capability and constraints fall within effective scope.
Sub-delegation. A delegation MAY be sub-delegated only if its delegable flag is true AND the granting delegation has sub_delegation_depth_remaining > 0. Each sub-delegation decrements the depth counter. This bounds the maximum chain length and prevents unbounded delegation trees.
Revocation. A principal MAY revoke a delegation it issued by publishing a signed RevocationStatement at its handshake:revocation endpoint. Verifiers SHOULD check the revocation list before accepting any handshake. Revocation propagation latency is implementation-defined; design partners targeting sub-second revocation should consult the Implementation Guide.
12. Receipt structure
Receipts are the protocol's evidence layer. Each receipt is a tamper-evident assertion that this service executed this action under this handshake at this time, producing a result whose hash is X.
Required fields: see §8.5. Receipts MUST be signed by the executing service.
Result hashing. The result_hash field commits to the action's output without revealing it. Compute as SHA-256(JCS(result)). This allows verifiers to confirm result integrity later by re-canonicalizing the result and comparing hashes.
Receipt graph. Receipts MAY reference upstream receipts via upstream_receipts, forming a DAG. This is critical for multi-step workflows: verifiers can trace the full causal chain back to the root delegation.
Anchoring. Receipts MAY be persisted to a Handshake Registry. The Registry SHOULD implement an append-only Merkle tree (Trillian-compatible), publishing tree roots periodically. Inclusion proofs are O(log n) hash operations. Verifiers can cross-check receipt integrity against the published tree root without trusting the Registry operator.
13. Composition with existing protocols
Handshake is designed to wrap, not replace.
13.1 Model Context Protocol (MCP)
The HandshakeRequest is sent as an MCP request-level extension before the first tools/call. The capability namespace mirrors the MCP tool schema. Receipts are produced for every tool invocation. Reference middleware: handshake-mcp (Python, TypeScript). Wire-level integration documented in schemas/v0.2.3/composition/mcp.md.
13.2 Agent2Agent (A2A)
Handshake provides A2A's deferred trust layer. The HandshakeRequest envelope is included in the A2A negotiation phase; receipts tie to A2A task identifiers. Reference integration documented in schemas/v0.2.3/composition/a2a.md.
13.3 OAuth 2.1
OAuth bootstraps user delegation. The OAuth access token, after introspection, is converted into a signed Handshake DelegationToken at the agent boundary. The OAuth scope set maps onto Handshake capabilities via a published mapping. Reference: handshake-oauth-bridge.
13.4 Agent Payments Protocol (AP2)
Handshake receipts serve as the attestation layer for AP2 mandates. Every payment-related action produces a receipt that can be presented for dispute resolution and reconciliation. Receipts MAY include AP2-specific extension fields documented in schemas/v0.2.3/composition/ap2.md.
14. Error handling, typed reason codes
Refusals MUST include a typed code. Implementations MUST use the codes below. Custom codes MUST be prefixed x-.
| Code | Meaning | Retry semantics |
|---|---|---|
signature_invalid | A signature in the request or chain failed verification | Do not retry; investigate |
chain_broken | The delegation chain does not terminate at a trusted principal | Do not retry |
scope_exceeded | Requested capability or constraints exceed effective scope | Do not retry; request narrower scope |
credential_revoked | A delegation in the chain has been revoked | Do not retry; obtain fresh delegation |
expired | A delegation in the chain is past its exp | Do not retry; obtain fresh delegation |
not_yet_valid | A delegation's nbf is in the future (clock skew?) | May retry after sync |
replay_detected | The request nonce has already been seen | Do not retry; generate fresh nonce |
aud_mismatch | The aud field does not match the receiving service's DID | Do not retry |
policy_denied | The service's local policy denies the action even within scope | Do not retry |
service_unavailable | The service is temporarily unable to verify or execute | Retry with backoff |
rate_limited | The agent or deployer has exceeded a rate limit | Retry after Retry-After |
protocol_version_unsupported | The protocol version in the request is unsupported | Do not retry; downgrade |
15. Versioning policy
Handshake follows semantic versioning per SemVer 2.0.0.
- Patch versions (v0.x.Y) include only clarifications, editorial fixes, and additive constraints that do not affect interoperability.
- Minor versions (v0.X.0) in the v0.x series MAY include breaking wire-level changes. Each minor version transition will publish a migration guide.
- Major versions (vX.0.0) at v1.0+ MUST be backwards-compatible at the wire level. Breaking changes require a major bump.
- Forward compatibility. Receivers MUST tolerate unknown OPTIONAL fields and MUST reject unknown REQUIRED fields with
protocol_version_unsupported. - Deprecation. Fields and codes deprecated in version v(X+1).y will be removed no earlier than v(X+3).0 (two minor versions of overlap).
16. Conformance
Implementations MAY claim one of three conformance levels:
- Core. Implements §5–8 (identity, crypto, message formats), §11 (delegation), §12 (receipts), §14 (errors), and passes the Core test vectors.
- Extended. Core + §10 constraint algebra, §13 composition with at least one of (MCP, A2A, OAuth 2.1, AP2), and the Extended test vectors.
- Sovereign. Extended + self-hosted Registry support, BYO-anchor capability, formal HSM-backed key management, and the Sovereign test vectors.
Test vectors are published at github.com/handshake-protocol/spec/test-vectors/v0.2.3/ under CC BY 4.0. Implementations claiming a level MUST pass all test vectors at that level.
17. Security considerations
Threat model. We assume any single agent in a delegation chain may be compromised, by prompt injection, supply-chain attack, or insider action. Handshake provides defense-in-depth via:
- Attenuating delegation (no agent can expand its scope)
- Short-lived credentials (recommended TTL ≤ 600 seconds)
- Audience binding (signed messages cannot be replayed across services)
- Nonce-based replay protection (services MUST track recent nonces within the TTL window)
- Tamper-evident audit (Merkle-anchored receipts cannot be retroactively altered)
- Sub-second revocation (versioned DID Documents + revocation endpoint polling)
Specific attacks and mitigations.
- Replay. Nonces + TTL window. Services MUST reject duplicate nonces within window.
- Audience confusion. Audience binding (
audfield) per §6.7. Receivers MUST verifyaud. - Chain forgery. Each link signed; chain walk validates each signature and audience binding.
- Key compromise. Versioned DID Documents enable rotation; revocation lists invalidate compromised keys; HSM-backed keys (Implementation Guide) reduce exfiltration risk.
- Side channels. Constant-time signature verification (use vetted libraries, see §6.6).
- Quantum. Migration to ML-DSA-65 begins in v0.3 with hybrid signatures.
Out of scope (not defended against). Handshake does not defend against a compromised root principal authorizing malicious actions, services misbehaving outside their receipted action, social-engineering attacks against principals, or attacks on the underlying transport layer. It provides accountability, not omniscience.
Implementation pitfalls. See the Implementation Guide for detailed deployment-side guidance on key management, performance optimization, and Registry topology. Common errors specific to v0.2.3 include: failing to canonicalize JSON before signing (§6.3), failing to verify audience binding, accepting handshakes without checking nonce uniqueness, and storing private keys in agent-process memory.
18. Privacy considerations
Receipts contain principal DIDs, capability invocations, and result hashes. They do not by default contain action payloads or principal-identifying personal data. Implementations MUST NOT include personal data (names, emails, account contents) in receipt fields.
Anchored-not-revealed. When anchored to a Registry, receipts contribute their hash to the Merkle tree. The receipt content itself is stored separately (in customer-controlled storage, by default). This means the Registry contains commitments to receipts but not the receipts themselves. Public Registry tree roots reveal receipt counts but not contents.
GDPR / CCPA. Receipts contain pseudonymous identifiers (DIDs) and timestamps. Linkage to natural persons requires the issuing organization's records. Right-to-erasure considerations: signed receipts cannot be modified once issued, but customer-controlled storage MAY be purged. The Registry retains only commitments, which carry no personal data.
Public Registry implications. Anchoring to a public Registry reveals: that some action took place at some time, attributable to some principal-set known to the Registry operator. It does not reveal action content. Customers requiring stronger privacy guarantees SHOULD use a self-hosted Registry or BYO-anchor mode.
19. What is not in this specification
The following are deliberately omitted from the public spec. They are documented in the Handshake Implementation Guide, available to design partners and Working Group members under NDA.
- Key management deployment patterns. HSM integration (CloudHSM, Vault, Thales, YubiHSM); ephemeral session key lifecycle; sidecar architectures for serverless agents; multi-region key distribution; key compromise response runbooks.
- Performance optimization playbook. Hot-path verification techniques; delegation chain caching strategies; public-key DNS distribution; signature batching for receipt anchoring; benchmark methodology and current numbers.
- Registry implementation topology. PostgreSQL schema and indexes; sharding strategy by deployer; multi-region active-active patterns; receipt blob storage at scale; backup and restore.
- Console implementation patterns. Audit report generation pipeline; workflow engine architecture; declarative policy compilation.
- Compliance implementation guidance. SOC2 Type II evidence collection patterns; EU AI Act mapping; HIPAA business associate program; PCI-DSS scope reduction.
- Customer integration patterns. Reference architectures by industry; 4-week onboarding playbook.
- Architectural trade-offs and decision rationale. Why these specific cryptographic choices; why these specific data-model decisions; what we considered and rejected.
- Pre-release roadmap detail. v0.3 → v1.0 detailed feature list and timing.
To request the Implementation Guide, contact partners@handshake.ai. Access requires a mutual NDA.
20. References
Normative.
- RFC 2119 / RFC 8174, Key words for use in RFCs to indicate requirement levels
- RFC 3339, Date and Time on the Internet: Timestamps
- RFC 4648, The Base16, Base32, and Base64 Data Encodings
- RFC 8032, Edwards-Curve Digital Signature Algorithm (EdDSA)
- RFC 8037, CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)
- RFC 8785, JSON Canonicalization Scheme (JCS)
- RFC 8937, Randomness Improvements for Security Protocols
- FIPS 180-4, Secure Hash Standard (SHA-256)
- FIPS 202, SHA-3 Standard
- FIPS 204, Module-Lattice-Based Digital Signature Standard (ML-DSA)
- W3C DID Core 1.0
- W3C Verifiable Credentials Data Model 2.0
- SemVer 2.0.0
Informative.
- RFC 9162, Certificate Transparency Version 2.0
- Model Context Protocol Specification (Anthropic)
- Agent2Agent Protocol (Google)
- Agent Payments Protocol AP2 (Visa, Mastercard)
- OAuth 2.1 Authorization Framework (draft)
- NIST AI Risk Management Framework
- EU Artificial Intelligence Act
Comments and proposals: spec@handshake.ai. Spec source: github.com/handshake-protocol/spec. Conformance test vectors: github.com/handshake-protocol/spec/test-vectors/v0.2.3. Implementation Guide (NDA): partners@handshake.ai.