94 lines
3.1 KiB
Bash
Executable file
94 lines
3.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Minimal, idempotent bootstrap for a Vault Agent AppRole used by containers.
|
|
# Usage:
|
|
# sudo -E ./bootstrap_secret_agent.sh <APPUSER> [KV_SUBPATH]
|
|
# Env (required):
|
|
# VAULT_ADDR=https://127.0.0.1:22300
|
|
# VAULT_TOKEN=<admin/root/installer token>
|
|
# VAULT_CACERT=<path to your Root CA or chain> # recommended for HTTPS
|
|
# Optional:
|
|
# VAULT_NAMESPACE=<hcp/enterprise namespace>
|
|
|
|
if [[ $# -lt 1 || $# -gt 2 ]]; then
|
|
echo "Usage: sudo -E $0 <APPUSER> [KV_SUBPATH]" >&2
|
|
exit 2
|
|
fi
|
|
|
|
APPUSER="$1"
|
|
KV_SUBPATH="${2:-$APPUSER}" # default subpath = APPUSER (e.g. nctest)
|
|
|
|
: "${VAULT_ADDR:?Set VAULT_ADDR (https://…)}"
|
|
: "${VAULT_TOKEN:?Set VAULT_TOKEN}"
|
|
: "${VAULT_NAMESPACE:=}"
|
|
|
|
KV_MOUNT="kv" # adjust if you use a different KV mount
|
|
ROLE="secret-agent-${APPUSER}"
|
|
POLICY="${ROLE}-policy"
|
|
|
|
need(){ command -v "$1" >/dev/null 2>&1 || { echo "missing: $1" >&2; exit 1; }; }
|
|
need vault; need getent; need sudo; need install
|
|
|
|
export VAULT_ADDR VAULT_TOKEN VAULT_NAMESPACE
|
|
|
|
HOMEDIR="$(getent passwd "$APPUSER" | cut -d: -f6 || true)"
|
|
[[ -n "$HOMEDIR" ]] || HOMEDIR="/home/${APPUSER}"
|
|
CREDS_DIR="${HOMEDIR}/vault/creds"
|
|
|
|
echo "==> Vault: $VAULT_ADDR"
|
|
[[ -n "$VAULT_CACERT" ]] && echo "==> CA: $VAULT_CACERT"
|
|
[[ -n "$VAULT_NAMESPACE" ]] && echo "==> NS: $VAULT_NAMESPACE"
|
|
echo "==> APP: $APPUSER"
|
|
echo "==> KV: ${KV_MOUNT}/data/${KV_SUBPATH}"
|
|
echo "==> ROLE: $ROLE"
|
|
echo "==> POLICY: $POLICY"
|
|
echo
|
|
|
|
# 1) Enable KV v2 (idempotent)
|
|
vault secrets enable -path="${KV_MOUNT}" kv-v2 >/dev/null 2>&1 || true
|
|
|
|
# 2) Write read-only policy to that subpath
|
|
POL="$(mktemp)"
|
|
cat >"$POL" <<EOF
|
|
path "${KV_MOUNT}/data/${KV_SUBPATH}" {
|
|
capabilities = ["read"]
|
|
}
|
|
EOF
|
|
vault policy write "${POLICY}" "$POL" >/dev/null
|
|
rm -f "$POL"
|
|
|
|
# 3) Enable AppRole and upsert the role
|
|
vault auth enable approle >/dev/null 2>&1 || true
|
|
vault write "auth/approle/role/${ROLE}" \
|
|
policies="${POLICY}" \
|
|
secret_id_ttl=0 \
|
|
secret_id_num_uses=0 \
|
|
token_ttl=15m \
|
|
token_max_ttl=30m >/dev/null
|
|
|
|
# 4) Fetch ROLE_ID and SECRET_ID
|
|
ROLE_ID="$(vault read -field=role_id "auth/approle/role/${ROLE}/role-id")"
|
|
SECRET_ID="$(vault write -field=secret_id -f "auth/approle/role/${ROLE}/secret-id")"
|
|
|
|
# 5) Install cred files with correct owner/mode
|
|
sudo install -d -o "${APPUSER}" -g "${APPUSER}" -m 0700 "${CREDS_DIR}"
|
|
printf "%s" "${ROLE_ID}" | sudo install -o "${APPUSER}" -g "${APPUSER}" -m 0400 /dev/stdin "${CREDS_DIR}/role_id"
|
|
printf "%s" "${SECRET_ID}" | sudo install -o "${APPUSER}" -g "${APPUSER}" -m 0400 /dev/stdin "${CREDS_DIR}/secret_id"
|
|
sudo ls -l "${CREDS_DIR}"
|
|
|
|
# 6) Optional: seed secrets if subpath not yet present
|
|
if ! vault kv get "${KV_MOUNT}/${KV_SUBPATH}" >/dev/null 2>&1; then
|
|
echo "==> Seeding ${KV_MOUNT}/${KV_SUBPATH} with example values (change later)"
|
|
vault kv put "${KV_MOUNT}/${KV_SUBPATH}" \
|
|
mariadb_root_password='CHANGE_ME_ROOT' \
|
|
mysql_password='CHANGE_ME_APP' >/dev/null
|
|
else
|
|
echo "==> KV already present at ${KV_MOUNT}/${KV_SUBPATH} (skip seed)"
|
|
fi
|
|
|
|
echo
|
|
echo "✔ Installed role_id/secret_id in: ${CREDS_DIR}"
|
|
echo " Role: ${ROLE}"
|
|
echo " Policy: ${POLICY}"
|
|
echo " KV Path: ${KV_MOUNT}/${KV_SUBPATH}"
|