generated from coulomb/repo-seed
feat(creds): implement NK-WP-0004 Credential Management Foundation
- .sops.yaml + keys/age.pub: SOPS age encryption for all secrets/ paths - .gitignore: broad secrets/ catch-all (any depth) - .githooks/pre-commit: blocks unencrypted secrets/, *.env outside bootstrap/, and known plaintext patterns (PI_SECRET_KEY=, LLDAP_JWT_SECRET=, etc.) - Makefile: full credential lifecycle (creds-init/generate/bundle/apply/verify/ status/rotate) + SOPS helpers (sops-setup/edit/encrypt/decrypt/rotate/check-secrets) + hooks/hooks-test - creds-apply.sh: runs create-secrets.sh in dependency order (postgresql → lldap → authelia → privacyidea), skips keycape with printed instructions, updates state - creds-verify.sh: checks all K8s secrets exist, updates creds-state.yaml - creds-status.sh: human-readable state table from creds-state.yaml - creds-rotate.sh: guided rotation for all 9 secret types with impact descriptions and atomic multi-component update sequences - creds-state.yaml: committable state file tracking generation, bundle, KeePassXC confirmation, per-component apply status, enckey and pi-admin bootstrap flags NK-WP-0003-T01 unblocked. /creds-bootstrap skill registered separately. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
104
sso-mfa/bootstrap/creds-verify.sh
Executable file
104
sso-mfa/bootstrap/creds-verify.sh
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
# creds-verify.sh — check all expected K8s secrets exist and update creds-state.yaml.
|
||||
#
|
||||
# Usage:
|
||||
# bash sso-mfa/bootstrap/creds-verify.sh
|
||||
# make creds-verify
|
||||
#
|
||||
# Checks the following K8s secrets:
|
||||
# databases/net-kingdom-pg-privacyidea-app → secrets_applied.postgres
|
||||
# sso/lldap-secrets → secrets_applied.lldap
|
||||
# sso/authelia-secrets → secrets_applied.authelia
|
||||
# mfa/privacyidea-config → secrets_applied.privacyidea
|
||||
# sso/keycape-config → secrets_applied.keycape
|
||||
# mfa/privacyidea-enckey → enckey_bootstrapped
|
||||
# sso/keycape-pi-token → pi_admin_created
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
STATE_FILE="$SCRIPT_DIR/creds-state.yaml"
|
||||
|
||||
if ! kubectl cluster-info &>/dev/null; then
|
||||
echo "ERROR: Cannot reach the Kubernetes cluster. Verify KUBECONFIG." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Check helper ──────────────────────────────────────────────────────────────
|
||||
secret_exists() {
|
||||
local ns="$1" name="$2"
|
||||
kubectl get secret "$name" --namespace="$ns" --ignore-not-found -o name 2>/dev/null | grep -q .
|
||||
}
|
||||
|
||||
update_state_top() {
|
||||
local key="$1" value="$2"
|
||||
if [[ -f "$STATE_FILE" ]]; then
|
||||
sed -i "s|^$key: .*|$key: $value|" "$STATE_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
update_state_nested() {
|
||||
local key="$1" value="$2"
|
||||
if [[ -f "$STATE_FILE" ]]; then
|
||||
sed -i "s|^ $key: .*| $key: $value|" "$STATE_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Results table ─────────────────────────────────────────────────────────────
|
||||
pass=0
|
||||
fail=0
|
||||
|
||||
check() {
|
||||
local label="$1" ns="$2" secret="$3" state_fn="$4" state_key="$5"
|
||||
if secret_exists "$ns" "$secret"; then
|
||||
printf " %-40s ✔ exists\n" "$label"
|
||||
"$state_fn" "$state_key" "true"
|
||||
((pass++)) || true
|
||||
else
|
||||
printf " %-40s ✗ missing (ns: %s, secret: %s)\n" "$label" "$ns" "$secret"
|
||||
"$state_fn" "$state_key" "false"
|
||||
((fail++)) || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "=== creds-verify — net-kingdom SSO/MFA secrets ==="
|
||||
echo ""
|
||||
|
||||
check "postgres (net-kingdom-pg-privacyidea-app)" \
|
||||
databases net-kingdom-pg-privacyidea-app \
|
||||
update_state_nested postgres
|
||||
|
||||
check "lldap (lldap-secrets)" \
|
||||
sso lldap-secrets \
|
||||
update_state_nested lldap
|
||||
|
||||
check "authelia (authelia-secrets)" \
|
||||
sso authelia-secrets \
|
||||
update_state_nested authelia
|
||||
|
||||
check "privacyidea (privacyidea-config)" \
|
||||
mfa privacyidea-config \
|
||||
update_state_nested privacyidea
|
||||
|
||||
check "keycape (keycape-config)" \
|
||||
sso keycape-config \
|
||||
update_state_nested keycape
|
||||
|
||||
echo ""
|
||||
|
||||
check "enckey (privacyidea-enckey)" \
|
||||
mfa privacyidea-enckey \
|
||||
update_state_top enckey_bootstrapped
|
||||
|
||||
check "pi-admin token (keycape-pi-token)" \
|
||||
sso keycape-pi-token \
|
||||
update_state_top pi_admin_created
|
||||
|
||||
echo ""
|
||||
echo "Results: $pass present, $fail missing"
|
||||
|
||||
if [[ -f "$STATE_FILE" ]]; then
|
||||
echo "State file updated: $STATE_FILE"
|
||||
fi
|
||||
|
||||
[[ "$fail" -eq 0 ]]
|
||||
Reference in New Issue
Block a user