From a2877d46ff1d13f979f063986a7b99d3a725033a Mon Sep 17 00:00:00 2001 From: Adam Moussa <166072409+amoussa1229@users.noreply.github.com> Date: Fri, 26 Jun 2026 19:55:01 -0400 Subject: [PATCH] fix: paginate batch-get-secret-value in fetch-config (secrets dropped past page 1) (#24) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fetch-config materialized only the FIRST page of Secrets Manager results: the AWS CLI does NOT auto-paginate batch-get-secret-value (the script's comment claiming it does was wrong; --no-cli-pager only disables the output pager, not API pagination). With 28 secret shells under open-swe-/ the first page returned ~10 items, stranding the rest on later pages. Required secrets that landed past page 1 (DASHBOARD_JWT_SECRET, TOKEN_ENCRYPTION_KEY, LANGSMITH_API_KEY_PROD) were silently dropped, tripping the FAIL-FAST 'missing required var' guard and crash-looping open-swe.service. Follow NextToken across pages (new batch_get_secrets_tsv helper). Verified against the live open-swe-dev secrets: now loads all 5 populated secrets (was 2). Same per-record base64 / exact-prefix / accept_var / emit_var hardening — only the page loop is new. --- deploy/seahaven/fetch-config.sh | 35 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/deploy/seahaven/fetch-config.sh b/deploy/seahaven/fetch-config.sh index 72dd2332..f350d5c4 100755 --- a/deploy/seahaven/fetch-config.sh +++ b/deploy/seahaven/fetch-config.sh @@ -149,7 +149,31 @@ done < <(jq -r '.Parameters[] | (.Name|@base64) + "\t" + (.Value|@base64)' <<<"$ log "loaded ${ssm_count} config param(s) from SSM" # 2) Secrets Manager (sensitive values). batch-get-secret-value filters by name -# prefix and auto-paginates; one secret per env var, SecretString = the value. +# prefix; one secret per env var, SecretString = the value. The AWS CLI does NOT +# auto-paginate this operation (unlike list/get-parameters-by-path), and a single +# response caps well under the full set (~10 items/page) — so we MUST follow +# NextToken ourselves or secrets on later pages are silently dropped (they then +# surface as FAIL-FAST "missing required var"). `--no-cli-pager` only disables the +# OUTPUT pager, not API pagination. Each page's records are base64(namevalue). +batch_get_secrets_tsv() { + local token="" page + while :; do + if [ -n "$token" ]; then + page="$(aws secretsmanager batch-get-secret-value \ + --filters "Key=name,Values=${SECRET_PREFIX}" \ + --region "$REGION" --no-cli-pager --output json --next-token "$token")" + else + page="$(aws secretsmanager batch-get-secret-value \ + --filters "Key=name,Values=${SECRET_PREFIX}" \ + --region "$REGION" --no-cli-pager --output json)" + fi + printf '%s' "$page" \ + | jq -r '.SecretValues[] | select(.SecretString != null) | (.Name|@base64) + "\t" + (.SecretString|@base64)' + token="$(printf '%s' "$page" | jq -r '.NextToken // empty')" + [ -n "$token" ] || break + done +} + log "reading secrets under ${SECRET_PREFIX} ..." secret_count=0 while IFS=$'\t' read -r nb vb; do @@ -164,14 +188,7 @@ while IFS=$'\t' read -r nb vb; do [ -n "$key" ] || continue accept_var "$key" "$value" "Secrets" secret_count=$((secret_count + 1)) -done < <( - aws secretsmanager batch-get-secret-value \ - --filters "Key=name,Values=${SECRET_PREFIX}" \ - --region "$REGION" \ - --no-cli-pager \ - --output json \ - | jq -r '.SecretValues[] | select(.SecretString != null) | (.Name|@base64) + "\t" + (.SecretString|@base64)' -) +done < <(batch_get_secrets_tsv) log "loaded ${secret_count} secret(s) from Secrets Manager" # --- Sea Haven DEFAULT_REPO_OWNER hard pin -----------------------------------