Skip to content

feat: agent identity protocol, CIBA proof claims, and E2E hardening#123

Merged
gustavovalverde merged 5 commits intomainfrom
feat/prd02-mcp-agent-detection
Mar 22, 2026
Merged

feat: agent identity protocol, CIBA proof claims, and E2E hardening#123
gustavovalverde merged 5 commits intomainfrom
feat/prd02-mcp-agent-detection

Conversation

@gustavovalverde
Copy link
Owner

@gustavovalverde gustavovalverde commented Mar 22, 2026

Summary

Implements the Agent Auth Protocol for Zentity: a system that gives agents enough identity to act on behalf of humans without turning the agent into a long-term container for human PII.

The design solves three problems at once: the caller authenticates as a machine, the human still approves sensitive actions, and the relying party learns who acted without getting a globally trackable agent identifier.

See Agent Architecture for the full design narrative.

Standards implemented

Spec Role
Agent Auth Protocol v1.0-draft Discovery, registration, lifecycle, capability grants
AAP draft JWT claim vocabulary for agent tokens
RFC 9396 Rich Authorization Details for typed approval payloads
RFC 8693 Token exchange for audience rebinding and purchase artifacts
RFC 7662 Agent introspection with lifecycle re-evaluation
draft-ietf-oauth-attestation-based-client-auth-08 Vendor attestation for host trust tiers
OIDC CIBA Core 1.0 Consent channel with runtime proof binding
A2A Protocol v0.3.0 Agent-to-agent discovery card

Architecture

The implementation is organized around five protocol concerns that form a chain:

Secure Transport → Structured Intent → Agent Control Plane → Consent Channel → Token Semantics

Principal boundaries

Three distinct caller classes, each with its own auth helper:

  • Browser user — session cookie → requireBrowserSession()
  • User-delegated machine — OAuth access token → requireUserAccessToken()
  • Pure machine clientclient_credentialsrequireClientCredentials()

Agent registration and lifecycle are machine-facing OAuth surfaces. Human approval comes later through CIBA.

Host and session hierarchy

Agent identity splits into two layers because two lifetimes need two keys:

  • Durable host (agent_host) — Ed25519 keypair persisted per installation, keyed by public_key_thumbprint. Survives restarts. One user+client can have multiple hosts (laptops, containers).
  • Ephemeral session (agent_session) — fresh Ed25519 keypair per process. Registered with a host-signed host-attestation+jwt. Carries runtime metadata (display_name, model, version).

Trust tiers

Two operational tiers based on what Zentity can verify about the installation:

Tier Reached by Effect
unverified Default registration Default policies: check_compliance, request_approval
attested Valid OAuth-Client-Attestation + PoP against TRUSTED_AGENT_ATTESTERS Additional default policy: read_profile

Attestation widens default host policy — it does not mint a separate token class.

Capability containment

Answers one question repeatedly: "Can this session do this action without interrupting the user?"

  • Host policies (agent_host_policy) — durable grants with constraint operators (max, min, in, not_in, eq)
  • Session grants (agent_session_grant) — ephemeral, seeded from host policy at registration
  • Usage ledger (capability_usage_ledger) — append-only, enforces daily_limit_count, daily_limit_amount, cooldown_sec
  • Grant evaluator (grant-evaluation.ts) — the sole CIBA auto-approve path

Auto-approval is refused for: identity scopes, missing capabilities, biometric-strength capabilities, no matching grant, or exceeded limits.

Approval routing

Three outcomes based on risk, not transport:

Outcome Condition Human interruption
Silent Matching grant + non-biometric None
Push No grant, identity scope, or manual required Push notification → approval page
Biometric Capability strength is biometric Always explicit approval

purchase always routes to biometric approval. read_profile can become silent for attested hosts.

Token anatomy (AAP profile)

CIBA access tokens carry the AAP draft claim vocabulary: agent, task, capabilities, oversight, audit. Exchanged tokens additionally carry delegation.

  • sub — human pairwise identifier for target client
  • act.sub — agent pairwise identifier for target client (derived from session ID + sector)
  • authorization_details — round-tripped from CIBA request through approval to token
  • purchase-authorization+jwt — RFC 8693 exchange artifact for downstream merchants

Binding chain

Each phase produces evidence the next can reuse:

OAuth user token → Durable host registration → Fresh session registration
  → Agent-Assertion on CIBA → Human approval → Access token (sub + act.sub)
    → Optional RFC 8693 exchange to purchase-authorization+jwt

Lifecycle

Two session clocks (idle TTL: 30min, max lifetime: 24h). No reactivation — expired sessions require fresh registration under the same host. Host key rotation invalidates all sessions.

