feat(paperless): automated secret-key rotation (openbao-ns pattern) #300

Merged
k.renner merged 2 commits from feat/paperless-secret-rotation into master 2026-07-18 19:45:21 +00:00
Member

First fan-out of the secret-rotation pattern (proven on woodpecker in #297), now using the cleaner openbao-namespace design.

Why openbao-ns

The rotation Job runs in the openbao namespace → reaches OpenBao intra-namespace → no NetworkPolicy edits (woodpecker's apps-ns job needed the apps↔openbao netpol pair in #299; this avoids that entirely).

Per-secret isolation

Its own scoped policy+role rotator-paperless (patch on homelab/data/apps/paperless only) — a compromised paperless job can't touch any other secret (#213/#202).

Contents

  • openbao/rotation/paperless.yaml: SA + quarterly/on-demand CronJob (openbao ns) → bao kv patch secret-key (DB creds in the same KV entry preserved).
  • openbao/policies/rotator-paperless.hcl: least-privilege policy (manual one-time bootstrap, documented in-file).
  • paperless.yaml: Reloader annotation; externalsecret.yaml: refreshInterval 1h→10m.

Impact

Rotating the Django SECRET_KEY invalidates paperless sessions (re-login) — no data loss. Requires the one-time OpenBao bootstrap (rotator-paperless policy+role) before first run. Verified: kustomize + yamllint clean.

First fan-out of the secret-rotation pattern (proven on woodpecker in #297), now using the cleaner **openbao-namespace** design. ## Why openbao-ns The rotation Job runs in the `openbao` namespace → reaches OpenBao **intra-namespace** → **no NetworkPolicy edits** (woodpecker's apps-ns job needed the apps↔openbao netpol pair in #299; this avoids that entirely). ## Per-secret isolation Its own scoped policy+role `rotator-paperless` (patch on `homelab/data/apps/paperless` only) — a compromised paperless job can't touch any other secret (#213/#202). ## Contents - `openbao/rotation/paperless.yaml`: SA + quarterly/on-demand CronJob (openbao ns) → `bao kv patch secret-key` (DB creds in the same KV entry preserved). - `openbao/policies/rotator-paperless.hcl`: least-privilege policy (manual one-time bootstrap, documented in-file). - `paperless.yaml`: Reloader annotation; `externalsecret.yaml`: refreshInterval 1h→10m. ## Impact Rotating the Django SECRET_KEY invalidates paperless sessions (re-login) — **no data loss**. Requires the one-time OpenBao bootstrap (rotator-paperless policy+role) before first run. Verified: kustomize + yamllint clean.
claude-bot added 1 commit 2026-07-18 19:31:00 +00:00
First fan-out of the secret-rotation pattern proven on woodpecker, now using the cleaner openbao-namespace design: the rotation Job runs in the openbao ns so it reaches OpenBao intra-namespace — NO NetworkPolicy edits needed (unlike woodpecker's apps-ns job). Per-secret isolation: its own scoped policy+role (rotator-paperless) so a compromised job can only touch the paperless KV path.
- openbao/rotation/paperless.yaml: SA + quarterly/on-demand CronJob (openbao ns) that bao kv patch's secret-key at homelab/apps/paperless (DB creds preserved).
- openbao/policies/rotator-paperless.hcl: least-privilege policy (manual bootstrap, documented in-file).
- paperless.yaml: reloader annotation; externalsecret.yaml: refreshInterval 1h->10m.
Rotating the Django SECRET_KEY invalidates paperless sessions (re-login); no data loss. Requires the one-time OpenBao bootstrap before first run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015K7gLUVVnutvDnzV2TrMRJ
claude-bot added 1 commit 2026-07-18 19:35:50 +00:00
Moves the WOODPECKER_AGENT_SECRET rotation from the apps namespace to the openbao namespace (matching the new paperless prototype), so it reaches OpenBao intra-namespace:
- openbao/rotation/woodpecker.yaml: SA + CronJob now in openbao ns, per-secret role rotator-woodpecker.
- openbao/policies/rotator-woodpecker.hcl: replaces the shared rotator policy (retired); per-secret least-privilege.
- REVERTS the #299 netpol pair (apps egress + openbao ingress) — no longer needed intra-ns.
- deletes apps/woodpecker/rotate-agent-secret.yaml and the old rotator.hcl.
server.yaml/agent.yaml (Reloader annotations) and externalsecret.yaml (10m) are unchanged.
Bootstrap: create rotator-woodpecker role/policy in openbao and delete the old rotator role/policy (documented in rotator-woodpecker.hcl).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015K7gLUVVnutvDnzV2TrMRJ
k.renner merged commit 9254eb04b7 into master 2026-07-18 19:45:21 +00:00
Sign in to join this conversation.