Skip to content

VITE_API_KEY is compiled into the JavaScript bundle and shipped to every browser #28

Description

@G2P2
  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:

  1. 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.
  2. Terminate auth at a reverse proxy that injects the upstream credential, so the browser never holds one.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions