v0.1.0 Open Source

Principal
Agent
Protocol

Every agent protocol in production today was designed to serve platform operators, not human principals. PAP fixes the root cause — cryptographically.

9
Crates (Rust + Python)
8
Working Examples
0
New Primitives
MIT
License
Trust Hierarchy
Human Principal
Device-bound keypair · Root of trust · WebAuthn
Orchestrator Agent
Root mandate · Full principal context · Signs sub-mandates
Downstream Agents
Scoped task mandates · TTL bounded · Scope ≤ parent
Marketplace Agents
Own principal chains · Federated discovery
// Transactions are handshakes between
// two mandate chains, not two agents.
5 constraints · enforced at protocol level

Your agents are leaking
everything about you

AI agents make hundreds of queries on your behalf — each one leaking context to platforms that build profiles, adjust prices, and sell your behavioral data to brokers you've never heard of.

You searched for a stroller once. Now every website thinks you're pregnant. For six months. That's one query, with a human behind a browser.

Now imagine AI agents making hundreds of queries on your behalf — every one leaking context to platforms that build profiles, adjust prices, and sell your behavioral data to brokers you've never heard of.

— PAP design rationale
A2A
Agent-to-Agent (Google)
  • Authenticates agents as platform entities
  • Privacy is an "opacity principle" — aspirational, not enforced
  • No context minimization at the protocol level
  • No session ephemerality guarantees
MCP
Model Context Protocol (Anthropic)
  • Tool access for a single agent — not negotiation between agents
  • Spec acknowledges it "cannot enforce security principles at the protocol level"
  • No cryptographic identity
  • No economic primitives
ACP / AGNTCY
REST-Based Agent Interop
  • Thin trust layer — no cryptographic identity
  • Enterprise workflow focus — principal is the org, not the individual
  • No field-level disclosure controls
  • Privacy is an implementation concern

None enforce context minimization. None define session ephemerality as a guarantee.
None have economic primitives. Privacy is always somebody else's problem.

Five constraints.
Enforced by the protocol.

PAP makes privacy the protocol's problem — not the developer's. The human principal is the root of trust. Every agent carries a cryptographically verifiable mandate from that root.

No new cryptography. No token economy. No central registry.
Built entirely on existing, standardized primitives maintained by bodies without platform capture.
Mandate Decay States
Active
Full scope. All operations permitted.
Degraded
Partial scope. Write operations restricted.
ReadOnly
No mutations. Queries only.
Suspended
All operations rejected. Non-renewal = revocation.
// Principal sees degradation.
// Not a surprise cutoff.
01
Deny by Default
An agent can only do what its mandate explicitly permits. No scope means no action. Absence of permission is not an error — it is the correct response.
02
Delegation Cannot Exceed Parent
A child mandate's scope is bounded by its parent's scope. A child's TTL cannot exceed its parent's TTL. This is verified cryptographically, not by policy.
03
Session DIDs Are Ephemeral
Both agents generate single-use keypairs for each session. These are not linked to any persistent identity. When the session closes, the keys are discarded.
04
Receipts: Property References Only
A transaction receipt records what types of data were disclosed — never the values. Both principals can audit the record. No platform stores it.
05
Non-Renewal Is Revocation
A mandate that isn't renewed doesn't need a revocation notice. It degrades progressively — Active → Degraded → ReadOnly → Suspended — and then it stops. The principal sees the degradation, not a surprise cutoff. Revocation is the natural state; continuation requires active consent.

Built on standards
that already exist

PAP uses no novel cryptographic primitives. Every layer is an existing, ratified specification maintained by bodies without platform capture.

