Your Vibe-Coded App Is Leaking API Keys: The 60-Second Check

By Rakshit Yadav (@yadavrakshit60)•Aug 2026•12 min read

If you came here from the reel: this is the guide. It is the full version of the 30 seconds you just watched — how to check whether your own app is leaking, how bad it gets, and what to install so it stops happening.

The claim in the reel was that hacking a vibe-coded app is easy. That is not a hot take. It is a repeatable, three-step process that works on a depressing share of apps launched this year, and you can run it on your own site right now, before somebody else does.

The 60-second check

Open your own deployed app and do this:

  1. Open DevTools (Cmd + Option + I on macOS, F12 on Windows).
  2. Go to the Network tab. Hard-reload the page (Cmd + Shift + R).
  3. Hit Cmd + F in the network panel and search for sk-.

Then repeat the search for these:

sk-          OpenAI / Anthropic / Stripe secret keys
sk_live_     Stripe live secret key
sk-proj-     OpenAI project key
eyJ          any JWT, including Supabase service tokens
AIza         Google API key
AKIA         AWS access key ID
xoxb-        Slack bot token
ghp_         GitHub personal access token
SECRET       lazy naming, catches a surprising amount

If any of those return a hit inside a .js bundle, an inline <script>, or a request header your browser sent, that key is public. Not "hard to find." Public. It shipped to every visitor, it is sitting in their browser cache, and it is very likely already in someone's scraper index.

That is the entire attack. No tooling, no exploit, no skill. A teenager with a browser can do it to your app tonight.

You can also just paste your URL into the free Website Security Quick Scan and let it run the pass for you.

Why this is not a niche problem

It is worth being precise here, because "AI code is insecure" gets thrown around without numbers.

FindingSource
20% of organizations using vibe-coding platforms have security risks in those appsWiz Research
62% of AI-generated code ships with vulnerabilitiesOX Security
61% of AI-generated code works, but only 10.5% passes security reviewCarnegie Mellon, via OX Security
86% of AI-generated code failed XSS defense checks; 2.74× more XSS than human-written codeGeorgetown CSET / CodeRabbit, via OX Security
5,600 vibe-coded apps scanned: 2,000+ vulnerabilities, 400+ exposed secrets, 175 PII exposuresEscape.tech, via OX Security

Read the second and third rows together, because that pairing is the whole story: the code works, and it is still broken. Working is what you tested for. Working is what the preview showed you. Nothing in your loop tested for the other thing.

It is not just the keys

Wiz published the four categories they kept finding in vibe-coded apps. Keys are only the loudest one:

  1. Exposed API keys and secrets — third-party credentials hardcoded into client-side code. Wiz's own example is a redacted sk-proj-... OpenAI key sitting in a bundle.
  2. Database misconfiguration — tables "wide-open to the world" because Row-Level Security was never switched on.
  3. Client-side authentication logic — password checks and role gates running in the browser, where any visitor can edit them.
  4. Unauthenticated internal apps — admin dashboards and staging environments deployed publicly with no auth at all.

And that is before you get to the rest of what a real audit turns up: no rate limits on endpoints that cost you money per call, client-side validation trusted as if it were a security control, tenant data that leaks across accounts, secrets sitting in git history long after they were "deleted," and dependencies the model installed that nobody has ever looked at.

If the sk- search found something, that is not your one problem. It is the one that happened to be visible in 60 seconds.

Why vibe coding leaks keys specifically

The AI is not doing anything malicious. It is doing exactly what you asked.

"Make the chat work" has an answer that calls the API straight from the browser, and that answer is faster to produce than the safe one. The model picks it. The feature works. You ship.

The most common version is the public env prefix. In Next.js, Vite, and Create React App, any env var with a public prefix gets inlined into the JavaScript bundle at build time:

# .env.local — one of these is a bomb
OPENAI_API_KEY=sk-proj-...              # server-side only
NEXT_PUBLIC_OPENAI_API_KEY=sk-proj-...  # compiled into the bundle, public forever

The app "did not work" with the first one. Adding the prefix made the error go away, so it stayed. The error going away is not the same as the problem being solved — and nothing in the loop knew the difference.

