Implement agent identity profile v01 (Signature-Agent + x509 delegation)#50
Open
Implement agent identity profile v01 (Signature-Agent + x509 delegation)#50
Conversation
Replace insecure String.includes() check with proper URL hostname validation to prevent authorization bypass via crafted URLs like evil-trusted.com.attacker.com or attacker.com/trusted.com/fake.json. The new isTrustedDirectory() method: - Parses URLs to extract and compare hostnames - Validates exact match or proper subdomain boundary - Case-insensitive comparison - Handles trusted directories with or without scheme prefix
- Fix is_active to check not_before <= now() in addition to not_after - Add /v1/certs/public-status endpoint for relying party revocation checks - Fix x5c attachment to only serve valid certificates (not expired/not-yet-valid) - Require status='active' for agent_id lookup in signature-agent-card - Change CLI default Signature-Agent format from legacy to dict - Add .nvmrc file (Node 20) - Update README with not_before field and public-status endpoint docs
- Require PoP signature for cert issuance (prevents issuing certs for keys you do not control) - Validate fingerprint_sha256 format (64 hex chars) on public-status endpoint - Add fingerprint computation guidance to README for mTLS integrators
- Add type checks and signature length validation (64 bytes for Ed25519)
- Disallow future timestamps (30s drift tolerance, 5min max age)
- Bind proof to agent_id: cert-issue:{agent_id}:{timestamp}
- Use object form for webcrypto.subtle.verify
- Fix fingerprint error message (accepts uppercase, normalizes to lowercase)
- Update README with native crypto fingerprint example
- Remove Issue Certificate button from portal (add CLI instructions)
- Add oba-bot cert issue command with PoP support
- Remove kid-only cert issuance (require agent_id for PoP binding) - Add --private-key-path to CLI for portal-created agents - Update portal snippet with full command (token + private-key-path) - Clarify README: 30s future drift tolerated for clock skew - Add happy-path PoP test with real Ed25519 crypto verification
- Auto-detect key format: JWK JSON (portal agent creation) or PEM (Setup page) - Extract PEM from .txt bundle files (Setup.tsx downloads keys in .txt) - Update portal snippet to show correct .json extension - Update README to document both supported formats
- Portal: use full agent ID in private key filename example (was truncated with slice(0,8) which didnt match actual filename) - CLI: validate jwk.x field exists (not just d) - CLI: import minimal JWK object (kty, crv, x, d only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Test valid=false for revoked certs (includes revoked_at, revoked_reason) - Test valid=false for expired certs (not_after in the past) - Test 404 when cert not found by fingerprint 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add migration 009 with pop_nonces table and check_pop_nonce function - Check nonce before issuing certificate (rejects replayed proofs) - Graceful degradation if migration not applied - Add test for replay detection - Document replay protection in README 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove dead issueCert() from portal API (lacks PoP proof param) - Add oba_* field validation in agents-api.ts (type check, length limit) - Normalize fingerprint in /v1/certs/status (lowercase, 64 hex chars) - Fix timestamp drift comment to match code (+30s tolerance) - Update Node engine to >=20.0.0 in proxy and verifier-client - Add E2E signature verification tests (5 tests) - Fix portal UI cert status logic to check not_before (add "pending" state)
- Add tag="web-bot-auth" to Signature-Input (MUST per IETF draft) - Add signature-agent;key="label" covered component format for dictionary member selection (RFC 8941) - Increase nonce from 16 to 64 bytes (RECOMMENDED per IETF draft) - Fix keyid to use full JWK thumbprint without truncation - Add relabeling support in verifier: parse ;key= parameter from covered components to select correct dictionary member 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update test assertions to expect the new IETF-compliant format: - signature-agent;key="sig1" covered component format - tag="web-bot-auth" in Signature-Input 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update parse_covered_headers in all clients to handle the IETF draft signature-agent;key="label" format. When parsing covered components, extract only the base header name (before ;) for lookup purposes. Files updated: - packages/verifier-client/src/headers.ts - plugins/wordpress-openbotauth/includes/Verifier.php - sdks/python/src/openbotauth_verifier/headers.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enforce leaf certificate EKU includes clientAuth (1.3.6.1.5.5.7.3.2) when EKU extension is present (default: enabled) - Add optional SAN URI binding validation for soft identity pinning - Add comprehensive tests for EKU and SAN validation scenarios - Note: Node.js exposes EKU OIDs via `keyUsage` property (not `extKeyUsage`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements the PR #6 spec file (
docs/specs/draft-openbotauth-agent-identity-00.md) in code, aligned to the current spec text (no ADT changes, no 402 semantics changes).Verifier (
packages/verifier-service)Signature-Agentas RFC 8941 Structured Field Dictionary with signature-label selection.Signature-Agent.Signature-Inputin verification flow.x5c/x5uvalidation:x5ufetch/.well-known/http-message-signatures-directoryURL handling.Registry (
packages/registry-service)oba_agent_id,oba_parent_agent_id,oba_principal) and migration./.well-known/signature-agent-card.POST /v1/certs/issuePOST /v1/certs/revokeGET /.well-known/ca.pemx5cto JWKS for active, scoped agent certs.Bot CLI (
packages/bot-cli)Signature-Agentin dictionary format (legacyremains default).Portal (
apps/registry-portal)oba_*fields in create/detail views.Docs
Signature-Agent, signature-agent-card, and x509 config/limitations.Migration
infra/neon/migrations/007_agent_identity_and_certs.sqlNotes
x5ucurrently fetches leaf cert only; AIA chain building is not implemented.Test Coverage
pnpm --filter @openbotauth/verifier-service test --run signature-parser