Discovery and introspection

  • /.well-known/agent-configuration — protocol discovery (endpoints, algorithms, features)
  • GET /api/auth/agent/capabilities — capability catalog with schemas and approval strengths
  • POST /api/auth/agent/introspect — RFC 7662-style, re-evaluates session lifecycle at query time
  • GET /api/auth/agent/jwks — signing keys for agent-facing JWT verification
  • /.well-known/agent-card.json — A2A agent card with agent-auth security scheme

What changed

New (apps/web)

  • Schema: agent_host, agent_session, agent_host_policy, agent_session_grant, capability_usage_ledger
  • CIBA: grant-evaluation.ts, agent-binding.ts, agent-jwt.ts, agent-lifecycle.ts, aap-profile.ts, pairwise-agent.ts, usage-ledger.ts, approval-path.ts
  • Auth: principal boundary helpers, agent registration routes, introspection, capability discovery, host key rotation, revocation
  • Dashboard: /dashboard/agents management UI
  • Identity: hardened JWKS fetcher for vendor attestation

New (apps/mcp)

  • Persistent Ed25519 host key with XDG-compliant storage
  • Host + session registration on every startup
  • Agent-Assertion attached to all CIBA requests
  • Tools surface agent identity and authorization_details

New (apps/demo-rp)

  • Agent runtime module with Ed25519 key management
  • Aether AI scenario updated for AAP token flow

Removed

  • Boundary system (agent-boundaries.ts, boundary-evaluation.ts, auto-approve.ts, /dashboard/agent-policies)
  • agent-claims.ts (replaced by aap-profile.ts)
  • agentic-authorization.md (replaced by agent-architecture.md)

Implement the full agent identity system (PRD-04 + PRD-05):

- Durable host / ephemeral session identity model with Ed25519 keys
- Capability-based authorization (host policies + session grants)
- Grant evaluator for CIBA auto-approval, replacing boundary system
- Append-only usage ledger with daily caps, amount limits, and cooldown
- Risk-graduated approval routing (auto, push, manual)
- Pairwise agent subject identifiers per relying party
- Three-clock session lifecycle (expiry, idle, absolute max)
- Agent/host revocation and host key rotation
- AAP token profile (act.sub, authorization_details) per draft-oauth-ai-agents
- Agent-Assertion JWT (Ed25519) verified on every CIBA request
- Vendor attestation pipeline with hardened JWKS fetcher
- RFC 7662-style agent introspection endpoint
- Agent discovery at /.well-known/agent-configuration
- Dashboard for agent management at /dashboard/agents

Schema: agent_host, agent_session, agent_host_policy, agent_session_grant,
capability_usage_ledger. Seeded capabilities: purchase, biometric,
read_profile, check_compliance, request_approval.

Removes: boundary system, agent-claims, auto-approve, agent-policies UI.
Add agent identity layer to the MCP server:

- Persistent host key (Ed25519) with XDG-compliant storage
- Agent session registration against Zentity auth endpoints
- Agent-Assertion JWT attached to every CIBA request
- Host-first bootstrap: register host before session on each start
- Runtime manager for session lifecycle
- CIBA requests carry agent metadata (host_id, task_id, task_hash)
- Purchase tool sends authorization_details with agent assertion
- Whoami tool surfaces host/session identity
- HTTP and stdio transports updated for agent context propagation
Demo RP (apps/demo-rp):
- Agent runtime module with Ed25519 key, host/session registration
- Aether AI scenario updated for AAP token flow
- DCR route hardened with DPoP and attestation headers
- Vendor tarballs updated to better-auth 1.5.1-beta.3

Documentation:
- New agent-architecture.md (replaces agentic-authorization.md)
- ADR-0004: agent-provider-adapter architecture decision record
- Updated attestation-privacy-architecture.md with agent data classification
- Updated oauth-integrations.md with agent endpoints

Landing page:
- Agents page and compliance standards text updates
@gustavovalverde gustavovalverde changed the title feat(agent): durable host identity with capability-based CIBA authorization feat: agent identity protocol, CIBA proof claims, and E2E hardening Mar 22, 2026
- Copy vendor/ directory before pnpm install in demo-rp Dockerfile
  (vendor tarballs are referenced in package.json as file: deps)
- Remove --reporter github-actions from knip invocation
  (knip 5.87.0 dropped the --reporter flag)
The deny-all .dockerignore excluded vendor tarballs from the Docker
build context, causing pnpm install to fail on file: dependencies.
@gustavovalverde gustavovalverde merged commit 55ecd25 into main Mar 22, 2026
27 of 28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant