# Issue #356: Build credential CRUD API endpoints ## Objective Implement CRUD API endpoints for managing user credentials with encryption, RLS, and audit logging. ## Approach Following TDD approach: 1. Create DTOs with validation 2. Write service tests first (RED) 3. Implement service with VaultService integration (GREEN) 4. Write controller tests (RED) 5. Implement controller with guards (GREEN) 6. Create module and wire dependencies 7. Verify all tests pass with 85%+ coverage ## Key Patterns Followed - RLS: Use `getRlsClient() ?? this.prisma` pattern - Encryption: Use VaultService with TransitKey.CREDENTIALS - Activity logging: Fire-and-forget pattern like existing activity helpers - DTOs: class-validator decorators for input validation - Guards: AuthGuard + WorkspaceGuard + PermissionGuard - Rate limiting: @Throttle decorator on getValue endpoint (10/minute) ## Files Created - [x] apps/api/src/credentials/dto/create-credential.dto.ts - [x] apps/api/src/credentials/dto/update-credential.dto.ts - [x] apps/api/src/credentials/dto/query-credential.dto.ts - [x] apps/api/src/credentials/dto/credential-response.dto.ts - [x] apps/api/src/credentials/dto/rotate-credential.dto.ts - [x] apps/api/src/credentials/dto/index.ts - [x] apps/api/src/credentials/credentials.service.spec.ts (18 tests - all passing) - [x] apps/api/src/credentials/credentials.service.ts - [x] apps/api/src/credentials/credentials.controller.spec.ts (8 tests - all passing) - [x] apps/api/src/credentials/credentials.controller.ts - [x] apps/api/src/credentials/credentials.module.ts - [x] apps/api/src/credentials/index.ts ## Files Modified - [x] apps/api/src/app.module.ts - imported CredentialsModule ## Admin Credentials Controller **Decision: Not implemented in this phase** - Issue #356 listed admin endpoints as optional ("Admin Secret Endpoints") - The UserCredential model supports SYSTEM scope for admin secrets - Admin endpoints can be added in a future issue when needed - Current implementation covers all user credential endpoints ## Testing Results - Service tests: 18/18 passing - Controller tests: 8/8 passing - Total: 26/26 tests passing - Coverage: **95.71%** (exceeds 85% requirement) - Service: 95.16% - Controller: 100% - TypeScript: All checks pass ## Endpoints Implemented - POST /api/credentials - Create credential - GET /api/credentials - List credentials (masked values only) - GET /api/credentials/:id - Get single credential (masked value only) - GET /api/credentials/:id/value - Decrypt and return plaintext (rate limited 10/min) - PATCH /api/credentials/:id - Update metadata - POST /api/credentials/:id/rotate - Rotate credential value - DELETE /api/credentials/:id - Soft delete ## Security Features - All credential values encrypted with VaultService (TransitKey.CREDENTIALS) - List/Get endpoints NEVER return plaintext (only maskedValue) - getValue endpoint rate limited to 10 requests/minute per user - All operations audit-logged with CREDENTIAL\_\* ActivityAction enums - RLS enforces per-user isolation - Input validation via class-validator DTOs ## Notes - CREDENTIAL\_\* ActivityAction enums already existed in schema (from issue #355) - Used existing activity logging pattern (fire-and-forget) - Followed existing controller patterns for guards and decorators - maskedValue shows last 4 characters with \*\*\*\* prefix - TypeScript exactOptionalPropertyTypes required careful handling in update method