Files
net-kingdom/sso-mfa/k8s/privacyidea/enckey-bootstrap.sh
Bernd Worsch 1d94652ba1 feat(sso-mfa): T04 privacyIDEA manifests (NK-WP-0001-T04)
Deploy privacyIDEA (MFA core) in the mfa namespace:
- pvc.yaml: privacyidea-data (5Gi) and privacyidea-logs (2Gi)
- configmap.yaml: pi.cfg reading secrets from env vars
- deployment.yaml: Deployment + ClusterIP Service (port 8080)
- middleware.yaml: Traefik RateLimit + admin IP AllowList
- ingress.yaml: pink.coulomb.social (portal + admin), pink-account.coulomb.social (self-service)
- create-secrets.sh: creates privacyidea-config Secret
- enckey-bootstrap.sh: post-deploy key extraction + DR Secrets
- bootstrap-admin.sh: pi-admin, trigger-admin, privacyidea-trigger-admin Secret
- verify-t04.sh: 8-section done-criteria checker

Config points CP-NK-002 (pink.coulomb.social) and CP-NK-003
(pink-account.coulomb.social) registered in CONFIG.md.

pink = PrivacyIDEA Net Knights (project mnemonic).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 01:22:41 +00:00

122 lines
5.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# enckey-bootstrap.sh — extract privacyIDEA key material and create DR Secrets
#
# Run ONCE after the first successful pod start (deployment.yaml applied and Running).
#
# What it does:
# 1. Finds the running privacyIDEA pod.
# 2. Generates RSA audit keys inside the pod if they do not exist yet.
# 3. Extracts: enckey, private.pem, public.pem → local files.
# 4. Creates K8s Secrets privacyidea-enckey and privacyidea-auditkeys.
# These are disaster-recovery copies — the authoritative key material
# lives in the privacyidea-data PVC.
# 5. Prints instructions to copy the extracted files into KeePassXC.
#
# Usage:
# ./enckey-bootstrap.sh [secrets-dir]
#
# <secrets-dir> is where local copies are written (default: ../../bootstrap/secrets).
# Files in secrets-dir are sensitive — shred them after entering into KeePassXC.
#
# Re-running is safe: kubectl apply is idempotent; pi-manage create_audit_keys
# does not overwrite existing keys.
set -euo pipefail
NAMESPACE="mfa"
SECRETS_DIR="${1:-../../bootstrap/secrets}"
PI_DIR="$SECRETS_DIR/privacyidea"
mkdir -p "$PI_DIR"
# ── 1. Find the running pod ───────────────────────────────────────────────────
echo "Looking for running privacyIDEA pod in namespace: $NAMESPACE"
PI_POD=$(kubectl get pod -n "$NAMESPACE" \
-l app.kubernetes.io/name=privacyidea \
--field-selector=status.phase=Running \
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
if [[ -z "$PI_POD" ]]; then
echo "ERROR: no Running privacyIDEA pod found in namespace '$NAMESPACE'." >&2
echo " Apply the manifests first and wait for the pod to reach Running state:" >&2
echo " kubectl get pods -n $NAMESPACE -w" >&2
exit 1
fi
echo "Found pod: $PI_POD"
# ── 2. Generate audit keys if missing ────────────────────────────────────────
echo ""
echo "Checking for audit keys..."
if kubectl exec -n "$NAMESPACE" "$PI_POD" -- test -f /etc/privacyidea/private.pem 2>/dev/null; then
echo " Audit keys already exist — skipping generation."
else
echo " Generating audit keys (pi-manage create_audit_keys)..."
kubectl exec -n "$NAMESPACE" "$PI_POD" -- pi-manage create_audit_keys
echo " Done."
fi
# ── 3. Check enckey exists (auto-generated by PI on first DB init) ────────────
echo ""
echo "Checking for encryption key..."
if ! kubectl exec -n "$NAMESPACE" "$PI_POD" -- test -f /etc/privacyidea/enckey 2>/dev/null; then
echo " enckey not found — generating (pi-manage create_enckey)..."
kubectl exec -n "$NAMESPACE" "$PI_POD" -- pi-manage create_enckey
echo " Done."
else
echo " enckey exists."
fi
# ── 4. Extract key material to local files ────────────────────────────────────
echo ""
echo "Extracting key material..."
kubectl exec -n "$NAMESPACE" "$PI_POD" -- \
cat /etc/privacyidea/enckey > "$PI_DIR/pi.enc"
echo " Wrote: $PI_DIR/pi.enc"
kubectl exec -n "$NAMESPACE" "$PI_POD" -- \
cat /etc/privacyidea/private.pem > "$PI_DIR/private.pem"
echo " Wrote: $PI_DIR/private.pem"
kubectl exec -n "$NAMESPACE" "$PI_POD" -- \
cat /etc/privacyidea/public.pem > "$PI_DIR/public.pem"
echo " Wrote: $PI_DIR/public.pem"
# ── 5. Create K8s Secrets (DR copies) ────────────────────────────────────────
echo ""
echo "Creating K8s Secret: privacyidea-enckey (namespace: $NAMESPACE)"
kubectl create secret generic privacyidea-enckey \
--namespace="$NAMESPACE" \
--from-file=enckey="$PI_DIR/pi.enc" \
--dry-run=client -o yaml | kubectl apply -f -
echo "Creating K8s Secret: privacyidea-auditkeys (namespace: $NAMESPACE)"
kubectl create secret generic privacyidea-auditkeys \
--namespace="$NAMESPACE" \
--from-file=private.pem="$PI_DIR/private.pem" \
--from-file=public.pem="$PI_DIR/public.pem" \
--dry-run=client -o yaml | kubectl apply -f -
# ── 6. Summary and KeePassXC instructions ─────────────────────────────────────
echo ""
echo "════════════════════════════════════════════════════════════"
echo " Key material extracted and K8s Secrets created."
echo "════════════════════════════════════════════════════════════"
echo ""
echo "IMPORTANT — Store the extracted files in KeePassXC NOW:"
echo ""
echo " KeePassXC group: net-kingdom/privacyIDEA"
echo " Entry: PI_ENCFILE"
echo " → Attach $PI_DIR/pi.enc as a binary attachment."
echo " Entry: Audit Keys"
echo " → Attach $PI_DIR/private.pem and $PI_DIR/public.pem"
echo ""
echo " Then shred the local copies:"
echo " find '$PI_DIR' -name '*.enc' -o -name '*.pem' | xargs shred -u"
echo ""
echo "DR restore: if the privacyidea-data PVC is lost, copy these files"
echo " back into a fresh PVC before starting the pod."
echo ""
echo "Next step: run ./bootstrap-admin.sh"