fix: nginx set/rewrite ordering, RAG API-key build arg, Jobs/TES auth header - #76
Merged
Merged
Conversation
`rewrite ... break;` halts processing of the current rewrite-module directive set, including any `set $..._upstream` that follows it in the same location block. Six locations (workbench, lims, auth, license, policy, hpc) had `set` placed after `rewrite ... break;`, so the variable was never assigned and proxy_pass resolved to `http://` (empty), producing a 500 before the backend was ever contacted. Introduced as a side effect of tonight's resolver-based upstream fix (commit d003395). Reordered set before rewrite in all six locations. Verified live: nginx -t clean, 4/4 heartbeat probes over ~1min watch window, zero uninitialized-variable or invalid-URL-prefix log entries. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0135NEjymEpbh7fhWwqz9CwL
Vite env vars are compile-time — the compose environment: block only ever reached the running rag backend container, never the already-built frontend bundle, leaving the key empty client-side and causing RAG's "Not authenticated" state. Adds RAGBIO_API_KEY as a build arg to the rag build block. Verified: rebuilt bundle contains the real key (confirmed non-empty prefix), /_svc/rag/ returns 200 through nginx-router. (An earlier nginx-side fix for this was misdiagnosed and has been reverted — the actual cause was frontend build-time, not routing.) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0135NEjymEpbh7fhWwqz9CwL
Jobs.jsx's apiFetch() helper set Content-Type but never imported
getToken() or attached an Authorization header, causing every TES
request to fail with 401 "missing bearer token" despite a valid
session. rolesApi.js already had the correct working pattern.
Imports getToken from ../lib/session (matches the web-build alias
vite.config.js resolves on) and attaches Authorization: Bearer
${token}, consistent with rolesApi.js. Verified: fake-token test now
correctly returns "invalid token" instead of "missing bearer token";
real session returns 200.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0135NEjymEpbh7fhWwqz9CwL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three independent post-deploy fixes found while verifying PR #75's nginx
resolver change against the live stack. Each is its own commit; none share
a root cause.
1.
fix(nginx): set/rewrite directive ordering (446ecb3)Regression from PR #75 (d003395):
rewrite ... break;halts the entirecurrent set of
ngx_http_rewrite_moduledirectives, including anysetwritten after it in the same location — so
set $workbench_upstream ...(and 5 siblings: lims, auth, license, policy, hpc) never ran, leaving
proxy_pass http://$x;pointed at an empty string. Live symptom: 500s on/_svc/workbench/,/_svc/lims/,/_svc/auth/*,/api/license/*,/_svc/policy/*,/_svc/hpc/*, confirmed viausing uninitialized "..._upstream" variable/invalid URL prefix in "http://"in the nginxerror log. Fixed by moving
setbeforerewrite ... break;in all sixlocations. Audited the whole file for every other
rewrite ... break;combined with a
set $..._upstream— confirmed no other instances exist.2.
fix(rag): RAGBIO_API_KEY build arg (e81e169)RAG's frontend (
ragbio-ui) authenticates with its own static,build-time API key (
import.meta.env.VITE_RAGBIO_API_KEY), completelyindependent of the Studio session JWT — not an iframe/cookie-forwarding
problem at all (an earlier diagnosis assumed it was; that nginx-side fix
has been reverted as a no-op, see below).
docker-compose.yml'srag:build block never passed this as a build arg, so the Dockerfile's
ARG RAGBIO_API_KEYwas always empty regardless of.env, baking anempty key into every build and causing RAG's "Not authenticated" banner.
Fixed by adding
args: RAGBIO_API_KEY: ${RAGBIO_API_KEY}. Verified therebuilt bundle actually contains the real key (non-empty, correct prefix
confirmed without printing the secret in full).
3.
fix(jobs): TES Authorization header (417092c)Jobs.jsx'sapiFetch()never attached anAuthorizationheader —unlike
rolesApi.js's already-working pattern — so every TES call 401'dwith
"missing bearer token"despite a valid Studio session. This is aplain
fetch(), not an iframe navigation, so it's fully able to send areal header itself; nginx's
/_tesproxy needed no change. Fixed byimporting
getTokenand attachingAuthorization: Bearer ${token}.Verification
nginx -tclean against the real Docker network for both nginx changes.zero recurrence of the uninitialized-variable / invalid-URL-prefix class
of error on any of the six affected routes.
contains a 64-char value matching the real key's prefix;
/_svc/rag/returns 200 through the router.
"missing bearer token"(no header) to"invalid token"(headerpresent but not a real session token) — proves the header now reaches
TES; a real session token should pass.
🤖 Generated with Claude Code