Watch
0
0
Fork
You've already forked hyperhive
0

keep authelia's oidc client secrets in the store, not on disk

The mint creates each client's secret in the swarm secret store and writes only the digest to disk. It mints only when the store answers and holds none. A new unit moves the plaintext files an earlier release left into the store and removes each once the store holds the same value. The bridge reads its secret from the store into /run before each start. The secret publisher unit and its path unit are gone.
This commit is contained in:
atlas 2026-10-30 03:25:57 +01:00 • committed by mara
commit d30cb7d122

View file

@ -0,0 +1,321 @@
# Cases for ./oidc-client-secrets.nix. Each case sets up the store's leaf, the
# digest and the plaintext file an earlier release left, and the stub's
# behaviour, runs the function under `set -e` as the units' scripts do, and
# compares its status, what the store holds, what is left on disk and whether
# `authelia` ran.
set -uo pipefail
failures=0
count=0
fail() {
echo "FAILED: $case: $*" >&2
failures=$((failures + 1))
}
id=swarm-grafana
leaf=secret/swarm/services/swarm-grafana/oidc/client
# setup <description>
setup() {
case=$1
count=$((count + 1))
dir=$(mktemp -d)
mkdir "$dir/kv" "$dir/clients"
export FAKE_BAO_KV=$dir/kv FAKE_BAO_LOG=$dir/bao.log FAKE_BAO_LOGIN_RC=0
export FAKE_AUTHELIA_LOG=$dir/authelia.log
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE FAKE_AUTHELIA_EMPTY
: >"$FAKE_BAO_LOG"
: >"$FAKE_AUTHELIA_LOG"
clients=$dir/clients
digest=$clients/$id.digest
legacy=$clients/$id.secret
stored=$FAKE_BAO_KV/$(printf '%s' "$leaf" | tr / _)
}
# run <function> — the function for $id and $leaf, with the stubs first on
# PATH, after the store login the units make first. Sets $rc and $minted.
run() {
minted=$(
set -e
PATH="$FAKE_BIN/bin:$PATH"
unset BAO_TOKEN
# shellcheck source=/dev/null
. "$HELPER"
clients=$dir/clients
store_init
store_login 2>>"$dir/err"
rc=0
"$1" "$id" "$leaf" 2>>"$dir/err" >>"$dir/out" || rc=$?
echo "${MINTED-}"
exit "$rc"
)
rc=$?
}
# expect <status>
expect() {
if [ "$rc" != "$1" ]; then fail "exited $rc, wanted $1: $(cat "$dir/err" "$dir/out" 2>/dev/null)"; fi
}
# held <value>, or held "" for a leaf the store does not have.
held() {
if [ -z "$1" ]; then
if [ -e "$stored" ]; then fail "the store holds '$(cat "$stored")', wanted nothing"; fi
elif [ "$(cat "$stored" 2>/dev/null)" != "$1" ]; then
fail "the store holds '$(cat "$stored" 2>/dev/null)', wanted '$1'"
fi
}
# digest_is <value>, or digest_is "" for no digest file.
digest_is() {
if [ -z "$1" ]; then
if [ -e "$digest" ]; then fail "a digest was written: '$(cat "$digest")'"; fi
elif [ "$(cat "$digest" 2>/dev/null)" != "$1" ]; then
fail "the digest is '$(cat "$digest" 2>/dev/null)', wanted '$1'"
fi
}
ran_authelia() {
[ -s "$FAKE_AUTHELIA_LOG" ]
}
store_called() {
grep -q '^kv' "$FAKE_BAO_LOG"
}
logged() {
grep -qF -- "$1" "$dir/err" "$dir/out" 2>/dev/null
}
no_secret_in_argv() {
if grep -q -e minted-secret -e old-secret "$FAKE_BAO_LOG" "$FAKE_AUTHELIA_LOG"; then
fail "a secret reached a command line"
fi
}
# --- mint_client_secret ---------------------------------------------------
setup "mint: a fresh client is minted into the store and only its digest is written"
run mint_client_secret
expect 0
held minted-secret
digest_is '$pbkdf2-sha512$fake'
if [ "$minted" != 1 ]; then fail "did not report the mint"; fi
if [ -e "$legacy" ]; then fail "wrote a plaintext file"; fi
if [ "$(stat -c %a "$digest")" != 600 ]; then fail "digest mode is $(stat -c %a "$digest")"; fi
if ! logged "minted client secret for $id into the store"; then fail "no mint line"; fi
no_secret_in_argv
setup "mint: a client the store and the disk both hold is left alone"
printf 'old-secret' >"$stored"
printf 'old-digest\n' >"$digest"
run mint_client_secret
expect 0
held old-secret
digest_is old-digest
if ran_authelia; then fail "minted although the store held a value"; fi
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote to a leaf that held a value"; fi
if [ "$minted" = 1 ]; then fail "reported a mint"; fi
setup "mint: a digest whose secret is gone from the store is minted again"
printf 'old-digest\n' >"$digest"
run mint_client_secret
expect 0
held minted-secret
digest_is '$pbkdf2-sha512$fake'
if [ "$minted" != 1 ]; then fail "did not report the mint"; fi
setup "mint: a store that refuses the login leaves the digest, and mints nothing"
printf 'old-digest\n' >"$digest"
export FAKE_BAO_LOGIN_RC=1
run mint_client_secret
expect 0
digest_is old-digest
if ran_authelia; then fail "minted with the store down"; fi
if store_called; then fail "called kv after a refused login"; fi
setup "mint: a store that refuses the read leaves the digest, and mints nothing"
printf 'old-digest\n' >"$digest"
export FAKE_BAO_DENY_READ=1
run mint_client_secret
expect 0
digest_is old-digest
if ran_authelia; then fail "minted although the read was refused"; fi
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote although the read was refused"; fi
setup "mint: no digest and a store that is down fails to retry, and mints nothing"
export FAKE_BAO_LOGIN_RC=1
run mint_client_secret
expect 1
digest_is ""
if ran_authelia; then fail "minted with the store down"; fi
setup "mint: no digest and a store that refuses the read fails to retry, and mints nothing"
export FAKE_BAO_DENY_READ=1
run mint_client_secret
expect 1
digest_is ""
if ran_authelia; then fail "minted although the read was refused"; fi
setup "mint: no digest but a secret in the store is for an operator, and nothing is minted"
printf 'old-secret' >"$stored"
run mint_client_secret
expect 3
held old-secret
digest_is ""
if ran_authelia; then fail "minted over the store's secret"; fi
if ! logged "<3>oidc client $id"; then fail "no err-priority line"; fi
setup "mint: a plaintext file with its digest is left for the migration"
printf 'old-secret\n' >"$legacy"
printf 'old-digest\n' >"$digest"
run mint_client_secret
expect 0
digest_is old-digest
if ran_authelia; then fail "minted although a file held the secret"; fi
if store_called; then fail "called the store"; fi
setup "mint: a plaintext file with no digest is for an operator, and nothing is minted"
printf 'old-secret\n' >"$legacy"
run mint_client_secret
expect 3
digest_is ""
held ""
if ran_authelia; then fail "minted over the file's secret"; fi
if ! logged "<3>oidc client $id"; then fail "no err-priority line"; fi
setup "mint: an authelia that prints nothing writes nothing"
export FAKE_AUTHELIA_EMPTY=1
run mint_client_secret
expect 1
held ""
digest_is ""
setup "mint: a store that refuses the write leaves no digest"
export FAKE_BAO_DENY_WRITE=1
run mint_client_secret
expect 1
held ""
digest_is ""
setup "mint: losing the race to another run writes no digest and keeps the winner's secret"
export FAKE_BAO_RACE=winner-secret
run mint_client_secret
expect 3
held winner-secret
digest_is ""
if [ "$(id -u)" != 0 ]; then
setup "mint: a digest that cannot be written is a failure, not a mint"
chmod 500 "$clients"
run mint_client_secret
chmod 700 "$clients"
expect 1
if [ "$minted" = 1 ]; then fail "reported a mint without a digest"; fi
digest_is ""
fi
# --- migrate_client_secret ------------------------------------------------
setup "migrate: a file the store lacks is stored, read back and removed"
printf 'old-secret\n' >"$legacy"
run migrate_client_secret
expect 0
held old-secret
if [ -e "$legacy" ]; then fail "left the file"; fi
if ! logged "stored in the store, removed the file $legacy"; then fail "no stored line"; fi
if ran_authelia; then fail "minted"; fi
no_secret_in_argv
setup "migrate: a file the store already holds is removed, and the store is not written"
printf 'old-secret\n' >"$legacy"
printf 'old-secret\n' >"$stored"
run migrate_client_secret
expect 0
held "old-secret"
if [ -e "$legacy" ]; then fail "left the file"; fi
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote to a leaf that held a value"; fi
if ! logged "already in the store, removed the file $legacy"; then fail "no removed line"; fi
setup "migrate: a store holding a different secret keeps both and reports an error"
printf 'old-secret\n' >"$legacy"
printf 'other-secret' >"$stored"
run migrate_client_secret
expect 3
held other-secret
if [ "$(cat "$legacy")" != old-secret ]; then fail "changed the file"; fi
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote to a leaf that held a value"; fi
if ! logged "<3>oidc client $id"; then fail "no err-priority line"; fi
setup "migrate: a store that refuses the login keeps the file and retries"
printf 'old-secret\n' >"$legacy"
export FAKE_BAO_LOGIN_RC=1
run migrate_client_secret
expect 1
if [ ! -e "$legacy" ]; then fail "removed the file"; fi
if store_called; then fail "called kv after a refused login"; fi
setup "migrate: a store that refuses the read keeps the file and retries"
printf 'old-secret\n' >"$legacy"
export FAKE_BAO_DENY_READ=1
run migrate_client_secret
expect 1
if [ ! -e "$legacy" ]; then fail "removed the file"; fi
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote although the read was refused"; fi
setup "migrate: a store that refuses the write keeps the file and retries"
printf 'old-secret\n' >"$legacy"
export FAKE_BAO_DENY_WRITE=1
run migrate_client_secret
expect 1
if [ ! -e "$legacy" ]; then fail "removed the file"; fi
held ""
setup "migrate: losing the race to a different secret keeps the file and reports an error"
printf 'old-secret\n' >"$legacy"
export FAKE_BAO_RACE=winner-secret
run migrate_client_secret
expect 3
held winner-secret
if [ ! -e "$legacy" ]; then fail "removed the file"; fi
setup "migrate: an empty file is kept and reported"
: >"$legacy"
run migrate_client_secret
expect 3
if [ ! -e "$legacy" ]; then fail "removed the file"; fi
held ""
setup "migrate: no file is nothing to do, store or no store"
export FAKE_BAO_LOGIN_RC=1
run migrate_client_secret
expect 0
if store_called; then fail "called the store"; fi
if [ "$(id -u)" != 0 ]; then
setup "migrate: a file that cannot be removed is a failure, not a move"
printf 'old-secret\n' >"$legacy"
chmod 500 "$clients"
run migrate_client_secret
chmod 700 "$clients"
expect 1
held old-secret
if ! [ -e "$legacy" ]; then fail "file vanished"; fi
if logged "removed the file"; then fail "logged a removal that did not happen"; fi
setup "migrate: a file the store already holds that cannot be removed is a failure"
printf 'old-secret\n' >"$legacy"
printf 'old-secret' >"$stored"
chmod 500 "$clients"
run migrate_client_secret
chmod 700 "$clients"
expect 1
if logged "removed the file"; then fail "logged a removal that did not happen"; fi
fi
if [ "$failures" != 0 ]; then
echo "$failures of $count cases failed" >&2
exit 1
fi
echo "$count cases passed"