All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- 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>
6.7 KiB
6.7 KiB
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
- Backend: Add audit query method to CredentialsService that filters ActivityLog by entityType=CREDENTIAL
- Backend: Add GET /api/credentials/audit endpoint with filters (date range, action type, credential ID)
- Frontend: Create page at /settings/credentials/audit
- 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
- Backend: Create CredentialAuditQueryDto
- Backend: Add getAuditLog method to CredentialsService
- Backend: Add getAuditLog endpoint to CredentialsController
- Backend: Tests for audit query (25 tests all passing)
- Frontend: Create audit page /settings/credentials/audit
- Frontend: Create AuditLogViewer component
- Frontend: Add audit log API client function
- 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
-
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
-
apps/api/src/credentials/dto/index.ts (MODIFIED)
- Exported QueryCredentialAuditDto
-
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
-
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
-
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
- Added 8 comprehensive tests for getAuditLog():
Frontend
-
apps/web/src/lib/api/credentials.ts (MODIFIED)
- Added AuditLogEntry interface
- Added QueryAuditLogDto interface
- Added fetchCredentialAuditLog() function
- Builds query string with optional parameters
-
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
-
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
- Activity Type Filtering: Shows 5 main action types (CREATED, ACCESSED, ROTATED, REVOKED, UPDATED)
- Pagination: Default 20 items per page (good balance for both mobile and desktop)
- PDA-Friendly Design:
- No aggressive language
- Clear status indicators with colors
- Responsive layout for all screen sizes
- Timestamps in readable format
- Mobile Support: Separate desktop table and mobile card layouts
- 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 buildin apps/api) - ✅ Web builds successfully (
pnpm buildin 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