generated from coulomb/repo-seed
feat(sso-mfa): T02/T03 live apply — age-encrypted secrets, CNPG cluster (NK-WP-0001-T02/T03)
- Add encrypt-secrets.sh / decrypt-secrets.sh: age-based secrets workflow replaces KeePassXC dependency; encrypted .env.age files committed to repo - Add bootstrap/secrets.enc/: all component secrets encrypted to age pubkey - Fix .gitignore: allow secrets.enc/**/*.age while blocking plaintext - Fix verify-t02.sh: update netpol names for Authelia+LLDAP+KeyCape stack - Fix verify-t03.sh: remove keycloak_db/role checks; fix ((PASS++)) set-e bug - Update postgresql/cluster.yaml: drop keycloak_db, bootstrap privacyidea_db only - Update postgresql/create-secrets.sh: remove keycloak secret - Fix netpol-databases.yaml: add port 8000 for CNPG instance manager HTTP API - T02 COMPLETE: namespaces, network policies, cert-manager issuers applied - T03 COMPLETE: CNPG operator installed, net-kingdom-pg cluster healthy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
79
sso-mfa/bootstrap/encrypt-secrets.sh
Executable file
79
sso-mfa/bootstrap/encrypt-secrets.sh
Executable file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
# encrypt-secrets.sh — encrypt secrets/ directory to secrets.enc/ using age
|
||||
#
|
||||
# Usage:
|
||||
# ./encrypt-secrets.sh [SECRETS_DIR] [AGE_KEY_FILE]
|
||||
#
|
||||
# SECRETS_DIR plaintext secrets directory (default: ./secrets)
|
||||
# AGE_KEY_FILE age private key file (default: ~/.config/net-kingdom/age.key)
|
||||
#
|
||||
# Reads the public key from the age key file and encrypts each *.env file
|
||||
# (and pi.enc if present) to secrets.enc/<component>/<filename>.age.
|
||||
#
|
||||
# After a successful encrypt, shreds the plaintext secrets directory unless
|
||||
# --no-shred is passed.
|
||||
#
|
||||
# Run after gen-secrets.sh to store secrets safely in the repo.
|
||||
# Commit secrets.enc/ to git.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SECRETS_DIR="${1:-./secrets}"
|
||||
AGE_KEY="${2:-$HOME/.config/net-kingdom/age.key}"
|
||||
NO_SHRED=false
|
||||
for arg in "$@"; do [[ "$arg" == "--no-shred" ]] && NO_SHRED=true; done
|
||||
|
||||
if [[ ! -d "$SECRETS_DIR" ]]; then
|
||||
echo "ERROR: secrets directory not found: $SECRETS_DIR" >&2
|
||||
echo "Run gen-secrets.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$AGE_KEY" ]]; then
|
||||
echo "ERROR: age key not found: $AGE_KEY" >&2
|
||||
echo "Generate with: age-keygen -o $AGE_KEY" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract public key from the private key file
|
||||
PUBKEY=$(grep 'public key:' "$AGE_KEY" | awk '{print $NF}')
|
||||
if [[ -z "$PUBKEY" ]]; then
|
||||
echo "ERROR: could not read public key from $AGE_KEY" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ENC_DIR="$(dirname "$SECRETS_DIR")/secrets.enc"
|
||||
mkdir -p "$ENC_DIR"
|
||||
|
||||
echo "Encrypting secrets → $ENC_DIR/"
|
||||
echo "Recipient: $PUBKEY"
|
||||
echo ""
|
||||
|
||||
count=0
|
||||
for component_dir in "$SECRETS_DIR"/*/; do
|
||||
component=$(basename "$component_dir")
|
||||
mkdir -p "$ENC_DIR/$component"
|
||||
for f in "$component_dir"*; do
|
||||
[[ -f "$f" ]] || continue
|
||||
fname=$(basename "$f")
|
||||
out="$ENC_DIR/$component/$fname.age"
|
||||
age -r "$PUBKEY" -o "$out" "$f"
|
||||
echo " encrypted: $component/$fname → secrets.enc/$component/$fname.age"
|
||||
count=$((count + 1))
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "$count file(s) encrypted to $ENC_DIR/"
|
||||
echo ""
|
||||
|
||||
if [[ "$NO_SHRED" == false ]]; then
|
||||
echo "Shredding plaintext secrets..."
|
||||
find "$SECRETS_DIR" -type f -exec shred -u {} \;
|
||||
rm -rf "$SECRETS_DIR"
|
||||
echo "Done. Plaintext secrets shredded."
|
||||
else
|
||||
echo "(--no-shred: plaintext kept at $SECRETS_DIR)"
|
||||
fi
|
||||
echo ""
|
||||
echo "Next: commit secrets.enc/ to git."
|
||||
Reference in New Issue
Block a user