Files
sentryagent-idp/openspec/changes/phase-1-mvp-implementation/tasks.md
SentryAgent.ai Developer d3530285b9 feat: Phase 1 MVP — complete AgentIdP implementation
Implements all P0 features per OpenSpec change phase-1-mvp-implementation:
- Agent Registry Service (CRUD) — full lifecycle management
- OAuth 2.0 Token Service (Client Credentials flow)
- Credential Management (generate, rotate, revoke)
- Immutable Audit Log Service

Tech: Node.js 18+, TypeScript 5.3+ strict, Express 4.18+, PostgreSQL 14+, Redis 7+
Standards: OpenAPI 3.0 specs, DRY/SOLID, zero `any` types
Quality: 18 unit test suites, 244 tests passing, 97%+ coverage
OpenAPI: 4 complete specs (14 endpoints total)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 09:14:41 +00:00

9.4 KiB

1. Project Bootstrap & Infrastructure

  • 1.1 Initialise package.json with all required dependencies (Express, TypeScript, Joi, jsonwebtoken, bcryptjs, uuid, pg, redis, pino, helmet, cors, dotenv, jest, supertest, ts-jest, ESLint, Prettier)
  • 1.2 Create tsconfig.json with strict mode enabled (all flags from README §6.4)
  • 1.3 Create .eslintrc.json with @typescript-eslint plugin and no-any rule
  • 1.4 Create .prettierrc
  • 1.5 Create jest.config.ts with ts-jest preset and coverage thresholds (>80%)
  • 1.6 Create docker-compose.yml with postgres:14-alpine and redis:7-alpine services
  • 1.7 Create .env.example documenting all required environment variables (DATABASE_URL, REDIS_URL, JWT_PRIVATE_KEY, JWT_PUBLIC_KEY, PORT, etc.)

2. Shared Infrastructure

  • 2.1 Create src/types/index.ts — all shared TypeScript interfaces (IAgent, ICredential, IAuditEvent, ITokenPayload, ICreateAgentRequest, IUpdateAgentRequest, etc.)
  • 2.2 Create src/utils/errors.ts — full SentryAgentError hierarchy (ValidationError, AgentNotFoundError, AgentAlreadyExistsError, CredentialError, AuthenticationError, AuthorizationError, RateLimitError, FreeTierLimitError)
  • 2.3 Create src/utils/crypto.tsgenerateClientSecret() (sk_live_ prefix + 64 hex), hashSecret(plain) (bcrypt 10 rounds), verifySecret(plain, hash) (bcrypt compare)
  • 2.4 Create src/utils/jwt.tssignToken(payload, privateKey) (RS256), verifyToken(token, publicKey) (returns typed payload), decodeToken(token) (no verification)
  • 2.5 Create src/utils/validators.ts — Joi schemas for CreateAgentRequest, UpdateAgentRequest, TokenRequest, IntrospectRequest, RevokeRequest, GenerateCredentialRequest, list query params
  • 2.6 Create src/db/pool.ts — typed pg.Pool singleton, reads DATABASE_URL from env
  • 2.7 Create src/cache/redis.ts — typed Redis client singleton, reads REDIS_URL from env
  • 2.8 Create src/db/migrations/001_create_agents.sqlagents table (all fields from OpenAPI spec, status as varchar)
  • 2.9 Create src/db/migrations/002_create_credentials.sqlcredentials table (credential_id, client_id, secret_hash, status, created_at, expires_at, revoked_at)
  • 2.10 Create src/db/migrations/003_create_audit_events.sqlaudit_events table (event_id, agent_id, action, outcome, ip_address, user_agent, metadata JSONB, timestamp)
  • 2.11 Create src/db/migrations/004_create_tokens.sqltoken_revocations table (jti, expires_at) for soft revocation tracking (supplementary to Redis)
  • 2.12 Create npm run db:migrate script to execute migrations in order

3. Middleware

  • 3.1 Create src/middleware/auth.ts — Bearer token extraction from Authorization header, RS256 JWT verification, Redis revocation check, attaches decoded payload to req.user; throws AuthenticationError on failure
  • 3.2 Create src/middleware/rateLimit.ts — Redis sliding window counter keyed by client_id; injects X-RateLimit-* headers on every response; throws RateLimitError at 100 req/min
  • 3.3 Create src/middleware/errorHandler.ts — Express error middleware; maps SentryAgentError subclasses to HTTP status codes and ErrorResponse JSON; maps unknown errors to 500

4. Agent Registry

  • 4.1 Create src/repositories/AgentRepository.ts — typed methods: create, findById, findByEmail, findAll (with filters + pagination), update, decommission, countByOwner; all SQL in this file only
  • 4.2 Create src/services/AgentService.tsregisterAgent, getAgentById, listAgents, updateAgent, decommissionAgent; enforces free-tier 100-agent limit; validates immutable fields on update; calls AuditService for all write operations; JSDoc on all public methods
  • 4.3 Create src/controllers/AgentController.ts — HTTP handlers for all 5 agent endpoints; Joi validation using validators.ts; delegates to AgentService; no business logic
  • 4.4 Create src/routes/agents.ts — Express router wiring AgentController handlers to paths with auth and rateLimit middleware

