#!/usr/bin/env bash # creds-apply.sh — run all create-secrets.sh scripts in dependency order. # # Usage: # bash sso-mfa/bootstrap/creds-apply.sh [secrets-dir] # make creds-apply # # Dependency order: # 1. postgresql (no dependencies) # 2. lldap (needs: secrets/lldap/secrets.env) # 3. authelia (needs: lldap/secrets.env → LLDAP_LDAP_USER_PASS) # 4. privacyidea (needs: secrets/privacyidea/secrets.env) # 5. keycape SKIPPED — requires owner-established RPF-WP-0040 factor delivery. # create-secrets.sh is first-creation only, never live replacement. # # After each successful component create/verification, creds-state.yaml is updated. # Differing existing values require a separate named rotation; this is not a batch rotation. set +x set -euo pipefail umask 077 SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" if (( $# > 1 )); then echo "ERROR: expected one private secrets directory." >&2 exit 1 fi SECRETS_DIR="$(realpath -sm -- "${1:-$SCRIPT_DIR/secrets}")" STATE_FILE="$SCRIPT_DIR/creds-state.yaml" K8S_DIR="$REPO_ROOT/sso-mfa/k8s" # ── Preflight checks ────────────────────────────────────────────────────────── if [[ -z "${KUBECONFIG:-}" && ! -f "$HOME/.kube/config" ]]; then echo "ERROR: KUBECONFIG is not set and ~/.kube/config does not exist." >&2 echo " Set KUBECONFIG or ensure cluster access before running creds-apply." >&2 exit 1 fi if ! kubectl cluster-info &>/dev/null; then echo "ERROR: Cannot reach the Kubernetes cluster." >&2 echo " Ensure the cluster is running and KUBECONFIG points to the right context." >&2 exit 1 fi if [[ ! -d "$SECRETS_DIR" ]]; then echo "ERROR: secrets directory not found: $SECRETS_DIR" >&2 echo " Run 'make creds-generate' first." >&2 exit 1 fi echo "=== creds-apply — net-kingdom SSO/MFA secrets ===" echo "Secrets dir : $SECRETS_DIR" echo "Cluster connectivity checked; use only the context admitted by the current procedure." echo "" # ── Helper: run a component's create-secrets.sh ─────────────────────────────── run_component() { local component="$1" local script_dir="$K8S_DIR/$component" local script="$script_dir/create-secrets.sh" local state_key="$2" echo "──────────────────────────────────────────────" echo "Applying: $component" if [[ ! -f "$script" ]]; then echo "ERROR: $script not found" >&2 exit 1 fi if ! (cd "$script_dir" && bash create-secrets.sh "$SECRETS_DIR") >/dev/null 2>&1; then echo "ERROR: component create/verification failed; earlier components may already be applied." >&2 echo "Use metadata-only reconciliation before retry; no native acceptance is claimed." >&2 exit 1 fi # Update state file if [[ -f "$STATE_FILE" ]]; then sed -i "s|^ $state_key: .*| $state_key: true|" "$STATE_FILE" echo " [state] secrets_applied.$state_key → true" fi echo "" } # ── Step 1: PostgreSQL ──────────────────────────────────────────────────────── run_component "postgresql" "postgres" # ── Step 2: LLDAP ──────────────────────────────────────────────────────────── if [[ ! -f "$SECRETS_DIR/lldap/secrets.env" ]]; then echo "ERROR: $SECRETS_DIR/lldap/secrets.env not found — run creds-generate first." >&2 exit 1 fi run_component "lldap" "lldap" # ── Step 3: Authelia (needs LLDAP bind password from lldap/secrets.env) ─────── run_component "authelia" "authelia" # ── Step 4: privacyIDEA ─────────────────────────────────────────────────────── if [[ ! -f "$SECRETS_DIR/privacyidea/secrets.env" ]]; then echo "ERROR: $SECRETS_DIR/privacyidea/secrets.env not found." >&2 exit 1 fi run_component "privacyidea" "privacyidea" # ── Step 5: KeyCape — SKIPPED (requires scoped factor delivery) ────────────────────── echo "──────────────────────────────────────────────" echo "SKIPPED: keycape (requires RPF-WP-0040 scoped factor delivery)" echo "" echo " After privacyIDEA is Running and bootstrapped:" echo " 1. Export existing keys from the verified Ready privacyIDEA pod:" echo " bash $K8S_DIR/privacyidea/enckey-bootstrap.sh $SECRETS_DIR" echo "" echo " 2. Create the pi-admin user:" echo " bash $K8S_DIR/privacyidea/bootstrap-admin.sh" echo "" echo " 3. Establish scoped factor custody and ESO delivery through railiance-platform RPF-WP-0040." echo "" echo " 4. Create KeyCape bootstrap secrets only if keycape-config is absent:" echo " bash $K8S_DIR/keycape/create-secrets.sh $SECRETS_DIR" echo "" echo " 5. Update state:" echo " make creds-verify" echo "" echo "=== creds-apply complete ===" echo "Run 'make creds-status' to review state." echo "Run 'make creds-verify' to confirm K8s secrets exist."