Files
stack/docs/scratchpads/361-credential-audit-viewer.md
Jason Woltje 6521cba735
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
feat: add flexible docker-compose architecture with profiles
- Add OpenBao services to docker-compose.yml with profiles (openbao, full)
- Add docker-compose.build.yml for local builds vs registry pulls
- Make PostgreSQL and Valkey optional via profiles (database, cache)
- Create example compose files for common deployment scenarios:
  - docker/docker-compose.example.turnkey.yml (all bundled)
  - docker/docker-compose.example.external.yml (all external)
  - docker/docker.example.hybrid.yml (mixed deployment)
- Update documentation:
  - Enhance .env.example with profiles and external service examples
  - Update README.md with deployment mode quick starts
  - Add deployment scenarios to docs/OPENBAO.md
  - Create docker/DOCKER-COMPOSE-GUIDE.md with comprehensive guide
- Clean up repository structure:
  - Move shell scripts to scripts/ directory
  - Move documentation to docs/ directory
  - Move docker compose examples to docker/ directory
- Configure for external Authentik with internal services:
  - Comment out Authentik services (using external OIDC)
  - Comment out unused volumes for disabled services
  - Keep postgres, valkey, openbao as internal services

This provides a flexible deployment architecture supporting turnkey,
production (all external), and hybrid configurations via Docker Compose
profiles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:55:33 -06:00

180 lines
6.7 KiB
Markdown

