Phase 23: per-stack secrets & configs (compose file-based), local + agent (0.29.0)

Manage Docker secrets and configs per stack from a new Secrets tab on Stack/
RemoteStackDetail. Content is stored as files inside the stack dir
(.secrets/<name>, .configs/<name>; dir 0700 / file 0600) and referenced from the
compose file with relative `file:` paths, so the daemon reads them without any
HOST_ROOT_PREFIX dependency. Content is write-only — the API only ever returns
metadata (name, kind, size).

- secret_service: write/delete/list (metadata only)/exists/rel_path/attach/detach;
  name validation rejects traversal/hidden/separators, content capped at 1 MiB.
- compose_edit_service: add/remove secret and config (top-level defs pruned when
  no service still references them).
- routers/secrets.py (admin-only, audit secret.*) + agent endpoints + multi-host
  proxy (audit agent.secret.*).
- Frontend SecretsPanel (create/list/delete + per-row attach/detach to a service;
  config rows take a mount target), agentId-aware for remote stacks.

Verified: name-sandbox + perms + metadata-only listing unit-tested; compose
add/remove round-trips to clean YAML; py_compile + backend/agent/frontend image
builds + route smoke-test (local/agent/proxy). Live exec check (/run/secrets/<name>
on a deployed stack) and swarm path are hardware-verify debt (swarm dropped: A).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
menzelj
2026-06-09 15:01:21 +00:00
co-authored by Claude Opus 4.8
parent 255c8441c6
commit 6464e0677c
13 changed files with 879 additions and 50 deletions
+23 -1
View File
@@ -10,7 +10,9 @@ as intuitive as Dockge, as capable as Portainer for Compose workflows.
> network attach) + Phase 12 (File browser) + Phase 13 (Multi-host networks &
> images) + Phase 14 (Multi-host file browser) + Phase 15 (Dashboard stack
> resource usage) + Phase 16 (Volumes page, multi-host) + Phase 17 (Multi-host
> dashboard) complete.
> dashboard) + Phase 18 (Image prune) + Phase 19 (Compose validate & diff) +
> Phase 20 (Container management) + Phase 21 (Container terminal) + Phase 22
> (Auto-update) + Phase 23 (Secrets & configs) complete.
## What works today (Phase 1)
@@ -153,6 +155,26 @@ as intuitive as Dockge, as capable as Portainer for Compose workflows.
container or connect any container on the host (`POST /api/networks/{id}/connect`
/ `/disconnect`).
### Phase 23 — Secrets & configs (compose file-based)
- A **Secrets** tab on the stack detail page manages per-stack Docker
**secrets** and **configs**: create one by name + content, list them (name,
kind, size — content is **never** returned by the API), and delete. Content is
write-only: once saved it is cleared from the form and cannot be read back.
- Files are stored inside the stack's own directory (`<stack_dir>/.secrets/<name>`
/ `.configs/<name>`, dir `0700` / file `0600`) and referenced from the compose
file with a **relative** `file:` path, so the Docker daemon reads them with no
`HOST_ROOT_PREFIX` dependency — exactly as if dropped next to `compose.yaml`.
- **Attach/detach** wires a stored secret/config into a chosen service: secrets
appear at `/run/secrets/<name>`, configs mount at a target path you specify. The
compose file is rewritten in place (top-level `secrets:`/`configs:` defs are
pruned when no service still uses them); **redeploy the stack to apply**.
- **Admin-only** (secrets are sensitive); every write/delete/attach/detach is
audited (`secret.*`). Works for **remote stacks** too — the agent stores the
files on its own host (`/agent/stacks/{id}/secrets/*`, proxied via
`/api/agents/{id}/stacks/{id}/secrets/*`). Names are validated against path
traversal (single component, no `..`, no leading dot); content capped at 1 MiB.
### Phase 22 — Auto-update (Watchtower-style)
- A per-stack **Auto-update** policy (on the stack Overview tab): when the