"Vibe coding," of quickly building an app with an emphasis on "getting it working, is gaining popularity as a modern development style.
In particular, using BaaS such as Supabase or Firebase allows you to complete authentication and database operations with just a few lines of code, making it very useful for rapid prototyping and UI improvement.
However, on the other hand, it is easy to make dangerous mistakes such as writing API keys or secret information directly on the front end which poses the risk of unexpected hacking or high bills .
This article uses actual examples and demonstrations to clearly explain why you should not write the private key to the front end.
introduce specific measures and design points to achieve both vibe coding and security
This is a security bible that every web application developer should read at least once.
Learn systematically about the principles of attacks and countermeasures, and lay the foundation for writing secure code.
*Links include affiliate links. We hope this will be helpful when purchasing books.
- The crisp typing feel that is unique to the capacitive non-contact system!
- REALFORCE's first wireless compatible device! Wired connection also available!
- Unlike the HHKB, the Japanese keyboard layout has no quirks and is easy for anyone to use!
- Equipped with a thumb wheel, horizontal scrolling is very easy!
- It also has excellent noise reduction performance, making it quiet and comfortable!
- Scrolling can be switched between high speed mode and ratchet mode!
What is Vibecoding? Risks that are often overlooked in exchange for efficiency
You often hear about "vibe coding" these days.
Roughly speaking, it's a style of development that prioritizes "just making it work" and is supported by AI and convenient tools to keep things moving at a good pace.
For example, if you use Supabase or Firebase, you can write login, database connection, and display all in one place from the front end, and you can see the results immediately in the browser.
When you experience this feeling, many people will rush ahead, thinking, "It works, so that's OK!" without thinking deeply about design and security.
However, if you deploy it without any consideration, you may encounter
unexpected pitfalls In fact, there are many cases where important information such as API keys are exposed in full view from the front end.
There are more people than you'd think who deploy things just because they "work" and expose dangerous information to the world.
Is that way of writing actually wrong?
Now that it's commonplace to have AI help with coding, there are more and more cases where the code writer doesn't realize there's a risk.
The code works, there are no errors, and it was generated by an AI... In that case, it's even less likely to be suspicious.
For example, if you write API keys and tokens directly in the front end, or if you don't create a back end and have everything processed on the front end, it
may work at first, but in reality it can be easily exploited from outside .
The accumulation of these "things we do unknowingly" can sometimes lead to serious problems such as information leaks and high bills
What happens when you write an API key on the front end?
often generates code that handles everything from login processes to connecting to external APIs
At this point, the AI will "naturally" suggest a configuration in which secret information such as API keys and authentication tokens are stored on the front end .
At first glance, it seems to work correctly and looks normal,
but if you deploy it with this configuration, secrets that should be kept secure on the server side will be exposed and visible to users' browsers.
What happens when the secret is at the front?
- You can easily extract it by accessing it from a browser
→ Even if it is not displayed on the screen, you can obtain the key by looking at the communication content and code. - This key allows "other people" to operate external services
→ Operations that are normally restricted, such as database access, AI API, and email sending, are now fully open. - Pay-per-use APIs result in immediate and high charges
. Fraudulent use of ChatGPT and external email distribution can result in charges of tens of thousands to hundreds of thousands of yen per night. - cases where leaking secrets directly leads to data leaks
→ For example, in cases like Supabase, the entire database can be read with just one key.
"Leaving a secret at the front desk" is like "sticking your house key on your front door before going out."
Actual damage cases: Troubles caused by leaked API keys
You might be thinking, "Is it really that bad just because an API key is on the front page?"
However, there have been several cases where serious damage has occurred due to API keys in projects that were actually born from vibe coding .
Real damage caused by Lovable.dev
Lovable.dev is gaining attention as an AI "vibe coding" platform .
While it allows developers to build apps with near-no-code ease, there have been a number of cases where security design has been left behind.
There have been several reported cases where
sensitive information such as authentication keys and email addresses were left publicly available in some apps published using Lovable.dev In fact, there have been confirmed cases where secret keys for OpenAI API and Google Maps API were embedded in the front-end, leading to unauthorized use .
requests worth tens of thousands of yen were generated in just one day , so this could have an immediate financial impact, especially for projects that use paid APIs.
Half of vibe-coded sites expose API keys
Another study scanned over 2,000 vibe-coded sites and found that approximately 49.5% of them had secrets like API keys, JWTs, and Google API keys exposed from the front .
This shows that in many cases, the priority is simply to get the code to "run," and security fundamentals are lacking

