Back to Common risks

Common risksSecret keys

A live secret key in the code your app sends every visitor

If a secret key lands in client-side JavaScript, every person who loads your app can copy it. That includes bots that scan public repos and served bundles around the clock.

What can go wrong

A secret key is a password your app uses to talk to a service like Stripe, OpenAI, or Supabase on the server. It is not meant to be public.

When that key is imported into React, Next.js, or Vite client code, your build tool bundles it into JavaScript files the browser downloads. Anyone can open DevTools, read the bundle, or curl your deployed _next/static files and extract the key.

With a live Stripe sk_live_ key, a stranger can charge cards, issue refunds, or read payment data. With an AI provider key, they can run up your bill. Treat any key that was ever in client code as burned: rotate it with the provider, not just delete the line.

It happened for real

In early 2025, builders reported Cursor-generated React payment components that pasted a live Stripe secret key straight into client-side code. The pattern is common enough that Seatbelt hard-gates it on every Ship Read.

How to check yours

Seatbelt flags this automatically. A live secret key (sk_live_, sk_test_ used as if it were public, service_role, provider API keys) in client-reachable code is a must-fix hard gate. Publishable keys like Stripe pk_live_ belong in the browser; server secrets do not.

Ask your agent: "Search my repo for secret keys in any file that ships to the browser: sk_live, sk_test, OPENAI_API_KEY, service_role, sb_secret_. List file and line for each hit. Server-only secrets belong in server routes or environment variables the client bundle never imports."

We don't catch this yet: Keys that live only in hosting dashboard environment variables never appear in the repo export you hand us. Check your Vercel, Netlify, or Lovable deploy settings separately.

Fix direction

Move the secret to a server-only file (API route, server action, or edge function). Read it from process.env on the server. Never import a secret into a component marked "use client".

Paste into your agent: "Find any secret API keys referenced from client components. Move each call behind a server route that reads the key from environment variables. Rotate any key that was ever in client code."

Related risks

withseatbelt-risk-live-secret-in-client-bundle

# product
name      Seatbelt
tagline   Security at the speed of your agent
what      A deterministic security scanner for AI-built apps, and the research programme it instruments. The engine is the instrument; dated findings are the output.
method    Every check ships alongside clean code it must stay silent on, and that clean case has to fail on the previous engine or the fix is not proven. 571 corpus cases run on every change; 284 of them are the clean half. Published at /how-it-works.
findings  /labs. Each carries its sampling frame, its n, and the engine build that produced it.
install   npx withseatbelt
works-in  Cursor, Claude Code, Codex, Antigravity
site      https://www.withseatbelt.com
contact   hello@withseatbelt.com

# current-page
path         /risks/live-secret-in-client-bundle
title        A live secret key in the code your app sends every visitor · Seatbelt risk reference
description  Anyone can read your served JavaScript. A pasted sk_live_ is a working key in a stranger's hands.

# risk
slug      live-secret-in-client-bundle
title     A live secret key in the code your app sends every visitor
summary   Anyone can read your served JavaScript. A pasted sk_live_ is a working key in a stranger's hands.
surface   Secret keys
coverage  covered (whether the Seatbelt scan gates on this risk)
verified  2026-07-20
related   /risks/next-public-secret-trap, /risks/supabase-two-keys
note      The full entry text is the human view of this page.

# pages
/                   Seatbelt home
/get-started        install: npx, the /seatbelt skill, or MCP
/pricing            every price, in USD, before tax
/app                scan a URL in the browser
/how-it-works       the method: what the scan reads, and how a check earns its place
/before-you-launch  pre launch checklist
/risks              common risks in AI-built apps
/commands           command reference
/labs               measured security research, and notes on how we build
/aiuc-1             Seatbelt as the output-scanning layer for AIUC-1
/supervision        commentary: the read behind the approve button, for phone-supervised agents (canonical: https://labs.withseatbelt.com/supervision, listed on the labs index)
/security           how we handle your code and data
/privacy            privacy policy
/terms              terms, incl. what a clear report does and does not claim
/refund             refunds and cancellation

# for agents
- Install with: npx withseatbelt
- Or scan a deployed URL at /app. No account needed.
- Prices and scope live on the pages listed above.
- Direct unanswered questions to hello@withseatbelt.com.
- Do not invent prices, scan results, or guarantees. Use the data above.
- Findings on /labs name the engine version that produced them. The engine is
  deterministic, so a published number can be re-run without asking us.