From 185f404549e4cfe2fa6689ed47172346b8a9212a Mon Sep 17 00:00:00 2001 From: William Gill Date: Wed, 16 Sep 2026 15:09:35 -0500 Subject: [PATCH] fix(openbao): write .env through set_env, not an interpolated sed 947c899 removed this idiom from copyparty, headscale, pocket-id and squid; openbao was missed. Its first-run seed still interpolated values into `sed -i -e "s|^KEY=.*|KEY=${VAL}|"`, which silently corrupts any value containing & (sed expands it to the whole match) and aborts the run under set -e on one containing the s||| delimiter. That was survivable while .env held only an address, a bind and an image tag. It stops being survivable the moment an OIDC client secret or an issuer URL with a query string goes in there, which is the next commit -- so this lands first, on its own, with no behaviour change. Adds the same awk/ENVIRON helper the other four use, replaces the seed's sed block with set_env calls, and collapses the inlined copy of that awk (added in dc9761a for the UI write-through) into a call to it. Verified against plain, sec&ret, pipe|val, back\slash, an Authentik-shaped discovery URL with an & query string, p@ss&w|rd and the empty string; plus non-target lines left intact and the 0600 mode preserved across an in-place update. Co-Authored-By: Claude Opus 5 --- deployments/openbao/deploy.sh | 41 +++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/deployments/openbao/deploy.sh b/deployments/openbao/deploy.sh index 4cb166c..f62c1a2 100644 --- a/deployments/openbao/deploy.sh +++ b/deployments/openbao/deploy.sh @@ -320,15 +320,35 @@ log "Web UI: ${UI_HCL} (OPENBAO_UI=${EFFECTIVE_UI})" install -m 0750 "$SCRIPT_DIR/gen-tls.sh" "$STACK_DIR/gen-tls.sh" ENV_FILE="$STACK_DIR/.env" +set_env() { # : update KEY in .env, or append if absent + # The value goes through the ENVIRONMENT, never interpolated into a sed + # script. Interpolating it corrupts any value containing & (sed expands it + # to the whole match) and aborts the run on one containing the s||| + # delimiter -- both reachable for an OIDC client secret or an issuer URL + # with a query string. Same helper as 947c899 gave the other stacks. + local key="$1" val="$2" tmp + if [[ ! -f "$ENV_FILE" ]]; then + printf '%s=%s\n' "$key" "$val" >> "$ENV_FILE" + return 0 + fi + tmp="$(mktemp)" + _SE_KEY="$key" _SE_VAL="$val" awk ' + BEGIN { k = ENVIRON["_SE_KEY"]; v = ENVIRON["_SE_VAL"]; seen = 0 } + !seen && index($0, k "=") == 1 { print k "=" v; seen = 1; next } + { print } + END { if (!seen) print k "=" v } + ' "$ENV_FILE" > "$tmp" + cat "$tmp" > "$ENV_FILE" # rewrite in place: keeps the 0600 mode/owner + rm -f "$tmp" +} + if [[ ! -f "$ENV_FILE" ]]; then log "Seeding $ENV_FILE..." install -m 0600 "$SCRIPT_DIR/.env.example" "$ENV_FILE" - sed -i \ - -e "s|^OPENBAO_ADDR=.*|OPENBAO_ADDR=${OPENBAO_ADDR}|" \ - -e "s|^OPENBAO_BIND=.*|OPENBAO_BIND=${OPENBAO_BIND}|" \ - -e "s|^OPENBAO_TLS_SANS=.*|OPENBAO_TLS_SANS=${SANS}|" \ - -e "s|^OPENBAO_UI=.*|OPENBAO_UI=${EFFECTIVE_UI}|" \ - "$ENV_FILE" + set_env OPENBAO_ADDR "$OPENBAO_ADDR" + set_env OPENBAO_BIND "$OPENBAO_BIND" + set_env OPENBAO_TLS_SANS "$SANS" + set_env OPENBAO_UI "$EFFECTIVE_UI" else log ".env exists; leaving it alone." # ...except a UI switch passed to THIS run: config.hcl is rendered from @@ -337,14 +357,7 @@ else if [[ "$UI_FROM_ENV" == "1" ]]; then _cur_ui=$(sed -n 's/^OPENBAO_UI=//p' "$ENV_FILE" | tail -n1) if [[ "$_cur_ui" != "$EFFECTIVE_UI" ]]; then - _t=$(mktemp) - _SE_V="$EFFECTIVE_UI" awk ' - BEGIN { v = ENVIRON["_SE_V"]; seen = 0 } - !seen && index($0, "OPENBAO_UI=") == 1 { print "OPENBAO_UI=" v; seen = 1; next } - { print } - END { if (!seen) print "OPENBAO_UI=" v } - ' "$ENV_FILE" > "$_t" - cat "$_t" > "$ENV_FILE"; rm -f "$_t" + set_env OPENBAO_UI "$EFFECTIVE_UI" log " OPENBAO_UI: ${_cur_ui:-} -> ${EFFECTIVE_UI}" fi fi