A quick demo: Is your API key really invisible?
Here we will introduce three common implementation patterns for handling API keys (two incorrect examples and one correct example).
Even if you think that it will work fine at first glance, it may actually pose a serious security risk.
- Wrong example 1:
Hard-coding the API key on the front end. This is a common bad example. Anyone can find out the key by looking at the code. - Incorrect Example 2 : Defining the API key in .env
Sometimes people say, "There's no problem if I define it in .env," but this is no different from Incorrect Example 1. -
.env
on the server side via the API and communicating with the front end via the API, the key will not be exposed to the user.
Incorrect example 1: Writing the API key directly on the front
First of all, the thing you should never do write the key directly in the code .
// app/page.tsx "use client"; import { useState } from "react"; const openaiApiKey = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // ← ⚠️ Danger! Write it directly on the frontend! export default function Page() { const [input, setInput] = useState(""); const [response, setResponse] = useState(""); const handleSubmit = async () => { const res = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${openaiApiKey}`, }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [{ role: "user", content: input }], }), }); const data = await res.json(); const text = data.choices?.[0]?.message?.content ?? "No response."; setResponse(text); }; return (<main className="max-w-xl mx-auto p-4 space-y-4"><h1 className="text-2xl font-bold"> 💬 ChatBot Demo (Dangerous Implementation Example)</h1><input type="text" placeholder="メッセージを入力..." value={input} onChange={(e) => setInput(e.target.value)} className="w-full p-2 border border-gray-300 rounded" /> <button onClick={handleSubmit} className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700" >Send</button> {response && (<div className="border p-3 rounded bg-gray-100 whitespace-pre-wrap"> <strong>AI response:</strong> {response}</div> )}</main> ); }
If you write the key directly in the frontend, it will be included in the JavaScript file after the build,
so if you publish the app, anyone can view it from a browser .
the Sources tab in Chrome DevTools , you can view the distributed bundle file as it is.
sk-
there , you can quickly find the hard-coded API key.

Incorrect example ② : Defining an API key in .env
Some people believe that it is safe to write it in .env, but if you reference it directly from the front-end code, it will end up being embedded in the built JavaScript and made public.
For example, if you create the following code:
.env
# .env NEXT_PUBLIC_OPENAI_KEY=sk-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
page.tsx
// app/page.tsx "use client"; import { useState } from "react"; const openaiApiKey = process.env.NEXT_PUBLIC_OPENAI_KEY; // ← ⚠️ Dangerous! Even in .env, this is NG export default function Page() { const [input, setInput] = useState(""); const [response, setResponse] = useState(""); const handleSubmit = async () => { const res = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${openaiApiKey}`, }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [{ role: "user", content: input }], }), }); const data = await res.json(); const text = data.choices?.[0]?.message?.content ?? "No response."; setResponse(text); }; return (<main className="max-w-xl mx-auto p-4 space-y-4"><h1 className="text-2xl font-bold"> 💬 ChatBot Demo (Dangerous Implementation Example)</h1><input type="text" placeholder="メッセージを入力..." value={input} onChange={(e) => setInput(e.target.value)} className="w-full p-2 border border-gray-300 rounded" /> <button onClick={handleSubmit} className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700" >Send</button> {response && (<div className="border p-3 rounded bg-gray-100 whitespace-pre-wrap"> <strong>AI response:</strong> {response}</div> )}</main> ); }
process.env.NEXT_PUBLIC_OPENAI_KEY
, its value is expanded as a string during the build.
In other words, .env
, it will actually be included in the front-end JavaScript file and will be freely visible to users.
If you open the distributed bundle in the Sources tab of your browser sk-
are embedded as they are.
.env
, as long as you reference it from the front end, the same risks as writing it directly remain.

Furthermore, when calling an API, the key is added to
the Authorization header Therefore, the Network tab , which is the same as making the key public to all users.

