Adds the full bedroom-developer-docs OpenSpec change implementation: - docs/developers/README.md — index page - docs/developers/quick-start.md — bootstrap to working token in 7 steps - docs/developers/concepts.md — AgentIdP, AGNTCY, lifecycle, OAuth 2.0, free tier - docs/developers/guides/README.md — guide index - docs/developers/guides/register-an-agent.md — all fields, validation, common errors - docs/developers/guides/manage-credentials.md — generate, list, rotate, revoke - docs/developers/guides/issue-and-revoke-tokens.md — OAuth 2.0 flow, introspect, revoke - docs/developers/guides/query-audit-logs.md — filters, pagination, 90-day retention - docs/developers/api-reference.md — all 14 endpoints, all error codes, curl examples Also commits deferred OpenSpec housekeeping from previous session: - Archives phase-1-mvp-implementation change to openspec/changes/archive/ - Adds bedroom-developer-docs change artifacts (30/30 tasks complete) - Syncs 4 delta specs to openspec/specs/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
84 lines
9.4 KiB
Markdown
84 lines
9.4 KiB
Markdown
## 1. Project Bootstrap & Infrastructure
|
|
|
|
- [x] 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)
|
|
- [x] 1.2 Create `tsconfig.json` with strict mode enabled (all flags from README §6.4)
|
|
- [x] 1.3 Create `.eslintrc.json` with `@typescript-eslint` plugin and no-`any` rule
|
|
- [x] 1.4 Create `.prettierrc`
|
|
- [x] 1.5 Create `jest.config.ts` with `ts-jest` preset and coverage thresholds (>80%)
|
|
- [x] 1.6 Create `docker-compose.yml` with `postgres:14-alpine` and `redis:7-alpine` services
|
|
- [x] 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
|
|
|
|
- [x] 2.1 Create `src/types/index.ts` — all shared TypeScript interfaces (`IAgent`, `ICredential`, `IAuditEvent`, `ITokenPayload`, `ICreateAgentRequest`, `IUpdateAgentRequest`, etc.)
|
|
- [x] 2.2 Create `src/utils/errors.ts` — full `SentryAgentError` hierarchy (`ValidationError`, `AgentNotFoundError`, `AgentAlreadyExistsError`, `CredentialError`, `AuthenticationError`, `AuthorizationError`, `RateLimitError`, `FreeTierLimitError`)
|
|
- [x] 2.3 Create `src/utils/crypto.ts` — `generateClientSecret()` (sk_live_ prefix + 64 hex), `hashSecret(plain)` (bcrypt 10 rounds), `verifySecret(plain, hash)` (bcrypt compare)
|
|
- [x] 2.4 Create `src/utils/jwt.ts` — `signToken(payload, privateKey)` (RS256), `verifyToken(token, publicKey)` (returns typed payload), `decodeToken(token)` (no verification)
|
|
- [x] 2.5 Create `src/utils/validators.ts` — Joi schemas for `CreateAgentRequest`, `UpdateAgentRequest`, `TokenRequest`, `IntrospectRequest`, `RevokeRequest`, `GenerateCredentialRequest`, list query params
|
|
- [x] 2.6 Create `src/db/pool.ts` — typed `pg.Pool` singleton, reads `DATABASE_URL` from env
|
|
- [x] 2.7 Create `src/cache/redis.ts` — typed Redis client singleton, reads `REDIS_URL` from env
|
|
- [x] 2.8 Create `src/db/migrations/001_create_agents.sql` — `agents` table (all fields from OpenAPI spec, `status` as varchar)
|
|
- [x] 2.9 Create `src/db/migrations/002_create_credentials.sql` — `credentials` table (`credential_id`, `client_id`, `secret_hash`, `status`, `created_at`, `expires_at`, `revoked_at`)
|
|
- [x] 2.10 Create `src/db/migrations/003_create_audit_events.sql` — `audit_events` table (`event_id`, `agent_id`, `action`, `outcome`, `ip_address`, `user_agent`, `metadata` JSONB, `timestamp`)
|
|
- [x] 2.11 Create `src/db/migrations/004_create_tokens.sql` — `token_revocations` table (`jti`, `expires_at`) for soft revocation tracking (supplementary to Redis)
|
|
- [x] 2.12 Create `npm run db:migrate` script to execute migrations in order
|
|
|
|
## 3. Middleware
|
|
|
|
- [x] 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
|
|
- [x] 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
|
|
- [x] 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
|
|
|
|
- [x] 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
|
|
- [x] 4.2 Create `src/services/AgentService.ts` — `registerAgent`, `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
|
|
- [x] 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
|
|
- [x] 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
|
|
|
|
- [x] 5.1 Create `src/repositories/TokenRepository.ts` — `addToRevocationList(jti, expiresAt)`, `isRevoked(jti)` (checks Redis first, then DB); `incrementMonthlyCount(clientId)`, `getMonthlyCount(clientId)` (Redis-backed)
|
|
- [x] 5.2 Create `src/services/OAuth2Service.ts` — `issueToken` (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
|
|
- [x] 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
|
|
- [x] 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
|
|
|
|
- [x] 6.1 Create `src/repositories/CredentialRepository.ts` — `create`, `findById`, `findByAgentId` (with pagination + status filter), `updateHash`, `revoke`, `revokeAllForAgent`; all SQL here only
|
|
- [x] 6.2 Create `src/services/CredentialService.ts` — `generateCredential` (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
|
|
- [x] 6.3 Create `src/controllers/CredentialController.ts` — HTTP handlers for all 4 credential endpoints; Joi validation; delegates to `CredentialService`
|
|
- [x] 6.4 Create `src/routes/credentials.ts` — Express router under `/agents/:agentId/credentials` with `auth` and `rateLimit` middleware
|
|
|
|
## 7. Audit Log Service
|
|
|
|
- [x] 7.1 Create `src/repositories/AuditRepository.ts` — `create(event)`, `findById(eventId)`, `findAll(filters, pagination)` with support for `agentId`, `action`, `outcome`, `fromDate`, `toDate` filtering and 90-day retention window enforcement
|
|
- [x] 7.2 Create `src/services/AuditService.ts` — `logEvent(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
|
|
- [x] 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
|
|
- [x] 7.4 Create `src/routes/audit.ts` — Express router with `auth` and `rateLimit` middleware
|
|
|
|
## 8. Application Assembly
|
|
|
|
- [x] 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)
|
|
- [x] 8.2 Create `src/server.ts` — imports `app.ts`, reads `PORT` from env, calls `app.listen`; entry point only
|
|
|
|
## 9. Unit Tests
|
|
|
|
- [x] 9.1 Write unit tests for `src/utils/crypto.ts` — secret generation format, bcrypt hash/verify round-trip
|
|
- [x] 9.2 Write unit tests for `src/utils/jwt.ts` — sign/verify/decode with RS256 test keys
|
|
- [x] 9.3 Write unit tests for `src/utils/validators.ts` — valid and invalid inputs for every Joi schema
|
|
- [x] 9.4 Write unit tests for `src/services/AgentService.ts` — mock `AgentRepository` and `AuditService`; cover all scenarios from agent-registry spec
|
|
- [x] 9.5 Write unit tests for `src/services/OAuth2Service.ts` — mock `TokenRepository`, `CredentialRepository`, `AuditService`; cover all scenarios from oauth2-token spec
|
|
- [x] 9.6 Write unit tests for `src/services/CredentialService.ts` — mock `CredentialRepository`, `AgentRepository`, `AuditService`; cover all scenarios from credential-management spec
|
|
- [x] 9.7 Write unit tests for `src/services/AuditService.ts` — mock `AuditRepository`; cover query, filter, and retention logic
|
|
- [x] 9.8 Write unit tests for `src/middleware/auth.ts` — valid token, expired token, revoked token, missing header
|
|
- [x] 9.9 Write unit tests for `src/middleware/errorHandler.ts` — each `SentryAgentError` subclass maps to correct HTTP status and error code
|
|
|
|
## 10. Integration Tests
|
|
|
|
- [x] 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
|
|
- [x] 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
|
|
- [x] 10.3 Write integration tests for Credential Management (`tests/integration/credentials.test.ts`) — all 4 endpoints, all response codes, full rotate-then-revoke flow
|
|
- [x] 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
|
|
- [x] 10.5 Verify test coverage meets >80% threshold across all services (`npm test -- --coverage`)
|