This playground handles one real credential: a TypeSafe API key, read on the server from TYPESAFE_API_KEY (or supplied per-request by a visitor through the x-typesafe-api-key header as their own personal key). Everything below exists so that key never lands in a commit, a log, a response, or the browser bundle.
Report privately. Use GitHub private vulnerability reporting for anything that could expose a key, bypass the SSRF defenses, widen a payload limit, or let a visitor's personal key reach anyone but the upstream API. Do not open a public issue for it.
If a key leaks, rotate it first. Then tell us. Rewriting git history does not un-leak a key; the rotation is the fix.
Scope note. Questions about the Jev model or the TypeSafe API itself belong with TypeSafe AI's official channels. This is a community project.
| Layer | Where | What it does |
|---|---|---|
pre-commit hook |
your machine (.githooks/, installed by pnpm install) |
scripts/check-secrets.mjs blocks staged .env files and well-known key shapes with no dependencies; also runs gitleaks protect --staged if you have it (brew install gitleaks) |
.gitignore |
your machine | .env, .env.* except the two committed files below; competing lockfiles |
CI secret-scan job |
every push and PR | the built-in check over all tracked files plus gitleaks (pinned release, checksum-verified) over full history; a hit fails the build |
| GitHub secret scanning + push protection | the remote | known provider tokens are rejected at push time; alerts for anything that slips through |
Also on: Dependabot alerts and security updates, a main ruleset (no force-push, no deletion), read-only GITHUB_TOKEN, actions pinned to commit SHAs, persist-credentials: false on checkout.
.env.example— placeholders only. Copy to.env.local(ignored) and fill in..env.1password— 1Password references (op://Development/Jev API Key/password), not values.pnpm dev:opruns the app throughop run, which expands them at launch so no key ever sits in a file. The secret check knows this file is allowed; it still fails if a literal value is ever put in it.
- The key is read on the server only (
lib/serverJev.ts, the Python server, the CLI scripts). It is never prefixedNEXT_PUBLIC_, never returned in a response body, and error text is redacted before it reaches the client. - A visitor's personal key (browser header override) is used for that request and not stored server-side. Browser
localStorageis not a secret vault; the UI masks it and offers removal. - Automated tests never call the live provider and never consume shared credits.
Do not bypass the hook. Correct false positives; rotate real keys. Four reviewed
synthetic negative-test findings from earlier commits are recorded as exact
commit/file/rule/line fingerprints in .gitleaksignore. They do not exempt test
files, token patterns, or future commits from scanning.