generated from coulomb/repo-seed
- deployment.yaml: image → 92.205.130.254:32166/coulomb/key-cape:latest (Gitea OCI registry, delivered by KEY-WP-0002; imagePullPolicy: Always) - k3s insecure registry hosts.toml: fixed server endpoint to http:// so containerd does not attempt HTTPS against the plain-HTTP Gitea NodePort - create-secrets.sh: add demo-app OIDC client (required for KeyCape to start; also needed for T08 acceptance tests) - keycape-config Secret updated in-place (no re-bootstrap needed) KeyCape pod 1/1 Running; /healthz OK; OIDC discovery live at https://kc.coulomb.social/.well-known/openid-configuration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
126 lines
4.9 KiB
Bash
126 lines
4.9 KiB
Bash
#!/usr/bin/env bash
|
|
# create-secrets.sh — create the keycape-config K8s Secret
|
|
#
|
|
# Usage:
|
|
# ./create-secrets.sh [secrets-dir]
|
|
#
|
|
# Creates ONE Secret in the sso namespace:
|
|
# keycape-config — config.yaml (full KeyCape config) + key.pem (RSA signing key)
|
|
#
|
|
# The privacyIDEA admin token is a separate Secret (keycape-pi-token) created
|
|
# by create-pi-token.sh AFTER privacyIDEA is bootstrapped (T04 complete).
|
|
# The PI admin token is read from that Secret at startup via config.yaml.
|
|
#
|
|
# Re-run this script to:
|
|
# - Rotate the Authelia client secret (update secrets/authelia/secrets.env first)
|
|
# - Add or modify OIDC client registrations (edit CLIENTS block below)
|
|
# - Rotate the RSA signing key (delete and regenerate secrets/keycape/key.pem)
|
|
|
|
set -euo pipefail
|
|
|
|
SECRETS_DIR="${1:-../../bootstrap/secrets}"
|
|
KEYCAPE_ENV="$SECRETS_DIR/keycape/secrets.env"
|
|
LLDAP_ENV="$SECRETS_DIR/lldap/secrets.env"
|
|
AUTHELIA_ENV="$SECRETS_DIR/authelia/secrets.env"
|
|
KEY_FILE="$SECRETS_DIR/keycape/key.pem"
|
|
|
|
for f in "$KEYCAPE_ENV" "$LLDAP_ENV" "$AUTHELIA_ENV"; do
|
|
if [[ ! -f "$f" ]]; then
|
|
echo "ERROR: $f not found — run sso-mfa/bootstrap/gen-secrets.sh first." >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
read_env() { bash -c "source '$1' 2>/dev/null; echo \${$2}"; }
|
|
|
|
LLDAP_BIND_PW=$(read_env "$LLDAP_ENV" LLDAP_LDAP_USER_PASS)
|
|
AUTHELIA_CLIENT_SECRET=$(read_env "$AUTHELIA_ENV" AUTHELIA_KEYCAPE_CLIENT_SECRET)
|
|
|
|
if [[ -z "$LLDAP_BIND_PW" || -z "$AUTHELIA_CLIENT_SECRET" ]]; then
|
|
echo "ERROR: could not read LLDAP_LDAP_USER_PASS or AUTHELIA_KEYCAPE_CLIENT_SECRET" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The privacyIDEA admin token is read from a separate Secret at runtime.
|
|
# Placeholder here — create-pi-token.sh populates the real value.
|
|
PI_ADMIN_TOKEN="PENDING_create-pi-token.sh"
|
|
if [[ -f "$SECRETS_DIR/keycape/pi_admin_token" ]]; then
|
|
PI_ADMIN_TOKEN=$(cat "$SECRETS_DIR/keycape/pi_admin_token")
|
|
echo "INFO: Using privacyIDEA admin token from $SECRETS_DIR/keycape/pi_admin_token"
|
|
fi
|
|
|
|
# ── RSA signing key ───────────────────────────────────────────────────────────
|
|
if [[ ! -f "$KEY_FILE" ]]; then
|
|
echo "Generating RSA-2048 signing key for KeyCape JWT tokens..."
|
|
mkdir -p "$(dirname "$KEY_FILE")"
|
|
openssl genrsa -out "$KEY_FILE" 2048 2>/dev/null
|
|
chmod 600 "$KEY_FILE"
|
|
echo " Generated: $KEY_FILE"
|
|
echo " IMPORTANT: Store this key in KeePassXC → net-kingdom/KeyCape/jwt-signing-key"
|
|
echo " as a binary attachment. It cannot be recovered if lost."
|
|
else
|
|
echo "INFO: Using existing key: $KEY_FILE"
|
|
fi
|
|
KEY_CONTENT=$(cat "$KEY_FILE")
|
|
|
|
# ── Build config.yaml ─────────────────────────────────────────────────────────
|
|
# Edit the OIDC clients block below to register downstream applications.
|
|
# Re-run this script after any change.
|
|
CONFIG_YAML=$(cat <<EOF
|
|
issuer: "https://kc.coulomb.social"
|
|
port: 8080
|
|
tokenLifetime: "15m"
|
|
privateKeyPem: "/etc/keycape/key.pem"
|
|
environment: "production"
|
|
|
|
lldap:
|
|
url: "ldap://lldap.sso.svc.cluster.local:3890"
|
|
bindDN: "uid=admin,ou=people,dc=netkingdom,dc=local"
|
|
bindPW: "${LLDAP_BIND_PW}"
|
|
baseDN: "dc=netkingdom,dc=local"
|
|
|
|
authelia:
|
|
baseURL: "http://authelia.sso.svc.cluster.local:9091"
|
|
clientId: "keycape"
|
|
clientSecret: "${AUTHELIA_CLIENT_SECRET}"
|
|
redirectURI: "https://kc.coulomb.social/authorize/callback"
|
|
|
|
privacyidea:
|
|
baseURL: "http://privacyidea.mfa.svc.cluster.local:8080"
|
|
adminToken: "${PI_ADMIN_TOKEN}"
|
|
realm: "netkingdom"
|
|
|
|
# ── OIDC client registrations ─────────────────────────────────────────────────
|
|
# clientType: "public" for SPAs/native apps (PKCE, no client secret)
|
|
# "confidential" for server-side apps (client secret required)
|
|
clients:
|
|
- clientId: "demo-app"
|
|
displayName: "Demo Application"
|
|
redirectUris:
|
|
- "http://localhost:3000/callback"
|
|
- "https://demo.coulomb.social/callback"
|
|
allowedScopes: ["openid", "profile", "email", "groups"]
|
|
grantTypes: ["authorization_code"]
|
|
clientType: "public"
|
|
EOF
|
|
)
|
|
|
|
echo "Creating K8s Secret: keycape-config (namespace: sso)"
|
|
kubectl create secret generic keycape-config \
|
|
--namespace=sso \
|
|
--from-literal=config.yaml="$CONFIG_YAML" \
|
|
--from-literal=key.pem="$KEY_CONTENT" \
|
|
--dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
echo ""
|
|
echo "Done. Secret keycape-config created in namespace: sso"
|
|
echo ""
|
|
if [[ "$PI_ADMIN_TOKEN" == "PENDING_create-pi-token.sh" ]]; then
|
|
echo "WARN: privacyIDEA admin token is a placeholder."
|
|
echo " After T04 bootstrap is complete, run:"
|
|
echo " ./create-pi-token.sh"
|
|
echo " Then re-run this script to update keycape-config."
|
|
echo ""
|
|
fi
|
|
echo "Next: apply deployment.yaml, middleware.yaml, ingress.yaml"
|