# Issue #361: Credential Audit Log Viewer
## Objective
Implement a credential audit log viewer to display all credential-related activities with filtering, pagination, and a PDA-friendly interface. This is a stretch goal for Phase 5c of M9-CredentialSecurity.
## Approach
1. **Backend**: Add audit query method to CredentialsService that filters ActivityLog by entityType=CREDENTIAL
2. **Backend**: Add GET /api/credentials/audit endpoint with filters (date range, action type, credential ID)
3. **Frontend**: Create page at /settings/credentials/audit
4. **Frontend**: Build AuditLogViewer component with:
- Date range filter
- Action type filter (CREATED, ACCESSED, ROTATED, UPDATED, etc.)
- Credential name filter
- Pagination (10-20 items per page)
- PDA-friendly timestamp formatting
- Mobile-responsive table layout
## Design Decisions
- **Reuse ActivityService.findAll()**: The existing query method supports all needed filters
- **RLS Enforcement**: Users see only their own workspace's activities
- **Pagination**: Default 20 items per page (matches web patterns)
- **Simple UI**: Stretch goal = minimal implementation, no complex features
- **Activity Types**: Filter by these actions:
- CREDENTIAL_CREATED
- CREDENTIAL_ACCESSED
- CREDENTIAL_ROTATED
- CREDENTIAL_REVOKED
- UPDATED (for metadata changes)
## Progress
- [x] Backend: Create CredentialAuditQueryDto
- [x] Backend: Add getAuditLog method to CredentialsService
- [x] Backend: Add getAuditLog endpoint to CredentialsController
- [x] Backend: Tests for audit query (25 tests all passing)
- [x] Frontend: Create audit page /settings/credentials/audit
- [x] Frontend: Create AuditLogViewer component
- [x] Frontend: Add audit log API client function
- [x] Frontend: Navigation link to audit log
- [ ] Testing: Manual E2E verification (when API integration complete)
- [ ] Documentation: Update if needed
## Testing
- [ ] API returns paginated results
- [ ] Filters work correctly (date range, action type, credential ID)
- [ ] RLS enforced (users see only their workspace data)
- [ ] Pagination works (next/prev buttons functional)
- [ ] Timestamps display correctly (PDA-friendly)
- [ ] Mobile layout is responsive
- [ ] UI gracefully handles empty state
## Notes
- Keep implementation simple - this is a stretch goal
- Leverage existing ActivityService patterns
- Follow PDA design principles (no aggressive language, clear status)
- No complex analytics needed
## Implementation Status
- Started: 2026-02-07
- Completed: 2026-02-07
## Files Created/Modified
### Backend
1. **apps/api/src/credentials/dto/query-credential-audit.dto.ts** (NEW)
- QueryCredentialAuditDto with filters: credentialId, action, startDate, endDate, page, limit
- Validation with class-validator decorators
- Default page=1, limit=20, max limit=100
2. **apps/api/src/credentials/dto/index.ts** (MODIFIED)
- Exported QueryCredentialAuditDto
3. **apps/api/src/credentials/credentials.service.ts** (MODIFIED)
- Added getAuditLog() method
- Filters by workspaceId and entityType=CREDENTIAL
- Returns paginated audit logs with user info
- Supports filtering by credentialId, action, and date range
- Returns metadata: total, page, limit, totalPages
4. **apps/api/src/credentials/credentials.controller.ts** (MODIFIED)
- Added GET /api/credentials/audit endpoint
- Placed before parameterized routes to avoid path conflicts
- Requires WORKSPACE_ANY permission (all members can view)
- Uses existing WorkspaceGuard for RLS enforcement
5. **apps/api/src/credentials/credentials.service.spec.ts** (MODIFIED)
- Added 8 comprehensive tests for getAuditLog():
- Returns paginated results
- Filters by credentialId
- Filters by action type
- Filters by date range
- Handles pagination correctly
- Orders by createdAt descending
- Always filters by CREDENTIAL entityType
### Frontend
1. **apps/web/src/lib/api/credentials.ts** (MODIFIED)
- Added AuditLogEntry interface
- Added QueryAuditLogDto interface
- Added fetchCredentialAuditLog() function
- Builds query string with optional parameters
2. **apps/web/src/app/(authenticated)/settings/credentials/audit/page.tsx** (NEW)
- Full audit log viewer page component
- Features:
- Filter by action type (dropdown with 5 options)
- Filter by date range (start and end date inputs)
- Pagination (20 items per page)
- Desktop table layout with responsive mobile cards
- PDA-friendly timestamp formatting
- Action badges with color coding
- User information display (name + email)
- Details display (credential name, provider)
- Empty state handling
- Error state handling
3. **apps/web/src/app/(authenticated)/settings/credentials/page.tsx** (MODIFIED)
- Added History icon import
- Added Link import for next/link
- Added "Audit Log" button linking to /settings/credentials/audit
- Button positioned in header next to "Add Credential"
## Design Decisions
1. **Activity Type Filtering**: Shows 5 main action types (CREATED, ACCESSED, ROTATED, REVOKED, UPDATED)
2. **Pagination**: Default 20 items per page (good balance for both mobile and desktop)
3. **PDA-Friendly Design**:
- No aggressive language
- Clear status indicators with colors
- Responsive layout for all screen sizes
- Timestamps in readable format
4. **Mobile Support**: Separate desktop table and mobile card layouts
5. **Reused Patterns**: Activity service already handles entity filtering
## Test Coverage
- Backend: 25 tests all passing
- Unit tests cover all major scenarios
- Tests use mocked PrismaService and ActivityService
- Async/parallel query testing included
## Notes
- Stretch goal kept simple and pragmatic
- Reused existing ActivityLog and ActivityService patterns
- RLS enforcement via existing WorkspaceGuard
- No complex analytics or exports needed
- All timestamps handled via browser Intl API for localization
## Build Status
- ✅ API builds successfully (`pnpm build` in apps/api)
- ✅ Web builds successfully (`pnpm build` in apps/web)
- ✅ All backend unit tests passing (25/25)
- ✅ TypeScript compilation successful for both apps
## Endpoints Implemented
- **GET /api/credentials/audit** - Fetch audit logs with filters
- Query params: credentialId, action, startDate, endDate, page, limit
- Response: Paginated audit logs with user info
- Authentication: Required (WORKSPACE_ANY permission)
## Frontend Routes Implemented
- **GET /settings/credentials** - Credentials management page (updated with audit log link)
- **GET /settings/credentials/audit** - Credential audit log viewer page
## API Client Functions
- `fetchCredentialAuditLog(workspaceId, query?)` - Get paginated audit logs with optional filters