Skip to content

Commit ae9d3a7

Browse files
committed
fix(deploy): send admin bearer when reseeding gateway backends
After #100, POST /v1/admin/backends requires Authorization: Bearer. remote-deploy's inline reseed omitted it and staging master CI failed 401; read gateway_admin_token and fail closed when missing.
1 parent 0cc1560 commit ae9d3a7

3 files changed

Lines changed: 53 additions & 8 deletions

File tree

deploy/scripts/register-challenge-backends.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,25 @@ register_one() {
5252
local payload http body token
5353
local -a auth=()
5454
token="$(resolve_admin_token || true)"
55-
if [[ -n "${token}" ]]; then
56-
auth=(-H "Authorization: Bearer ${token}")
55+
if [[ -z "${token}" ]]; then
56+
echo "register-challenge-backends: missing gateway admin token" >&2
57+
echo " set BASE_GATEWAY_ADMIN_TOKEN or deploy/secrets/gateway_admin_token" >&2
58+
return 1
5759
fi
60+
auth=(-H "Authorization: Bearer ${token}")
5861
payload="$(printf '{"challenge_id":"%s","base_url":"%s","weight":1}' "$challenge_id" "$base_url")"
5962
if [[ "$COMPOSE_MODE" -eq 1 ]]; then
6063
body="$(docker compose -f docker-compose.yml \
6164
-f deploy/compose/role-master.yml \
6265
exec -T gateway \
6366
curl -sS -w '\n%{http_code}' -X POST http://127.0.0.1:8080/v1/admin/backends \
6467
-H 'content-type: application/json' \
65-
${auth[@]+"${auth[@]}"} \
68+
"${auth[@]}" \
6669
-d "$payload" 2>/dev/null || true)"
6770
else
6871
body="$(curl -sS -w '\n%{http_code}' -X POST "${GATEWAY_URL%/}/v1/admin/backends" \
6972
-H 'content-type: application/json' \
70-
${auth[@]+"${auth[@]}"} \
73+
"${auth[@]}" \
7174
-d "$payload" 2>/dev/null || true)"
7275
fi
7376
http="$(printf '%s' "$body" | tail -n1)"

deploy/scripts/remote-deploy.sh

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,49 @@ if [[ '$ROLE' == 'master' ]]; then
442442
# The gateway races this script on boot, so retry until registration sticks,
443443
# then prove proxy routing end-to-end: a missed reseed leaves /challenge/*
444444
# at 503 while /healthz stays green. Both must fail the deploy loudly.
445+
# Gateway /v1/admin/* requires Authorization: Bearer (gateway_admin_token).
445446
echo "remote-deploy: registering challenge backends"
446447
reseed_ok=0
447448
for attempt in \$(seq 1 15); do
448449
if python3 - <<'PY'
449-
import json, sys, urllib.request, urllib.error
450+
import json, os, sys, urllib.error, urllib.request
451+
from pathlib import Path
452+
453+
def resolve_admin_token() -> str:
454+
token = (os.environ.get("BASE_GATEWAY_ADMIN_TOKEN") or "").strip()
455+
if token:
456+
return token
457+
candidates = []
458+
env_file = (os.environ.get("BASE_GATEWAY_ADMIN_TOKEN_FILE") or "").strip()
459+
if env_file:
460+
candidates.append(Path(env_file))
461+
# remote-deploy cds to REMOTE_DIR (/opt/base); secrets live beside the tree.
462+
candidates.extend(
463+
[
464+
Path("deploy/secrets/gateway_admin_token"),
465+
Path("/opt/base/deploy/secrets/gateway_admin_token"),
466+
]
467+
)
468+
for path in candidates:
469+
if path.is_file():
470+
token = path.read_text(encoding="utf-8").strip()
471+
if token:
472+
return token
473+
return ""
474+
475+
token = resolve_admin_token()
476+
if not token:
477+
print(
478+
"ERROR: gateway admin token missing "
479+
"(set BASE_GATEWAY_ADMIN_TOKEN or deploy/secrets/gateway_admin_token)",
480+
flush=True,
481+
)
482+
sys.exit(1)
483+
484+
headers = {
485+
"content-type": "application/json",
486+
"Authorization": f"Bearer {token}",
487+
}
450488
backends = [
451489
("prism", "http://prism-challenge:8092"),
452490
("design", "http://design-challenge:8093"),
@@ -457,7 +495,7 @@ for cid, url in backends:
457495
req = urllib.request.Request(
458496
"http://127.0.0.1:8080/v1/admin/backends",
459497
data=payload,
460-
headers={"content-type": "application/json"},
498+
headers=headers,
461499
method="POST",
462500
)
463501
try:

docs/runbooks/staging-testnet-e2e.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,20 @@ are registered. `remote-deploy.sh` (master) re-seeds automatically; to do it by
5555
hand:
5656

5757
```bash
58-
# From this repo (against a reachable gateway):
58+
# From this repo (against a reachable gateway; reads deploy/secrets/gateway_admin_token):
5959
GATEWAY_URL=http://staging.api.joinbase.ai ./deploy/scripts/register-challenge-backends.sh
6060

61-
# Or on the droplet:
61+
# Or on the droplet (admin bearer required after #100):
62+
TOKEN=$(tr -d '[:space:]' </opt/base/deploy/secrets/gateway_admin_token)
6263
curl -fsS -X POST http://127.0.0.1:8080/v1/admin/backends \
6364
-H 'content-type: application/json' \
65+
-H "Authorization: Bearer ${TOKEN}" \
6466
-d '{"challenge_id":"prism","base_url":"http://prism-challenge:8092","weight":1}'
6567
curl -fsS -X POST http://127.0.0.1:8080/v1/admin/backends \
6668
-H 'content-type: application/json' \
69+
-H "Authorization: Bearer ${TOKEN}" \
6770
-d '{"challenge_id":"design","base_url":"http://design-challenge:8093","weight":1}'
71+
unset TOKEN
6872
curl -fsS http://staging.api.joinbase.ai/challenge/prism/health
6973
curl -fsS http://staging.api.joinbase.ai/challenge/design/health
7074
```

0 commit comments

Comments
 (0)