feat: Phase 1 P1 — Dockerfile, AGNTCY alignment docs, Node.js SDK

Three remaining Phase 1 P1 deliverables:

1. Dockerfile — multi-stage build (builder + production), node:18-alpine,
   non-root USER node, .dockerignore excluding secrets and dev artifacts

2. AGNTCY alignment docs (docs/agntcy/) — README and alignment.md mapping
   all 6 AGNTCY domains to AgentIdP features with Phase 2/3 pending items noted

3. Node.js SDK (@sentryagent/idp-sdk) — TypeScript strict, zero any, native
   fetch (Node 18+), TokenManager with 60s auto-refresh, service clients for
   all 14 endpoints (agents, credentials, tokens, audit), AgentIdPError typed
   error hierarchy, full README

All three changes tracked under openspec/changes/ with tasks marked complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SentryAgent.ai Developer
2026-03-28 14:46:53 +00:00
parent d94a8cedc0
commit aa5167835e
34 changed files with 1572 additions and 0 deletions

175
docs/agntcy/alignment.md Normal file
View File

@@ -0,0 +1,175 @@
# AGNTCY Alignment Mapping
This document maps each AGNTCY standard concept to the corresponding AgentIdP implementation. It is the authoritative reference for AGNTCY compliance claims.
---
## AGNTCY Core Concepts
AGNTCY defines five foundational concepts for AI agent identity:
| AGNTCY Concept | Description |
|----------------|-------------|
| **Non-Human Identity** | Agents are first-class identities — not service accounts, not user proxies |
| **Agent Registry** | Authoritative directory of registered agent identities with stable, immutable IDs |
| **Credential Management** | Secure issuance, rotation, and revocation of agent credentials |
| **Authentication** | Standardised protocol for agents to prove their identity |
| **Lifecycle Management** | Defined states for agent provisioning, suspension, and retirement |
| **Audit and Accountability** | Immutable event log of all agent actions for governance and compliance |
---
## Implementation Mapping
### Non-Human Identity
AGNTCY requires agents to be treated as first-class identities with their own identity model — not mapped onto human user accounts.
| AGNTCY Requirement | AgentIdP Implementation | Status |
|--------------------|------------------------|--------|
| Unique, immutable agent identifier | `agentId` (UUID, system-assigned at registration, never changes) | ✅ Implemented |
| Human-readable stable name | `email` field — unique email-format identifier per agent | ✅ Implemented |
| Identity metadata | `agentType`, `version`, `capabilities`, `owner`, `deploymentEnv` fields | ✅ Implemented |
| Capability declaration | `capabilities` array — `resource:action` strings declaring agent permissions | ✅ Implemented |
| Identity separate from human users | Agents have their own registry, credential model, and token flow — no user accounts | ✅ Implemented |
**API endpoints:** `POST /api/v1/agents`, `GET /api/v1/agents/{agentId}`
---
### Agent Registry
AGNTCY requires a centralised, queryable registry of agent identities.
| AGNTCY Requirement | AgentIdP Implementation | Status |
|--------------------|------------------------|--------|
| Register new agent identity | `POST /api/v1/agents` | ✅ Implemented |
| Retrieve agent by stable ID | `GET /api/v1/agents/{agentId}` | ✅ Implemented |
| List and filter registered agents | `GET /api/v1/agents?owner=&agentType=&status=` | ✅ Implemented |
| Update agent metadata | `PATCH /api/v1/agents/{agentId}` | ✅ Implemented |
| Soft-delete retired agents (record retained) | `DELETE /api/v1/agents/{agentId}` → status: `decommissioned`, record persisted | ✅ Implemented |
| Enforce uniqueness of agent identity | `email` unique constraint — `409 AGENT_ALREADY_EXISTS` on duplicate | ✅ Implemented |
---
### Credential Management
AGNTCY requires secure credential issuance with rotation and revocation support.
| AGNTCY Requirement | AgentIdP Implementation | Status |
|--------------------|------------------------|--------|
| Issue agent credentials | `POST /api/v1/agents/{agentId}/credentials` — generates `client_id` + `client_secret` | ✅ Implemented |
| Secret never stored in plaintext | `client_secret` stored as bcrypt hash; plaintext returned once only | ✅ Implemented |
| Multiple active credentials per agent | An agent can hold multiple active credentials simultaneously | ✅ Implemented |
| Credential rotation | `POST /api/v1/agents/{agentId}/credentials/{credentialId}/rotate` | ✅ Implemented |
| Credential revocation | `DELETE /api/v1/agents/{agentId}/credentials/{credentialId}` | ✅ Implemented |
| Credential lifecycle tracking | `status` field: `active` / `revoked`; `revokedAt` timestamp | ✅ Implemented |
| Optional credential expiry | `expiresAt` field on credential generation | ✅ Implemented |
---
### Authentication
AGNTCY requires a standardised, interoperable authentication protocol for agents.
| AGNTCY Requirement | AgentIdP Implementation | Status |
|--------------------|------------------------|--------|
| Standardised auth protocol | OAuth 2.0 Client Credentials grant (RFC 6749 §4.4) | ✅ Implemented |
| Signed, verifiable tokens | RS256 JWT access tokens — any party with the public key can verify | ✅ Implemented |
| Token introspection | `POST /api/v1/token/introspect` — RFC 7662 compliant | ✅ Implemented |
| Token revocation | `POST /api/v1/token/revoke` — RFC 7009 compliant | ✅ Implemented |
| Scope-based access control | `agents:read`, `agents:write`, `tokens:read`, `audit:read` scopes | ✅ Implemented |
| Token lifetime enforcement | 1-hour JWT expiry, enforced at verification | ✅ Implemented |
| Revocation durability | Revocations persisted to PostgreSQL + Redis | ✅ Implemented |
**Token claims align with AGNTCY identity model:**
| JWT Claim | AGNTCY Meaning |
|-----------|----------------|
| `sub` | The agent's stable `agentId` — the AGNTCY non-human identity reference |
| `client_id` | The credential that authenticated this token request |
| `scope` | Declared capabilities granted for this token |
| `jti` | Unique token ID — enables precise revocation |
---
### Lifecycle Management
AGNTCY defines a mandatory lifecycle for agent identities.
| AGNTCY State | AgentIdP Status | Behaviour |
|-------------|-----------------|-----------|
| Provisioned / Active | `active` | Agent can authenticate and obtain tokens |
| Suspended | `suspended` | Agent cannot obtain new tokens; existing tokens expire naturally |
| Decommissioned / Retired | `decommissioned` | Permanent — all credentials revoked, agent cannot authenticate, record retained |
| AGNTCY Requirement | AgentIdP Implementation | Status |
|--------------------|------------------------|--------|
| Defined lifecycle states | `status` enum: `active`, `suspended`, `decommissioned` | ✅ Implemented |
| Irreversible decommission | `decommissioned` status cannot be reversed via API | ✅ Implemented |
| Credential cascade on decommission | All active credentials revoked when agent is decommissioned | ✅ Implemented |
| State transitions audited | Every status change writes an `agent.suspended`, `agent.reactivated`, or `agent.decommissioned` audit event | ✅ Implemented |
---
### Audit and Accountability
AGNTCY requires an immutable, queryable audit log of all significant agent actions.
| AGNTCY Requirement | AgentIdP Implementation | Status |
|--------------------|------------------------|--------|
| Immutable audit log | `audit_events` table — append-only, no API delete/update | ✅ Implemented |
| Automatic event capture | 12 event types captured automatically across all services | ✅ Implemented |
| Query and filter audit events | `GET /api/v1/audit` with filters: `agentId`, `action`, `outcome`, `fromDate`, `toDate` | ✅ Implemented |
| Retrieve individual event | `GET /api/v1/audit/{eventId}` | ✅ Implemented |
| Event retention | 90-day retention enforced at query layer (free tier) | ✅ Implemented |
| Auth failure logging | `auth.failed` event on every failed `POST /token` attempt | ✅ Implemented |
**Audited events (12 total):**
| Event | Trigger |
|-------|---------|
| `agent.created` | New agent registered |
| `agent.updated` | Agent metadata changed |
| `agent.suspended` | Agent suspended |
| `agent.reactivated` | Agent reactivated from suspended |
| `agent.decommissioned` | Agent permanently decommissioned |
| `token.issued` | Access token issued |
| `token.revoked` | Access token revoked |
| `token.introspected` | Token introspection called |
| `credential.generated` | New credentials generated |
| `credential.rotated` | Credential rotated |
| `credential.revoked` | Credential revoked |
| `auth.failed` | Authentication attempt failed |
---
## Compliance Status Summary
| AGNTCY Domain | Phase 1 Status | Notes |
|---------------|----------------|-------|
| Non-Human Identity | ✅ Fully implemented | Immutable IDs, typed metadata, capability declarations |
| Agent Registry | ✅ Fully implemented | Full CRUD, pagination, soft-delete |
| Credential Management | ✅ Fully implemented | Generate, rotate, revoke, bcrypt storage |
| Authentication | ✅ Fully implemented | OAuth 2.0 CC, RS256 JWT, introspect, revoke, scopes |
| Lifecycle Management | ✅ Fully implemented | active / suspended / decommissioned with cascades |
| Audit and Accountability | ✅ Fully implemented | 12 event types, immutable, queryable, 90-day retention |
| Federation | 🔲 Phase 2 | Cross-system agent identity federation |
| W3C DIDs | 🔲 Phase 3 | Decentralised identifier support |
| Policy Engine | 🔲 Phase 2 | OPA-based capability enforcement |
| Secret Management | 🔲 Phase 2 | HashiCorp Vault integration |
---
## Interoperability
An agent registered in AgentIdP can be identified by any AGNTCY-compliant system using its `agentId` (UUID). The JWT access token carries the `sub` claim (= `agentId`), making the agent's identity verifiable by any party that holds the AgentIdP RS256 public key.
To verify an AgentIdP token in an external system:
1. Obtain the AgentIdP RS256 public key (`JWT_PUBLIC_KEY` from the server operator)
2. Verify the JWT signature using RS256
3. The `sub` claim is the agent's stable AGNTCY-aligned identity reference
4. The `scope` claim declares the agent's authorised capabilities for this token
This is the same verification model used across all OAuth 2.0 / OIDC systems — purpose-built for machine-to-machine interoperability.