- Add frontend-foundation change (FN-005) with 46 tasks - Add deployment-config change (FN-006) with 27 tasks - Add runfusion-poc/opencode-poc change (FN-008) with 25 tasks - Add config-secrets change (FN-009) with 31 tasks - Add codeserver-spawn change (FN-010) with 38 tasks - Include project specsheet and configuration - Archive completed deployment-config change
2.5 KiB
Context
The backend has Config and Secret models (FN-004) with scope fields, but no frontend UI or runtime injection. SSH keys already use Fernet encryption (FN-011), so the encryption pattern is established. This design completes the config/secrets lifecycle.
Current state:
- Config model: key, value, scope (global/user/project/instance), scope_id
- Secret model: key, encrypted_value, scope, scope_id
- Fernet encryption utilities exist in app/encryption.py
- No UI for management
- No runtime injection into containers
Goals / Non-Goals
Goals:
- Allow users to manage configs and secrets via UI
- Inject configs/secrets into tool containers at spawn time
- Support scope-based inheritance (instance overrides project overrides user overrides global)
- Maintain encryption for all secret values
Non-Goals:
- Secret versioning or history
- Automatic secret rotation
- Integration with external secret managers (Vault, AWS Secrets Manager)
- Config/secrets for non-tool resources
Decisions
1. Mount configs as files, secrets as env vars
- Rationale: Configs (JSON) are often files (e.g., settings.json). Secrets are typically env vars.
- Config mount:
/app/config/<key>.json - Secret env:
<KEY>=<decrypted_value>
2. Scope resolution: closest match wins
- Rationale: Instance-specific values should override project defaults
- Resolution order: instance → project → user → global
3. Secret values never sent to frontend decrypted
- Rationale: Security. Frontend only sees masked values (e.g.,
••••••). - Decryption happens only in backend during runtime injection
4. Config values are plaintext (not encrypted)
- Rationale: Configs are not sensitive. Encrypting them adds complexity without security benefit.
Risks / Trade-offs
[Risk] Secret injection at spawn time could fail silently → Mitigation: Validate all referenced secrets exist before spawning. Return error if missing.
[Risk] Config files in containers could be read by other processes → Mitigation: Mount config files with restrictive permissions (0400). Run containers as non-root.
[Risk] Large configs could exceed container env var limits → Mitigation: Document size limits. Consider config file mounting for large values.
Migration Plan
No migration needed. This extends existing models.
Open Questions
- Should configs support JSON schema validation?
- Do we need bulk import/export for configs/secrets?
- Should secret keys be validated against a naming convention?