Layer Standard Purpose Body
Identity WebAuthn Device-bound keypair generation. Root of trust anchored to hardware. W3C
Identity W3C DIDs Decentralized identifiers — did:key. No central registry. W3C
Credentials W3C VC 2.0 Verifiable Credential envelope wrapping mandate payloads. W3C
Disclosure SD-JWT Selective claim disclosure. Share 2 of 4 claims. Over-disclosure structurally prevented. IETF
Vocabulary Schema.org Capability and action type references. Describes what. Protocol governs under what terms. schema.org
Data JSON-LD Structured linked data for agent advertisements. No vocabulary extensions. W3C
Privacy OHTTP (RFC 9458) Oblivious HTTP. Cloud request unlinkability. The relay cannot correlate requests. IETF
Transport HTTP/JSON 6-phase session handshake: Token → DID Exchange → Disclosure → Execution → Receipt → Close. IETF
Federation HTTP/JSON Cross-registry sync, announce, and peer discovery. Content-hash dedup.

9 focused crates.
Rust core + Python SDK.

pap-did
Ed25519 keypair generation, did:key derivation, DID documents, ephemeral session keys.
pap-core
Mandate issuance, hierarchical delegation, scope enforcement, session state machine, receipts, decay states.
pap-credential
W3C Verifiable Credential envelope, SD-JWT selective disclosure. Over-disclosure structurally prevented.
pap-marketplace
Signed JSON-LD agent advertisements, marketplace registry, disclosure-based filtering.
pap-proto
Protocol message types and typed envelope serialization for the 6-phase handshake.
pap-transport
Axum HTTP client/server driving the 6-phase session handshake. A thin wrapper — doesn't change the trust model.
pap-federation
Federated registry with cross-registry sync, announce, peer discovery, and content-hash dedup.
pap-webauthn
WebAuthn signer abstraction with software fallback and mock authenticator for testing.
pap-python
Python bindings via PyO3. pip install pap. Full mandate chain, delegation, and verification from Python.

Full protocol.
From Python.

PyO3 bindings expose the entire Rust core to Python. Generate keypairs, issue mandates, delegate to sub-agents, and verify chains — all with native Python types and exceptions.

$ pip install pap
  • PrincipalKeypair & SessionKeypair with did:key derivation
  • Scope, DisclosureSet, and Mandate with full chain verification
  • Typed exceptions: PapSignatureError, PapScopeError, PapSessionError
  • Mixed keypair types in chain verification (principal + session)
  • Build from source with maturin develop — Rust 1.75+, Python 3.8+
python
from pap import (
    PrincipalKeypair, SessionKeypair,
    Scope, ScopeAction, DisclosureSet,
    Mandate, MandateChain,
)

# 1. Generate the principal's root keypair
principal = PrincipalKeypair.generate()
print(principal.did())  # did:key:z6Mk...

# 2. Define what the agent is allowed to do
scope = Scope([ScopeAction("schema:SearchAction")])
ds = DisclosureSet.empty()

# 3. Issue and sign a root mandate
mandate = Mandate.issue_root(
    principal.did(), "did:key:zagent",
    scope, ds, ttl
)
mandate.sign(principal)

# 4. Delegate to a sub-agent (scope <= parent)
agent_key = SessionKeypair.generate()
child = mandate.delegate(
    agent_key.did(), scope, ds, ttl
)
child.sign_with_session_key(agent_key)

# 5. Verify the full chain
chain = MandateChain(mandate)
chain.push(child)
chain.verify_chain([principal, agent_key])

Eight scenarios.
Clone and run today.

Each example exercises protocol features the others do not. Proving the trust model works in code, not prose.

Zero-Disclosure Search
A web search with zero personal disclosure. 12 protocol steps from keypair generation to co-signed receipt.
  • Full 12-step handshake
  • Zero claims disclosed to search agent
  • Co-signed receipt, property refs only
cargo run --bin search
Selective Disclosure
A flight booking requiring personal context. SD-JWT: 2 of 4 claims revealed. Email + phone cryptographically withheld.
  • SD-JWT: name + nationality only
  • Marketplace filters by satisfiable disclosure
  • Receipt: "Alice Baur" never appears
