feat: implement SSH key management

- Add backend API endpoints for SSH key CRUD (POST, GET, DELETE)
- Implement Ed25519 key generation with Fernet-encrypted private keys
- Add frontend SSH keys page with generate, list, and delete functionality
- Include copy-to-clipboard for public keys
- Add responsive CSS styles for key cards
- Register ssh_keys router in main.py
- Add basic auth tests for SSH key endpoints

Quality gates: ruff ✓, mypy ✓, typecheck ✓, lint ✓
This commit is contained in:
Fusion
2026-05-18 14:44:21 +02:00
parent be81aa1c8b
commit a441ea2fac
24 changed files with 500 additions and 369 deletions
@@ -0,0 +1,51 @@
## Context
The SSHKey model exists in the database but there's no API to create, list, or manage SSH keys. Users need SSH keys for git operations with external providers.
## Goals / Non-Goals
**Goals:**
- Generate Ed25519 SSH key pairs via API
- Encrypt private keys with Fernet before storage
- List user's SSH keys with public key display
- Support copying public keys to clipboard
- Allow deletion of SSH keys
**Non-Goals:**
- RSA key generation (Ed25519 only)
- Private key display/decryption to users
- SSH key editing (name changes only via update)
- Integration with git operations (separate feature)
## Decisions
1. **Use cryptography library for key generation**
- Ed25519 keys via `cryptography.hazmat.primitives.asymmetric.ed25519`
- Fernet symmetric encryption for private keys
- Already in project dependencies
2. **Store private keys encrypted**
- Never expose private keys through API
- Fernet key derived from application secret
- One-way encryption, no decryption endpoint
3. **Frontend uses simple table/list view**
- Name, created date, public key preview
- Copy button for full public key
- Generate and delete actions
## Risks / Trade-offs
- **[Fernet key rotation loses access to old keys]** → Document that rotating JWT_SECRET effectively locks old SSH keys
- **[Private key storage is only as secure as Fernet key]** → Store Fernet key securely, use strong application secret
## Migration Plan
1. Create API endpoints
2. Add frontend page
3. Register router
4. Run tests
## Open Questions
- Should we allow SSH key naming during generation?