feat(FN-009): implement config and secrets management with runtime injection
- Add RuntimeInjectionService for scope-based config/secret resolution - Mount configs as JSON files at /app/config/ with 0400 permissions - Inject secrets as environment variables with uppercase keys - Implement scope hierarchy: instance > project > user > global - Create ConfigListPage and SecretListPage frontend components - Mask secret values in API responses (never expose decrypted) - Validate secrets exist before spawning containers - Add comprehensive tests for runtime injection service - Update documentation with config/secrets workflow
This commit is contained in:
@@ -259,3 +259,67 @@ docker network create tools # One-time setup
|
||||
```
|
||||
|
||||
Spawned containers use the `tools` network for Traefik routing.
|
||||
|
||||
## Config & Secrets
|
||||
|
||||
### Overview
|
||||
|
||||
The platform supports scoped configuration values and encrypted secrets that are injected into tool containers at spawn time.
|
||||
|
||||
### Scopes
|
||||
|
||||
Configs and secrets support four scope levels (closest match wins):
|
||||
|
||||
1. **Global** — Available to all users and projects
|
||||
2. **User** — Available to a specific user across all projects
|
||||
3. **Project** — Available within a specific project
|
||||
4. **Instance** — Available to a specific tool instance
|
||||
|
||||
### Configs
|
||||
|
||||
Configs are plaintext JSON values mounted as files into containers:
|
||||
|
||||
- Mount path: `/app/config/<key>.json`
|
||||
- Permissions: `0400` (read-only, owner-only)
|
||||
- Scope resolution: instance > project > user > global
|
||||
|
||||
**API Endpoints:**
|
||||
- `POST /configs` — Create config
|
||||
- `GET /configs` — List configs (filter by scope_type, scope_id)
|
||||
- `PUT /configs/{id}` — Update config value
|
||||
- `DELETE /configs/{id}` — Delete config
|
||||
|
||||
**Frontend:**
|
||||
- `/projects/{id}/configs` — Config management UI
|
||||
|
||||
### Secrets
|
||||
|
||||
Secrets are encrypted with Fernet and injected as environment variables:
|
||||
|
||||
- Env var format: `<UPPERCASE_KEY>=<decrypted_value>`
|
||||
- Values are never sent to the frontend decrypted (displayed as `••••••`)
|
||||
- Scope resolution: instance > project > user > global
|
||||
|
||||
**API Endpoints:**
|
||||
- `POST /secrets` — Create secret
|
||||
- `GET /secrets` — List secrets (filter by scope_type, scope_id)
|
||||
- `PUT /secrets/{id}` — Update secret value
|
||||
- `DELETE /secrets/{id}` — Delete secret
|
||||
|
||||
**Frontend:**
|
||||
- `/projects/{id}/secrets` — Secret management UI
|
||||
|
||||
### Runtime Injection
|
||||
|
||||
When a tool instance is spawned:
|
||||
|
||||
1. Configs are resolved from all applicable scopes
|
||||
2. Secrets are resolved and decrypted
|
||||
3. Config files are generated in `/tmp/headquarter-configs/{instance_id}/`
|
||||
4. Config files are mounted as read-only volumes
|
||||
5. Secrets are injected as environment variables
|
||||
6. Missing required secrets will fail the spawn with a clear error
|
||||
|
||||
### Validation
|
||||
|
||||
Before spawning, the system validates that all required secrets exist. If any are missing, the spawn fails with an error message listing the missing secrets.
|
||||
|
||||
Reference in New Issue
Block a user