Correct: Via API
The keys defined in .env
should
not be directly referenced If you use Next.js's API Routes and Route Handlers, the only thing sent from the client is "user input," and the OpenAI API key is never made public. (The same configuration will work safely even if deployed to Vercel, etc.)
For example, if you create the following code:
.env
OPENAI_API_KEY=sk-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
route.ts
// app/api/ai/route.ts import { NextResponse } from "next/server"; export async function POST(req: Request) { try { const { input } = await req.json(); const apiKey = process.env.OPENAI_API_KEY; // Server-side only, not exposed if (!apiKey) { return NextResponse.json( { error: "Server misconfig: OPENAI_API_KEY missing" }, { status: 500 } ); } const r = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "gpt-4o-mini", messages: [{ role: "user", content: input }], }), }); const data = await r.json(); return NextResponse.json(data, { status: r.status }); } catch (e) { console.error(e); return NextResponse.json({ error: "Bad request" }, { status: 400 }); } }
page.tsx
// app/page.tsx "use client"; import { useState } from "react"; export default function Page() { const [input, setInput] = useState(""); const [response, setResponse] = useState(""); const handleSubmit = async () => { const res = await fetch("/api/ai", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ input }), }); const data = await res.json(); const text = data.choices?.[0]?.message?.content ?? "No response."; setResponse(text); }; return (<main className="max-w-xl mx-auto p-4 space-y-4"><h1 className="text-2xl font-bold"> 💬 ChatBot Demo (via secure API)</h1><input type="text" value={input} onChange={(e) => setInput(e.target.value)} className="w-full p-2 border border-gray-300 rounded" /> <button onClick={handleSubmit} className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700" >Send</button> {response && (<div className="border p-3 rounded bg-gray-100 whitespace-pre-wrap"> <strong>AI response:</strong> {response}</div> )}</main> ); }
Of course, there is no API key on the front end, so you won't find it even if you look at the Sources tab.

Additionally, the Authorization header is not included in the Network tab, and since the server side makes the request to OpenAI on your behalf, it is not leaked to the user.

Solution: Proxy requests from the server
As you can see from the examples above, handling API keys on the front end is extremely dangerous,
so make sure you only read API keys
If the front-end only sends user input to the server , and the server makes requests to the OpenAI API on your behalf , the API key will not be leaked to the outside world. This the simplest and most secure way to operate .
- ❌Handwritten → Anyone can copy the key from the source code or communication contents
- ❌ .env → Embedded after build, so everyone can see it
- ✅Proxy requests via server → Keys are never revealed
If the information is leaked to the outside world even for a moment, it is possible that fraudulent use could result in a bill of hundreds of thousands to hundreds of thousands of yen
There are many
other risks to secrets that can be leaked unexpectedly accidentally publishing an .env
. Since secrets can be exposed to the public without you realizing it, you should always be careful when handling secrets such as API keys .
I have also published an article that uses this method to properly address security issues.
If you would like to see detailed code and deployment examples, please refer to this article.

If you're coding with vibes, this is a must read!
If you've read this far and are thinking, "Oh no, maybe I wasn't paying attention to security," don't worry, you still have time.
there's a bible that you should read at least once, regardless of your position
It "Systematically Learning How to Create Secure Web Applications, 2nd Edition" (author: Tokumaru Hiroshi) .
explains
the essence of security - "Why is it dangerous?" and "How should it be prevented?" - from the principles of vulnerability to examples and countermeasures a truly "systematic" book that teaches you the specifics of attack flow and key points of defense.
Even if you don't actually put it into practice, you can prevent serious accidents by simply acquiring the minimum knowledge .
If a few thousand yen can prevent risks of hundreds of thousands to hundreds of thousands of yen, there's no reason not to read it.
This is a security bible that every web application developer should read at least once.
Learn systematically about the principles of attacks and countermeasures, and lay the foundation for writing secure code.
*Links include affiliate links. We hope this will be helpful when purchasing books.
If you find the content difficult,
a good idea to ask an experienced engineer to check it .
Finally, let's check it out now
As explained in this article, handling API keys on the front end is extremely dangerous .
Even if something appears to be working correctly, it is not uncommon for the API key to actually be exposed to the entire world.
For example, do you really understand how
the app "coded with vibes" If you're still unclear about it, you should immediately review the design and ensure it's secure .
With the help of AI, many people are
now able to write code and feel like, "I can do this too." It may look like it works fine,
but if you neglect security and your API key is leaked, there is a real risk that you will be charged a large amount.
If that happens, you be the one to take responsibility.
- The crisp typing feel that is unique to the capacitive non-contact system!
- REALFORCE's first wireless compatible device! Wired connection also available!
- Unlike the HHKB, the Japanese keyboard layout has no quirks and is easy for anyone to use!
- Equipped with a thumb wheel, horizontal scrolling is very easy!
- It also has excellent noise reduction performance, making it quiet and comfortable!
- Scrolling can be switched between high speed mode and ratchet mode!