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>
181 lines
5.9 KiB
Markdown
181 lines
5.9 KiB
Markdown
# Issue #358: Build frontend credential management pages
|
|
|
|
## Objective
|
|
|
|
Create frontend credential management pages at `/settings/credentials` with full CRUD operations, following PDA-friendly design principles and existing UI patterns.
|
|
|
|
## Backend API Reference
|
|
|
|
- `POST /api/credentials` - Create (encrypt + store)
|
|
- `GET /api/credentials` - List (masked values only)
|
|
- `GET /api/credentials/:id` - Get single (masked)
|
|
- `GET /api/credentials/:id/value` - Decrypt and return value (rate-limited)
|
|
- `PATCH /api/credentials/:id` - Update metadata only
|
|
- `POST /api/credentials/:id/rotate` - Replace value
|
|
- `DELETE /api/credentials/:id` - Soft delete
|
|
|
|
## Approach
|
|
|
|
### 1. Component Architecture
|
|
|
|
```
|
|
/app/(authenticated)/settings/credentials/
|
|
└── page.tsx (main list + modal orchestration)
|
|
|
|
/components/credentials/
|
|
├── CredentialList.tsx (card grid)
|
|
├── CredentialCard.tsx (individual credential display)
|
|
├── CreateCredentialDialog.tsx (create form)
|
|
├── EditCredentialDialog.tsx (metadata edit)
|
|
├── ViewCredentialDialog.tsx (reveal value)
|
|
├── RotateCredentialDialog.tsx (rotate value)
|
|
└── DeleteCredentialDialog.tsx (confirm deletion)
|
|
|
|
/lib/api/
|
|
└── credentials.ts (API client functions)
|
|
```
|
|
|
|
### 2. UI Patterns (from existing code)
|
|
|
|
- Use shadcn/ui components: `Card`, `Button`, `Badge`, `AlertDialog`
|
|
- Follow personalities page pattern for list/modal state management
|
|
- Use lucide-react icons: `Plus`, `Eye`, `EyeOff`, `Pencil`, `RotateCw`, `Trash2`
|
|
- Mobile-first responsive design
|
|
|
|
### 3. Security Requirements
|
|
|
|
- **NEVER display plaintext in list** - only `maskedValue`
|
|
- **Reveal button** requires explicit click
|
|
- **Auto-hide revealed value** after 30 seconds
|
|
- **Warn user** before revealing (security-conscious UX)
|
|
- Show rate-limit warnings (10 requests/minute)
|
|
|
|
### 4. PDA-Friendly Language
|
|
|
|
```
|
|
❌ NEVER ✅ ALWAYS
|
|
─────────────────────────────────────────
|
|
"Delete credential" "Remove credential"
|
|
"EXPIRED" "Past target date"
|
|
"CRITICAL" "High priority"
|
|
"You must rotate" "Consider rotating"
|
|
```
|
|
|
|
## Progress
|
|
|
|
- [x] Read issue details and design doc
|
|
- [x] Study existing patterns (personalities page)
|
|
- [x] Identify available UI components
|
|
- [x] Create API client functions (`lib/api/credentials.ts`)
|
|
- [x] Create dialog component (`components/ui/dialog.tsx`)
|
|
- [x] Create credential components
|
|
- [x] CreateCredentialDialog.tsx
|
|
- [x] ViewCredentialDialog.tsx (with reveal + auto-hide)
|
|
- [x] EditCredentialDialog.tsx
|
|
- [x] RotateCredentialDialog.tsx
|
|
- [x] CredentialCard.tsx
|
|
- [x] Create settings page (`app/(authenticated)/settings/credentials/page.tsx`)
|
|
- [x] TypeScript typecheck passes
|
|
- [x] Build passes
|
|
- [ ] Add navigation link to settings
|
|
- [ ] Manual testing
|
|
- [ ] Verify PDA language compliance
|
|
- [ ] Mobile responsiveness check
|
|
|
|
## Implementation Notes
|
|
|
|
### Missing UI Components
|
|
|
|
- Need to add `dialog.tsx` from shadcn/ui
|
|
- Have: `alert-dialog`, `card`, `button`, `badge`, `input`, `label`, `textarea`
|
|
|
|
### Provider Icons
|
|
|
|
Support providers: GitHub, GitLab, OpenAI, Bitbucket, Custom
|
|
|
|
- Use lucide-react icons or provider-specific SVGs
|
|
- Fallback to generic `Key` icon
|
|
|
|
### State Management
|
|
|
|
Follow personalities page pattern:
|
|
|
|
```typescript
|
|
const [mode, setMode] = useState<"list" | "create" | "edit" | "view" | "rotate">("list");
|
|
const [selectedCredential, setSelectedCredential] = useState<Credential | null>(null);
|
|
```
|
|
|
|
## Testing
|
|
|
|
- [ ] Create credential flow
|
|
- [ ] Edit metadata (name, description)
|
|
- [ ] Reveal value (with auto-hide)
|
|
- [ ] Rotate credential
|
|
- [ ] Delete credential
|
|
- [ ] Error handling (validation, API errors)
|
|
- [ ] Rate limiting on reveal
|
|
- [ ] Empty state display
|
|
- [ ] Mobile layout
|
|
|
|
## Notes
|
|
|
|
- Backend API complete (commit 46d0a06)
|
|
- RLS enforced - users only see own credentials
|
|
- Activity logging automatic on backend
|
|
- Custom UI components (no Radix UI dependencies)
|
|
- Dialog component created matching existing alert-dialog pattern
|
|
- Navigation: Direct URL access at `/settings/credentials` (no nav link added - settings accessed directly)
|
|
- Workspace ID: Currently hardcoded as placeholder - needs context integration
|
|
|
|
## Files Created
|
|
|
|
```
|
|
apps/web/src/
|
|
├── components/
|
|
│ ├── ui/
|
|
│ │ └── dialog.tsx (new custom dialog component)
|
|
│ └── credentials/
|
|
│ ├── index.ts
|
|
│ ├── CreateCredentialDialog.tsx
|
|
│ ├── ViewCredentialDialog.tsx
|
|
│ ├── EditCredentialDialog.tsx
|
|
│ ├── RotateCredentialDialog.tsx
|
|
│ └── CredentialCard.tsx
|
|
├── lib/api/
|
|
│ └── credentials.ts (API client with PDA-friendly helpers)
|
|
└── app/(authenticated)/settings/credentials/
|
|
└── page.tsx (main credentials management page)
|
|
```
|
|
|
|
## PDA Language Verification
|
|
|
|
✅ All dialogs use PDA-friendly language:
|
|
|
|
- "Remove credential" instead of "Delete"
|
|
- "Past target date" instead of "EXPIRED"
|
|
- "Approaching target" instead of "URGENT"
|
|
- "Consider rotating" instead of "MUST rotate"
|
|
- Warning messages use informative tone, not demanding
|
|
|
|
## Security Features Implemented
|
|
|
|
✅ Masked values only in list view
|
|
✅ Reveal requires explicit user action (with warning)
|
|
✅ Auto-hide revealed value after 30 seconds
|
|
✅ Copy-to-clipboard for revealed values
|
|
✅ Manual hide button for revealed values
|
|
✅ Rate limit warning on reveal errors
|
|
✅ Password input fields for sensitive values
|
|
✅ Security warnings before revealing
|
|
|
|
## Next Steps for Production
|
|
|
|
- [ ] Integrate workspace context (remove hardcoded workspace ID)
|
|
- [ ] Add settings navigation menu or dropdown
|
|
- [ ] Test with real OpenBao backend
|
|
- [ ] Add loading states for API calls
|
|
- [ ] Add optimistic updates for better UX
|
|
- [ ] Add filtering/search for large credential lists
|
|
- [ ] Add pagination for credential list
|
|
- [ ] Write component tests
|