Skip to content

feat: operator-signed agent revocation (needs migration 0006 before merge) - #3

Open
mikejmorgan-ai wants to merge 1 commit into
mainfrom
feat/agent-revocation
Open

mikejmorgan-ai wants to merge 1 commit into
mainfrom
feat/agent-revocation

Conversation

@mikejmorgan-ai

Copy link
Copy Markdown
Contributor

Operator-signed agent revocation

The first lifecycle transition this deployment writes. Only the agent's own operator key can revoke it; AgenID holds no key that can.

⚠️ Merge only after migration 0006_revocations is applied to production (Supabase prljrmgickpkkunrrkxq). The route calls the revoke_agent function it creates, and every public page in this PR says revocation is deployed. The automated apply was not approved during the autonomous run, so this PR waits. Once the migration is applied, merging is safe and the deploy is the only remaining step.

What changes

  • POST /api/v1/agents/{agenid}/revocation — accepts a v1.2-draft Revocation (revokes_type: "agent") signed by the agent's operator key. Refuses another agent's key, an authority key, a tampered signature, a revoked_at outside ±5 min, a path/target mismatch.
  • Permanent per spec §12: replay → 409 already_revoked, re-registration → 409 agent_exists, directory listing refused.
  • Atomic: revoke_agent writes the revocation, the status and the agent.revoked ledger event in one transaction. Validated on embedded Postgres (idempotent, full rollback on failure, anon cannot execute).
  • Envelope gains revocation (signed object when REVOKED, else null); the Verification Card shows who signed it.
  • /revoke signs in the browser from the /issue key file; requires reason, typed identifier and a permanence confirmation.
  • One implementation (packages/api/src/revoke.ts), shared by Fastify and the web route; a test fails if anything else calls revokeAgent or writes REVOKED.
  • Every public surface that said "no revocation flow" now states what is and is not deployed (key rotation/revocation and other transitions are still not).
  • docs/revocation-propagation.md — proposal (not normative) for cache lifetime and registry-unreachable behavior.

Verification

  • web 1294 · api 93 · core 99 · cli 8 · mcp 4 — all green; pnpm -r build clean; check:docs clean.
  • e2e 3s–3v: revoke through the web route in HTTP-registry mode, envelope verifies offline, card renders REVOKED, replay 409.
  • Standing, window and permanence guards each proven to fail with the check removed.

🤖 Generated with Claude Code

https://claude.ai/code/session_012Jiy2JKhXUXk8LLDtAkjaR

@vercel

vercel Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agenid-web Ready Ready Preview Oct 19, 2026 1:51pm UTC

mikejmorgan-ai added a commit that referenced this pull request Oct 19, 2026
…tion approval

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jiy2JKhXUXk8LLDtAkjaR
The first lifecycle transition this deployment writes. POST
/api/v1/agents/{agenid}/revocation accepts a Revocation (v1.2-draft object,
revokes_type "agent") signed by the agent's own operator key - the key its
ManifestProof names, role=operator, controller=agent_id - and nothing else.
AgenID holds no key that can revoke an agent.

Spec 1.1.1 section 12 makes REVOKED permanent: a replay or second revocation is
409 already_revoked, re-registration is 409 agent_exists, directory listing is
refused. revoked_at must be within five minutes of the registry clock.

Status, stored revocation and the agent.revoked ledger event are written in one
Postgres transaction by revoke_agent (migration 0006: RLS on, public read, no
write policies, EXECUTE revoked from PUBLIC). Validated against an embedded
Postgres: idempotent on a revoked agent, full rollback on a failed insert,
anon cannot execute.

The resolution envelope gains `revocation` (the signed object when REVOKED,
null otherwise) so a verifier can check who made the change. /revoke signs in
the browser from the /issue key file. Rules live once in
packages/api/src/revoke.ts, shared by the Fastify registry and the web route;
a test fails if any other file calls revokeAgent or writes REVOKED.

Every public surface that said "no revocation flow" now says agent revocation
is operator-only and key rotation, key revocation and other transitions are
not deployed. docs/revocation-propagation.md proposes the missing half.

Tests: web 1294, api 93 (+4), e2e 3s-3v. Standing, window and permanence
guards each proven to fail with the check removed.

Requires migration 0006 applied to production before merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Jiy2JKhXUXk8LLDtAkjaR

This branch was successfully deployed

1 active deployment
Preview — 6761cfa1 Deployed Oct 19, 2026 by vercel[bot]
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