You already knew that, by the way. You knew NEXT_PUBLIC_ ships to the browser before you opened this page. The leak did not happen because you lacked the knowledge. It happened at 1 a.m., in the middle of a feature, when the model produced something that worked and nothing objected.

What it costs when someone finds it

Not abstract:

  • A leaked LLM key is a metered bill someone else runs up. Scrapers watch public bundles continuously. The window between publish and abuse is minutes, not days, and there is no spend cap by default.
  • A leaked Stripe secret key reads your customer list, issues refunds, and creates charges.
  • A leaked Supabase service key, or an anon key with RLS off, is your entire user table — emails, hashes, whatever else you stored.
  • A leaked key is permanently compromised. It was public. You cannot un-publish it, and you cannot know who already has it.
  • The regulatory part. If that table had EU or California users in it, you now have a disclosure obligation and a clock, not just a bad afternoon.

One key. Any one of these. That is the exposure you are carrying right now if the search came back with a hit.

Prompting harder does not fix this

The obvious reaction is to write a better prompt. "Never put API keys in client-side code." Add it to the chat. Done.

It does not hold, and the reason is structural: the model has no memory of your standards. Every new chat starts from zero. You can write the perfect security prompt on Monday and get a hardcoded key on Thursday, because Thursday's session never saw Monday's prompt. There is no version of prompting that survives a fresh context window.

Reviewing it yourself does not hold either. You are the person who wrote NEXT_PUBLIC_ at 1 a.m. to make an error go away. You are not going to catch it at 1 a.m. on a different night, in a 400-line diff, on the feature you are excited about.

What actually closes the gap is not a better prompt or more discipline. It is standards written into the repository, and a reviewer in the loop that is not you — one that reads those standards every session, inspects the diff before it merges, and returns a verdict that blocks.

That is exactly what AgenticKit installs.

AgenticKit: the reviewer that does not get tired

AgenticKit installs a working AI engineering team into your repository — into .cursor/ and .claude/ — instead of leaving you to re-explain your standards to a chat box every morning.

You get 46 specialized agents, 61 skills (architectural playbooks the agents read before they act), 47 slash commands (multi-step workflow pipelines), and strict project rules that load automatically on every session.

The ones that own everything this post is about:

AssetWhat it does
security-auditorAudits the running surface: OWASP Top 10, two-tenant IDOR tests, auth and session checks, secrets scanning, dependency audit. Returns a binary PASS / FAIL backed by reproducible findings. It does not rubber-stamp.
code-reviewerAudits what changed in the diff — conventions, logic errors, security smells — with an APPROVE / NEEDS WORK verdict. This is the one that catches the NEXT_PUBLIC_ prefix before it deploys.
/auditCombined code review + security audit on your current git diff. One command, run it before every merge.
security-basicsThe OWASP and tenant-isolation playbook the agents read before acting — so the standard is in the repo, not in a prompt you have to remember.
auth-patternsSessions, cookies, protected routes. The correct shapes, so the model stops inventing them per session.
/shipEnd-to-end feature pipeline that runs code review and the security audit as built-in gates, not optional extras.

The split is deliberate. code-reviewer grades the diff statically before it merges; security-auditor executes tests against what is actually deployed. /ship runs both in order, so a feature cannot reach "done" without passing through them.

What changes once it is installed

  • Your standards persist across sessions. Rules live in .cursor/rules/ and .claude/rules/, and a sessionStart hook keeps CURSOR.md / CLAUDE.md current. Session 40 knows what session 1 knew. No re-prompting.
  • Something reviews the diff that is not you. /audit does not get tired at 1 a.m., does not skim, and does not get excited about the feature.
  • Security becomes a gate, not an intention. A PASS/FAIL verdict either blocks or it does not. "I'll harden it before launch" has never blocked anything.
  • The findings come with the fix path. The auditor tells you the exploit path and the required control, and the engineering agents implement it — inside the same repo, following the same rules.
  • Roles have hard boundaries. The security auditor does not wander into code style; the reviewer does not deploy. You get a specific verdict from a specific desk instead of one generalist producing mush.
  • One licence covers both editors. Cursor and Claude Code, same install, same standards.

