#!/usr/bin/env bash # creds-status.sh — print a human-readable credential state table. # # Usage: # bash sso-mfa/bootstrap/creds-status.sh [state-file] [--v2] # make creds-status # make creds-agent-status set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" STATE_FILE="${1:-$SCRIPT_DIR/creds-state.yaml}" # --v2 flag forces v2 display regardless of schema_version field FORCE_V2=false for arg in "$@"; do [[ "$arg" == "--v2" ]] && FORCE_V2=true; done if [[ ! -f "$STATE_FILE" ]]; then echo "ERROR: creds-state.yaml not found: $STATE_FILE" >&2 echo " This file is created at repo init — check your working directory." >&2 exit 1 fi # Simple key extractors (no yaml lib dependency) top_val() { grep -E "^$1:" "$STATE_FILE" | sed 's/^[^:]*: *//' | sed 's/ *#.*//' | tr -d '"'; } nested_val() { grep -E "^ $1:" "$STATE_FILE" | sed 's/^[^:]*: *//' | sed 's/ *#.*//' | tr -d '"'; } status_icon() { case "$1" in true) echo "✔" ;; false) echo "✗" ;; null) echo "—" ;; *) echo "?" ;; esac } SCHEMA_VER="$(top_val schema_version)" if [[ "$SCHEMA_VER" == "2" || "$FORCE_V2" == "true" ]]; then # ── Schema v2: agent-driven model (NK-WP-0005) ──────────────────────────── echo "=== net-kingdom Credential State (v2 — agent mode) ===" echo "" age_key="$(top_val age_key_present)" secrets_gen="$(top_val secrets_generated)" ops_bundle="$(top_val ops_bundle_created)" ops_loc="$(top_val ops_bundle_location)" emerg_delivered="$(top_val emergency_bundle_delivered)" emerg_at="$(top_val emergency_bundle_delivered_at)" bootstrap_complete="$(top_val bootstrap_complete)" printf " %-32s %s\n" "age key present:" "$(status_icon "$age_key")" printf " %-32s %s\n" "secrets generated:" "$(status_icon "$secrets_gen")" printf " %-32s %s %s\n" "ops bundle created:" \ "$(status_icon "$ops_bundle")" \ "$([ "$ops_bundle" = "true" ] && echo "${ops_loc:-}" || true)" printf " %-32s %s %s\n" "emergency bundle delivered:" \ "$(status_icon "$emerg_delivered")" \ "$([ "$emerg_delivered" = "true" ] && echo "at ${emerg_at:-}" || echo "(pending human confirmation)")" echo "" echo " Secrets applied:" for component in postgres lldap authelia privacyidea keycape; do val="$(nested_val "$component")" printf " %-28s %s\n" "$component" "$(status_icon "$val")" done echo "" enckey="$(top_val enckey_bootstrapped)" pi_admin="$(top_val pi_admin_created)" printf " %-32s %s\n" "enckey bootstrapped:" "$(status_icon "$enckey")" printf " %-32s %s\n" "pi-admin created:" "$(status_icon "$pi_admin")" echo "" printf " %-32s %s\n" "bootstrap complete:" "$(status_icon "$bootstrap_complete")" echo "" echo "Run 'make creds-verify' to refresh secrets_applied state from the live cluster." echo "Run 'make creds-agent-init' to resume bootstrap if not complete." else # ── Schema v1: human-as-operator model (NK-WP-0004, legacy) ────────────── echo "=== net-kingdom Credential State (v1 — human mode) ===" echo "" generated_at="$(top_val generated_at)" bundle_at="$(top_val bundle_at)" keepass_confirmed="$(top_val keepass_confirmed)" printf " %-30s %s\n" "Generated at:" "${generated_at:-—}" printf " %-30s %s\n" "Bundle at:" "${bundle_at:-—}" printf " %-30s %s %s\n" "KeePassXC confirmed:" \ "$(status_icon "$keepass_confirmed")" \ "$([ "$keepass_confirmed" = "false" ] && echo "(set keepass_confirmed: true manually)" || true)" echo "" echo " Secrets applied:" for component in postgres lldap authelia privacyidea keycape; do val="$(nested_val "$component")" note="" [[ "$component" == "keycape" && "$val" == "false" ]] && \ note=" (requires PI_ADMIN_TOKEN — post-T04)" printf " %-28s %s%s\n" "$component" "$(status_icon "$val")" "$note" done echo "" enckey="$(top_val enckey_bootstrapped)" pi_admin="$(top_val pi_admin_created)" printf " %-30s %s%s\n" "enckey bootstrapped:" \ "$(status_icon "$enckey")" \ "$([ "$enckey" = "false" ] && echo " ← TIME-SENSITIVE once pod is live" || true)" printf " %-30s %s\n" "pi-admin created:" "$(status_icon "$pi_admin")" echo "" echo "Run 'make creds-verify' to refresh state from the live cluster." fi