50 lines
1.9 KiB
Bash
50 lines
1.9 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Summary:
|
|
# - Scans all first-level subdirectories in the current working directory (each treated as a "service").
|
|
# - If a service contains ./<service>/secrets.sops.yaml, decrypts it with sops.
|
|
# - Splits the decrypted YAML into individual key/value pairs and writes each value to a separate file:
|
|
# /run/secrets/<service>/<key>
|
|
# - Output matches Docker "secrets" convention: one file per secret
|
|
|
|
# Assumptions:
|
|
# - ./<service>/secrets.sops.yaml is a flat, single-level key: value YAML map encrypted with sops (dotenv-like, but in YAML)
|
|
# - sops, age and yq (mikefarah) are installed and in PATH
|
|
# - The script is executed from the "services root" directory: its direct children are service directories (e.g. ./immich/, ./caddy/, ...)
|
|
# - For systemd, set WorkingDirectory to this directory.
|
|
|
|
set -euo pipefail
|
|
umask 077 # 0600 by default
|
|
|
|
OUT_ROOT="/run/secrets"
|
|
SECRETS_GROUP="apps" # docker container runs under apps user
|
|
DIR_MODE="0750"
|
|
FILE_MODE="0640"
|
|
|
|
for service_dir in ./*/; do
|
|
service_name="${service_dir#./}" # remove leading './': './service/' -> 'service/'
|
|
service_name="${service_name%/}" # remove trailing '/': 'service/' -> 'service'
|
|
|
|
secrets_file="./${service_name}/secrets.sops.yaml"
|
|
[[ -f "$secrets_file" ]] || continue
|
|
|
|
out_dir="${OUT_ROOT}/${service_name}"
|
|
install -d -m "$DIR_MODE" -o root -g "$SECRETS_GROUP" -- "$out_dir"
|
|
|
|
sops -d "$secrets_file" \
|
|
| yq -r -0 'to_entries[] | "\(.key)\u0000\(.value)\u0000"' \
|
|
| while IFS= read -r -d '' key && IFS= read -r -d '' value; do
|
|
[[ "$key" =~ ^[A-Za-z0-9_][-A-Za-z0-9_]*$ ]] || { echo "skip bad key: $key" >&2; continue; }
|
|
|
|
tmp_val="$(mktemp "${out_dir}/.${key}.XXXXXX")"
|
|
|
|
printf '%s' "$value" > "$tmp_val"
|
|
|
|
chown root:"$SECRETS_GROUP" "$tmp_val"
|
|
chmod "$FILE_MODE" "$tmp_val"
|
|
|
|
mv -f -- "$tmp_val" "${out_dir}/${key}"
|
|
done
|
|
|
|
echo "sops ok: ${service_name}"
|
|
done |