5. OAuth 2.0 Token Service

  • 5.1 Create src/repositories/TokenRepository.tsaddToRevocationList(jti, expiresAt), isRevoked(jti) (checks Redis first, then DB); incrementMonthlyCount(clientId), getMonthlyCount(clientId) (Redis-backed)
  • 5.2 Create src/services/OAuth2Service.tsissueToken (validates client credentials via bcrypt, checks agent status, enforces 10k monthly limit, signs RS256 JWT, writes audit event), introspectToken (verifies + checks revocation), revokeToken (adds JTI to Redis + DB revocation list, writes audit event); JSDoc on all public methods
  • 5.3 Create src/controllers/TokenController.ts — HTTP handlers for POST /token, POST /token/introspect, POST /token/revoke; parses application/x-www-form-urlencoded; delegates to OAuth2Service; returns OAuth2ErrorResponse for /token errors, ErrorResponse for introspect/revoke errors
  • 5.4 Create src/routes/token.ts — Express router; /token uses no Bearer auth middleware (credentials are in body); /token/introspect and /token/revoke use auth middleware

6. Credential Management

  • 6.1 Create src/repositories/CredentialRepository.tscreate, findById, findByAgentId (with pagination + status filter), updateHash, revoke, revokeAllForAgent; all SQL here only
  • 6.2 Create src/services/CredentialService.tsgenerateCredential (checks agent active status, generates secret via crypto.ts, bcrypt-hashes, persists), listCredentials, rotateCredential (generates new secret, replaces hash, same credentialId), revokeCredential; calls AuditService for all write operations; JSDoc on all public methods
  • 6.3 Create src/controllers/CredentialController.ts — HTTP handlers for all 4 credential endpoints; Joi validation; delegates to CredentialService
  • 6.4 Create src/routes/credentials.ts — Express router under /agents/:agentId/credentials with auth and rateLimit middleware

7. Audit Log Service

  • 7.1 Create src/repositories/AuditRepository.tscreate(event), findById(eventId), findAll(filters, pagination) with support for agentId, action, outcome, fromDate, toDate filtering and 90-day retention window enforcement
  • 7.2 Create src/services/AuditService.tslogEvent(agentId, action, outcome, ipAddress, userAgent, metadata) (async insert, fire-and-forget for token endpoints); queryEvents(filters, pagination), getEventById(eventId); enforces 90-day retention on queries; JSDoc on all public methods
  • 7.3 Create src/controllers/AuditController.ts — HTTP handlers for GET /audit and GET /audit/{eventId}; scope check for audit:read; Joi validation of query params
  • 7.4 Create src/routes/audit.ts — Express router with auth and rateLimit middleware

8. Application Assembly

  • 8.1 Create src/app.ts — Express app factory: registers helmet, cors, morgan/pino-http, JSON body parser, urlencoded body parser (for token endpoints), all 4 route modules, and errorHandler middleware; exported function (not called directly — testable)
  • 8.2 Create src/server.ts — imports app.ts, reads PORT from env, calls app.listen; entry point only

9. Unit Tests

  • 9.1 Write unit tests for src/utils/crypto.ts — secret generation format, bcrypt hash/verify round-trip
  • 9.2 Write unit tests for src/utils/jwt.ts — sign/verify/decode with RS256 test keys
  • 9.3 Write unit tests for src/utils/validators.ts — valid and invalid inputs for every Joi schema
  • 9.4 Write unit tests for src/services/AgentService.ts — mock AgentRepository and AuditService; cover all scenarios from agent-registry spec
  • 9.5 Write unit tests for src/services/OAuth2Service.ts — mock TokenRepository, CredentialRepository, AuditService; cover all scenarios from oauth2-token spec
  • 9.6 Write unit tests for src/services/CredentialService.ts — mock CredentialRepository, AgentRepository, AuditService; cover all scenarios from credential-management spec
  • 9.7 Write unit tests for src/services/AuditService.ts — mock AuditRepository; cover query, filter, and retention logic
  • 9.8 Write unit tests for src/middleware/auth.ts — valid token, expired token, revoked token, missing header
  • 9.9 Write unit tests for src/middleware/errorHandler.ts — each SentryAgentError subclass maps to correct HTTP status and error code

10. Integration Tests

  • 10.1 Write integration tests for Agent Registry (tests/integration/agents.test.ts) — all 5 endpoints, all response codes, pagination, filtering; uses real Postgres (test DB) and Redis
  • 10.2 Write integration tests for OAuth2 Token Service (tests/integration/token.test.ts) — all 3 endpoints, all response codes, token issuance and revocation flow, RFC compliance
  • 10.3 Write integration tests for Credential Management (tests/integration/credentials.test.ts) — all 4 endpoints, all response codes, full rotate-then-revoke flow
  • 10.4 Write integration tests for Audit Log Service (tests/integration/audit.test.ts) — query with all filter combinations, single event retrieval, retention window enforcement
  • 10.5 Verify test coverage meets >80% threshold across all services (npm test -- --coverage)