cargo run --bin travel-booking
Delegation Chain
4-level mandate hierarchy. Scope narrows and TTL shrinks at each level. Three rejected delegations prove the constraints hold.
  • Human → Orchestrator → Trip Planner → Booking
  • 3 rejected over-scope delegations
  • Decay state transitions demonstrated
cargo run --bin delegation-chain
Payment Extensions
Chaumian ecash payment (vendor cannot identify payer), value-capped auto-approval, and continuity tokens with principal-controlled TTL.
  • Ecash: vendor cannot identify payer
  • Auto-approval: $12.99 below $20 threshold
  • Continuity tokens: delete to sever
cargo run --bin payment
HTTP Transport
Same protocol invariants as the in-memory search, but over HTTP. Single binary, Axum server on a random port, 6-phase handshake.
  • Full 6-phase handshake over HTTP
  • Transport is a thin wrapper
  • Trust model unchanged by transport
cargo run --bin networked-search
Federated Discovery
Two independent registries on different ports. Federation sync makes agents from Registry A discoverable through Registry B.
  • Two registries, two ports
  • Push announcements across registries
  • Content-hash dedup prevents duplicates
cargo run --bin federated-discovery
WebAuthn Ceremony
Device-bound key generation using the WebAuthn API. Mock authenticator for testing. The production path for principal keypairs.
  • WebAuthn-based key generation
  • Mock authenticator for CI/testing
  • Software fallback signer
cargo run --bin webauthn-ceremony
Local AI Assistant
Docker Compose: Ollama + SearXNG + PAP marketplace + providers + orchestrator + receipt viewer. Your prompts never leave your machine.
  • Ollama local LLM (pull mistral)
  • SearXNG private search — no Google
  • External tool use via PAP full handshake
  • Receipt viewer: see exactly what was disclosed
cd examples/local-ai-assistant && docker compose up -d

What PAP replaces
and why

Concern A2A MCP ACP PAP ✓
Context minimization SD-JWT per interaction
Session ephemerality Stateful Optional Ephemeral DIDs, keys discarded
Field-level disclosure SD-JWT selective claims
Cryptographic scope enforcement Mandate chain verification
Agent-to-agent negotiation (tool access)
Privacy-preserving payment Ecash / Lightning proofs
Marketplace discovery Agent Cards HTTP Federated, disclosure-filtered
Audit trail Co-signed receipts
Principal control Platform User (stated) Enterprise Cryptographic mandate

Clone, run,
see it work.

1
Clone the repo
Requires Rust stable (1.75+). No external services, no API keys, no accounts.
2
Run the test suite
All protocol constraints are exercised in the test suite. Green across the board.
3
Run any example
Start with search for the simplest full handshake, or jump to delegation-chain for the trust hierarchy in action.
4
Run the local AI assistant
Docker Compose brings up the full stack: Ollama, SearXNG, PAP marketplace, providers, and a receipt viewer at localhost:9090.
View on GitHub Contributing →
bash
# Clone the repository
git clone https://github.com/Baur-Software/pap.git
cd pap

# Run the full test suite
cargo test

# Core protocol examples
cargo run --bin search          # Zero-disclosure search
cargo run --bin travel-booking  # SD-JWT selective disclosure
cargo run --bin delegation-chain # 4-level trust hierarchy
cargo run --bin payment         # Ecash + auto-approval

# Transport & federation
cargo run --bin networked-search    # 6-phase HTTP handshake
cargo run --bin federated-discovery # Cross-registry federation
cargo run --bin webauthn-ceremony   # Device-bound keys

# Local AI assistant (Docker)
cd examples/local-ai-assistant
docker compose up -d
docker exec ollama ollama pull mistral
# Ask a question — your prompt stays local
curl http://localhost:9010/ask \
  -d '{"query":"What is the weather in Seattle?"}'
# See exactly what was disclosed
curl http://localhost:9090/receipts

Go deeper

Open Source · MIT OR Apache-2.0

The question isn't whether your
agents can talk to each other.

The question is who they answer to. PAP gives you the tools to answer that question in code, not policy.