generated from coulomb/repo-seed
feat(sso-mfa): Phase 0a bootstrap tooling (NK-WP-0001-T01)
- sso-mfa/bootstrap/gen-secrets.sh: generates all pre-cluster secrets (PI_SECRET_KEY, PI_PEPPER, DB passwords, Keycloak admin, break-glass) into a structured secrets/ directory; prints summary with truncated values. PI_ENCFILE deferred — must be generated inside the privacyIDEA container. - sso-mfa/bootstrap/pack-bundle.sh: age-encrypts the secrets directory into an offsite ops bundle. - sso-mfa/bootstrap/README.md: KeePassXC group/entry structure, full workflow (generate → KeePassXC → bundle → shred → PI_ENCFILE post-deploy). - .gitignore: add sso-mfa/bootstrap/secrets/, *.age, *.kdbx. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
51
sso-mfa/bootstrap/pack-bundle.sh
Executable file
51
sso-mfa/bootstrap/pack-bundle.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# pack-bundle.sh — create an age-encrypted ops bundle from the secrets directory
|
||||
#
|
||||
# Usage:
|
||||
# ./pack-bundle.sh SECRETS_DIR RECIPIENT_PUBKEY [OUTPUT_FILE]
|
||||
#
|
||||
# RECIPIENT_PUBKEY is the age public key to encrypt to.
|
||||
# Generate one with: age-keygen -o ops-bundle.key (store key safely)
|
||||
# The public key appears on stdout and in the .key file header.
|
||||
#
|
||||
# OUTPUT_FILE defaults to ops-bundle-<timestamp>.tar.age in the current directory.
|
||||
#
|
||||
# Example:
|
||||
# age-keygen -o ~/ops-bundle.key
|
||||
# ./pack-bundle.sh ./secrets "age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Usage: $0 SECRETS_DIR RECIPIENT_PUBKEY [OUTPUT_FILE]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SECRETS_DIR="${1%/}"
|
||||
RECIPIENT="$2"
|
||||
TIMESTAMP="$(date +%Y%m%dT%H%M%S)"
|
||||
OUTPUT="${3:-ops-bundle-${TIMESTAMP}.tar.age}"
|
||||
|
||||
if [[ ! -d "$SECRETS_DIR" ]]; then
|
||||
echo "ERROR: $SECRETS_DIR is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v age &>/dev/null; then
|
||||
echo "ERROR: age is not installed. Install with: apt install age" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMPTAR="$(mktemp --suffix=.tar)"
|
||||
trap 'shred -u "$TMPTAR" 2>/dev/null || rm -f "$TMPTAR"' EXIT
|
||||
|
||||
echo "Packing: $SECRETS_DIR → (tar) → (age encrypt) → $OUTPUT"
|
||||
tar -C "$(dirname "$SECRETS_DIR")" -cf "$TMPTAR" "$(basename "$SECRETS_DIR")"
|
||||
age -r "$RECIPIENT" -o "$OUTPUT" "$TMPTAR"
|
||||
|
||||
echo "Bundle written: $OUTPUT"
|
||||
echo "Recipient key : $RECIPIENT"
|
||||
echo ""
|
||||
echo "Store $OUTPUT offsite (cloud, external drive, second location)."
|
||||
echo "Decrypt with:"
|
||||
echo " age -d -i <private-key-file> -o secrets.tar $OUTPUT && tar xf secrets.tar"
|
||||
Reference in New Issue
Block a user