constructor() {
this.baseURL = import.meta.env.VITE_API_BASE_URL || ""
this.apiKey = import.meta.env.VITE_API_KEY
}
(frontend/src/lib/api/realClient.ts:42-45)
and it is sent as a bearer credential:
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
(frontend/src/lib/api/realClient.ts:59)
Every VITE_-prefixed variable is statically replaced by Vite at build time. It is not a runtime secret; it is a string literal in dist/assets/*.js. frontend/vite.config.ts:32 sets sourcemap: true, so it will also sit in the published .map files in readable form.
Trigger: build with a key set (frontend/.env.example:9 documents exactly this: # VITE_API_KEY=your_api_key_here), deploy the static bundle, then curl https://<host>/assets/index-*.js | grep -o "Bearer[^\"]*".
Observed: the shared backend API key, readable by anyone who can load the page.
Expected: no long-lived credential reachable from the client.
README.md:302 already says "Do not commit real API keys" — the same reasoning applies here, and more strongly, because this key is not just committed but actively published.
Given the RC deployment shape described in README.md (one backend, one frontend, internal network), the pragmatic options are, in descending order of preference:
- Drop client-side auth entirely and put the backend behind network-level access control. The frontend already works with no key —
apiKey is optional at realClient.ts:40.
- Terminate auth at a reverse proxy that injects the upstream credential, so the browser never holds one.
- If per-user auth is genuinely needed, issue short-lived per-user tokens from a login endpoint.
Whichever path, please remove VITE_API_KEY from .env.example at the same time so it stops being suggested as a supported configuration.
(
frontend/src/lib/api/realClient.ts:42-45)and it is sent as a bearer credential:
(
frontend/src/lib/api/realClient.ts:59)Every
VITE_-prefixed variable is statically replaced by Vite at build time. It is not a runtime secret; it is a string literal indist/assets/*.js.frontend/vite.config.ts:32setssourcemap: true, so it will also sit in the published.mapfiles in readable form.Trigger: build with a key set (
frontend/.env.example:9documents exactly this:# VITE_API_KEY=your_api_key_here), deploy the static bundle, thencurl https://<host>/assets/index-*.js | grep -o "Bearer[^\"]*".Observed: the shared backend API key, readable by anyone who can load the page.
Expected: no long-lived credential reachable from the client.
README.md:302already says "Do not commit real API keys" — the same reasoning applies here, and more strongly, because this key is not just committed but actively published.Given the RC deployment shape described in
README.md(one backend, one frontend, internal network), the pragmatic options are, in descending order of preference:apiKeyis optional atrealClient.ts:40.Whichever path, please remove
VITE_API_KEYfrom.env.exampleat the same time so it stops being suggested as a supported configuration.