From 4968ea79d91290f29b1a5174341da5605bb6deaa Mon Sep 17 00:00:00 2001 From: "Adrian A. Baumann" Date: Sat, 28 Feb 2026 22:46:55 +0100 Subject: [PATCH] docs: add secrets management implementation plan Co-Authored-By: Claude Sonnet 4.6 --- docs/plans/2026-02-28-secrets-management.md | 162 ++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 docs/plans/2026-02-28-secrets-management.md diff --git a/docs/plans/2026-02-28-secrets-management.md b/docs/plans/2026-02-28-secrets-management.md new file mode 100644 index 0000000..5e6eef5 --- /dev/null +++ b/docs/plans/2026-02-28-secrets-management.md @@ -0,0 +1,162 @@ +# Secrets Management Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Remove secrets from the Helm chart and replace them with an idempotent kubectl bootstrap script at `scripts/create-secrets.sh`. + +**Architecture:** Delete the Helm-managed Secret template and strip secret values from values files so nothing sensitive ever lives in git. A standalone shell script pre-creates the Kubernetes Secret before ArgoCD first syncs; the existing `secretKeyRef` references in the deployments continue to work unchanged. + +**Tech Stack:** bash, kubectl, Helm 3 + +--- + +### Task 1: Delete the Helm Secret template + +**Files:** +- Delete: `helm/shorefront/templates/secret.yaml` + +**Step 1: Delete the file** + +```bash +rm helm/shorefront/templates/secret.yaml +``` + +**Step 2: Verify it's gone** + +```bash +ls helm/shorefront/templates/ +``` + +Expected: `secret.yaml` is not listed. + +**Step 3: Commit** + +```bash +git add helm/shorefront/templates/secret.yaml +git commit -m "feat: remove Helm-managed Secret template" +``` + +--- + +### Task 2: Remove secrets block from values files + +**Files:** +- Modify: `helm/shorefront/values.yaml` (lines 37-39) +- Modify: `helm/shorefront/values-prod.yaml` + +**Step 1: Edit `values.yaml` — remove the `secrets:` block** + +Remove these lines from the bottom of `helm/shorefront/values.yaml`: + +```yaml +secrets: + postgresPassword: changeme-in-prod + jwtSecretKey: changeme-in-prod +``` + +The file should end after the `ingress:` block: + +```yaml +ingress: + host: shorefront.example.com + ingressClassName: traefik +``` + +**Step 2: Edit `values-prod.yaml` — replace comment with usage instructions** + +Replace the entire content of `helm/shorefront/values-prod.yaml` with: + +```yaml +ingress: + host: shorefront.yourdomain.com + +# Secrets are NOT managed by Helm. Run scripts/create-secrets.sh before +# the first helm install/ArgoCD sync: +# +# export POSTGRES_PASSWORD= +# export JWT_SECRET_KEY= +# bash scripts/create-secrets.sh +``` + +**Step 3: Verify helm template renders without errors** + +```bash +helm template shorefront helm/shorefront/ +``` + +Expected: renders all templates cleanly; no `shorefront-secret` Secret resource in output; no template errors. + +**Step 4: Commit** + +```bash +git add helm/shorefront/values.yaml helm/shorefront/values-prod.yaml +git commit -m "feat: remove secrets block from Helm values" +``` + +--- + +### Task 3: Create the bootstrap script + +**Files:** +- Create: `scripts/create-secrets.sh` + +**Step 1: Create `scripts/` directory and write the script** + +Create `scripts/create-secrets.sh` with this exact content: + +```bash +#!/usr/bin/env bash +set -euo pipefail + +NAMESPACE="shorefront" + +# --- Validate required env vars --- +: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}" +: "${JWT_SECRET_KEY:?JWT_SECRET_KEY is required}" + +echo "Creating namespace '${NAMESPACE}' if it does not exist..." +kubectl create namespace "${NAMESPACE}" --dry-run=client -o yaml | kubectl apply -f - + +echo "Creating/updating secret 'shorefront-secret' in namespace '${NAMESPACE}'..." +kubectl create secret generic shorefront-secret \ + --namespace "${NAMESPACE}" \ + --from-literal=POSTGRES_PASSWORD="${POSTGRES_PASSWORD}" \ + --from-literal=JWT_SECRET_KEY="${JWT_SECRET_KEY}" \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "Done. Secret 'shorefront-secret' is ready in namespace '${NAMESPACE}'." +``` + +**Step 2: Make it executable** + +```bash +chmod +x scripts/create-secrets.sh +``` + +**Step 3: Verify the script is valid bash and has correct shebang** + +```bash +bash -n scripts/create-secrets.sh && echo "syntax OK" +``` + +Expected output: `syntax OK` + +**Step 4: Dry-run the script without a cluster to confirm env var validation** + +```bash +bash scripts/create-secrets.sh 2>&1 || true +``` + +Expected output: +``` +scripts/create-secrets.sh: line N: POSTGRES_PASSWORD: POSTGRES_PASSWORD is required +``` + +(exits non-zero because the env vars are unset — this confirms the guard works) + +**Step 5: Commit** + +```bash +git add scripts/create-secrets.sh +git commit -m "feat: add scripts/create-secrets.sh for bootstrapping k8s secrets" +```