Skip to main content

Protocol implementation status

Target: PAP draft 0.1, updated October 9, 2026, and the Operations extension version 1 (see Compatibility).

AreaStatus
Discovery document and OAuth metadataImplemented in Python and TypeScript
Client metadata, conversation-event, and Operations wire modelsImplemented in Python and TypeScript with shared fixtures
Domain and issuer bindingImplemented in Python and TypeScript
Duplicate JSON member rejectionImplemented at Python and TypeScript trust boundaries
Client metadata validationImplemented in Python and TypeScript
Client metadata and public JWKS retrievalImplemented in Python and TypeScript with Reactor safety policies
Pairwise user IDs and session wire primitivesImplemented in Python and TypeScript
Signed-out session start and renewal over HTTPImplemented in Python and TypeScript; host signer and DPoP provider required
Direct Sign-In state, S256 PKCE, callback validation, and exchange grantImplemented in Python and TypeScript
Reactor clock, randomness, signer, DPoP proof, token, cache, browser, Account Token lock, protected input, standing permission, and company contracts (Contribution points)Implemented and lifecycle-tested in Python and TypeScript
ES256/RS256 assertion signingImplemented in Python and TypeScript
DPoP proof creation and verificationImplemented in Python and TypeScript; host key resolver and replay cache required
DPoP-aware API/conversation HTTP transportImplemented in Python and TypeScript with nonce retry and same-origin redirect proof rebinding
Conversation creation, continuation, and ordered JSON event readsImplemented in Python and TypeScript with long polling, backlog draining, cursor recovery, and duplicate suppression
Direct Sign-In browser handoff and token exchangeImplemented in Python and TypeScript; host state, browser, signer, and DPoP providers required
Browser Session assertion, controlled form POST, and verificationImplemented in Python and TypeScript; host signer/form-post and company replay cache required
Device Sign-InImplemented in Python and TypeScript; host state store, signer, and DPoP provider required
Mediated Sign-InImplemented in Python and TypeScript; credentials only through the host's pap.protectedInput, one endpoint on the company's domain, no redirects, one-time code from the same Session
Account Token refresh, rotation, narrowing, and revocationImplemented in Python and TypeScript; rotation serialized by pap.accountTokenLock, invalid_grant signs out, wider scopes are re_consent_required
OpenAPI and MCP clientsImplemented in Python and TypeScript: ApiClient (DPoP, 202 operations, scope-carrying refusals) and McpClient/McpBearerAuth with a resource-bound Bearer token from bearer_for_mcp/bearerForMcp, sent only to its MCP server's exact URL
Conversation SSE streaming, handoff, Direct Conversations, sign-in mid-conversation, and active closeImplemented in Python and TypeScript: Last-Event-ID reconnects, display-only text deltas, discarded partial messages, direct_conversation_open details
Operations v1Client implemented in Python and TypeScript: negotiation, exact approval (revision + digest), terms_changed, recovery after a lost confirm, cancel, extension_required, and standing permissions through pap.standingPermissionStore; company handlers in both reference companies
Extensible pap CLIReactor host/plugin, non-secret profiles, company discovery, agent identity/JWKS inspection, extension diagnostics, and live discovery command implemented
Generated API referencesPython and TypeScript public exports inventoried; documentation CI rejects stale pages
Company/server SDKReference companies in Python (personal_agent_protocol.company, over ASGI) and TypeScript (@datalayer/personal-agent-protocol/server, over node:http(s)), every replaceable part a Reactor point; both serve MCP and, with web, browser sessions and operation pages
Demo worlds and end-to-end journeysPython (personal_agent_protocol.demo): a user with a company (Manzanita) and two companies composed (Ledgerly at Northwind); TypeScript: Manzanita; real keys over in-process HTTP or TLS

Supported package line​

The supported SDK versions, the draft and Operations version each implements, and the four language pairings are on the Compatibility page; the Support page says which versions get fixes.

Known gaps​

  • Python pins metadata connections to the addresses its URL safety policy approved (PinnedNetworkBackend), closing the DNS-rebinding interval. Node rejects non-public DNS results before metadata requests, but its default transport does not yet pin the socket: production Node deployments need an enforcing egress proxy to fully close the interval.
  • Pairwise ID generation and a file-backed atomic Python reference store are implemented. Distributed deployments must contribute their own transactional pap.pairwiseUserIdStore and own retention and erasure policy.
  • Python and TypeScript Direct Sign-In perform trusted browser handoff, atomic one-use state consumption, exact callback validation, fresh assertion/DPoP exchange, one nonce retry, and partial-scope reporting. Hosts still provide the authorization-state store, browser surface, signer, and DPoP key custody.
  • Session clients sign fresh claims, create a DPoP proof, and send the token request. Local JOSE implementations are available, but applications still own key selection and custody.
  • Security contribution contracts exist, but the SDK deliberately ships no default signer, DPoP key custody, durable replay cache, token store, browser handoff, or browser form-post surface.
  • Browser Session clients sign the distinct poppy-browser+jwt assertion and submit it through pap.browserFormPost; company verification enforces the endpoint, Session owner, 60-second lifetime, company-domain return target, and one-use jti. Company adapters still own cookie creation and must bind cookie state and lifetime to the underlying PAP Session.
  • DPoP resource clients own authorization headers, create a fresh proof for every attempt, retry one nonce challenge, and refuse cross-origin credential forwarding. The Account Token lifecycle and resource-bound MCP Bearer acquisition on top of it are implemented in both SDKs.
  • Conversation clients (messages, JSON events, SSE, handoff, Direct Conversations, closing), Account Tokens, Mediated Sign-In, and the Operations client are aligned in Python and TypeScript, and so are the two reference companies; all four language pairings pass every conformance case.
  • The reference company keeps state in one process by default. Production companies contribute a durable pap.company.store (an async keyed store with create, take, and compare-and-set, checked by check_store) over which a restarted or replaced company continues every flow, a distributed pap.company.replayCache, their account directory, agent, and idempotent operation executors.
  • The SDK ships an in-memory standing permission store for examples and tests only. Hosts contribute a durable, atomic pap.standingPermissionStore and their own interface for granting permissions.
  • The CLI does not expose auth, session, conversation, Operations, or conformance workflows until their service and protected-store boundaries are implemented.

The machine-readable requirement ledger lives in protocol/requirements.yaml.

PAP itself still leaves payments, push notifications, and message attachments as open topics. See Open topics and SDK gaps before designing private extensions or interpreting an unimplemented SDK service as an omission from the protocol.