Stated plainly: nothing makes an app unhackable. What this does is close the loop where nothing was checking — which, right now, is the actual reason your key is in a bundle.

How to install it, end to end

Prerequisites: Node.js 18+, a git repository, and Cursor or Claude Code installed. The install writes into your project folder, so run it from the project root.

1. Get a licence key

Buy from the pricing page. The key arrives by email right after checkout.

2. Authenticate

npx agentickit-cursor login YOUR_LICENSE_KEY

One time per machine.

3. Install into your project

cd your-project
npx agentickit-cursor init

A plain init installs both editor targets: .cursor/ with CURSOR.md, and .claude/ with CLAUDE.md.

4. Pick your target and kit (optional)

Two independent axes. --target controls where files land and is free. --kit controls which assets you get and is tied to your licence. They compose.

# WHERE they land
npx agentickit-cursor init --target cursor    # .cursor/ + CURSOR.md
npx agentickit-cursor init --target claude    # .claude/ + CLAUDE.md
npx agentickit-cursor init --target both      # default

# WHICH assets (licence-gated)
npx agentickit-cursor init --kit engineering  # 28 agents, 29 commands, 36 skills
npx agentickit-cursor init --kit marketing    # 18 agents, 18 commands, 26 skills
npx agentickit-cursor init --kit both         # 46 agents, 47 commands, 61 skills

# they compose
npx agentickit-cursor init --kit marketing --target claude

Not sure which one you need? The free Kit Picker asks six yes/no questions and hands you the exact command.

5. Verify the install

npx agentickit-cursor doctor

Reports installed targets, per-target asset counts, whether the sync library and hooks are wired, and whether each memory file is filled or still a placeholder.

6. Run your first security pass

Restart Cursor or Claude Code so it picks up the new agents, then:

/audit

On a vibe-coded app that has never been reviewed, expect findings. That is the point. Then let the agents work through them.

7. Stay current

npx agentickit-cursor update

Updates agents, skills, and commands while preserving your CURSOR.md / CLAUDE.md and any files of your own under .cursor/ or .claude/.

Where the files land

AssetCursorClaude Code
Agents.cursor/agents/*.md.claude/agents/*.md (plus tools, model)
Commands.cursor/commands/*.md.claude/commands/*.md (plus argument-hint, allowed-tools)
Skills.cursor/skills/<slug>/SKILL.md.claude/skills/<slug>/SKILL.md
Rules.cursor/rules/*.mdc.claude/rules/*.md
Hooks.cursor/hooks.json.claude/settings.json
MemoryCURSOR.mdCLAUDE.md

Where to buy

One-time payment. No subscription. Every licence covers both Cursor and Claude Code, and the key is emailed to you at checkout.

KitPriceWhat is in it
Engineering$29 (was $49)Engineering agents, commands, and skills + ENGINEERING-ORG.md
Both$49 (was $89)Full engineering + marketing, all org maps, kit updates
Marketing$29 (was $49)Marketing agents, commands, and skills + MARKETING-ORG.md

If the security half is what brought you here, Engineering is the one — security-auditor, code-reviewer, /audit, and /ship all live there.

→ Buy on the pricing page

There is a standing discount of up to 70% — message @rakshit_yadav19 on X before you check out.

The short version

Vibe coding is not the problem. Vibe coding with nothing checking the output is the problem, and the numbers say so: 62% of AI-generated code ships with a vulnerability, and only about 1 in 10 snippets passes a security review.

Run the sk- search on your own app right now. If it comes back with a hit, you already know you have been shipping without a reviewer.

Install AgenticKit, run /audit, and stop finding out from a stranger.


Questions about the install? Reply to the reel or DM @rakshit_yadav19.

Sources

Related Tools & Agents

🛠️ Free Tool: security-scan🛠️ Free Tool: package-auditor🛠️ Free Tool: kit-picker🤖 Agent: security-auditor🤖 Agent: code-reviewer⚡ Command: /audit⚡ Command: /shipSkill: security-basicsSkill: auth-patterns

Put a reviewer in the loop that never gets tired

security-auditor, code-reviewer, and /audit install straight into .cursor/ and .claude/. One licence, both editors.

Get the kit →