docs: add secrets management implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
162
docs/plans/2026-02-28-secrets-management.md
Normal file
162
docs/plans/2026-02-28-secrets-management.md
Normal file
@@ -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=<real-password>
|
||||
# export JWT_SECRET_KEY=<real-jwt-secret>
|
||||
# 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"
|
||||
```
|
||||
Reference in New Issue
Block a user