AI security

How to store your OpenAI key server-side

The key does not belong in the browser or the app bundle. In Gemmein you paste it once in the dashboard, and it stays on the server. Your app calls a named tool by name and inputs. The key and the prompt never leave the server.

01 / OVERVIEW

The key lives on the server, always.

A provider key in client code is a key anyone can copy. It ships in the app bundle, and once it is out, someone else can spend against your account. Obfuscation does not fix that. The key has to stay off the browser entirely. Gemmein holds it on the server and gives the browser a named tool to call instead.

Paste the key in the dashboard, then call a named tool from the app. The app sends a name and inputs. It never sends the key, a prompt, or a raw provider request.
02 / WHERE THE KEY GOES

Once, in the dashboard.

You paste the key on the dashboard's AI page, never in a file and never in the SDK. It stays server-side. You can connect OpenAI, Anthropic, Google, Deepgram, Replicate, fal, AssemblyAI, ElevenLabs, or Runway.

A tool can be defined before its key exists. It simply waits. Calls are refused with ai_not_configured until the key is pasted, after which the same tool runs with no further change.
03 / HOW IT WORKS

The app sends a name. The server holds the key.

A tool is a file in your project: provider, model, instructions, template, and inputs. Gemmein composes the provider request from the tool and runs it on your key. The browser only ever sends a tool name and its inputs.

gemmein/ai/tools/deep-research.jsonTool definition
{
  "label": "Deep Research",
  "provider": "openai",
  "model": "gpt-4o",
  "credits": 20,
  "instructions": "You are a careful research assistant. Answer with sources.",
  "promptTemplate": "Research this question:\n\n{{question}}",
  "inputs": [
    { "name": "question", "type": "text", "required": true, "maxLength": 2000 }
  ]
}
Your app calls the toolJavaScript / Expo
// A name and inputs. No key. No prompt. No provider request.
const answer = await g.ai.runText("deep-research", {
  question: "How can I improve client onboarding?"
});

Carry the tool with npx gemmein sync. The key never appears in your code or the browser bundle.

04 / WHY NOT THE BROWSER

Raw calls are off by default.

Letting the browser compose the provider request would put the prompt in the bundle and hand the request's shape to the caller. So raw calls from the browser are off for every key until the owner turns them on deliberately, for an app that genuinely needs it.

The key stays put

It is held server-side and used to make the call for a signed-in person at the tool's price. It never reaches the browser, and it is never in a request your app can read.

When you need more

For embeddings, images, audio, or your own model call, call the provider directly from your own server with your own key. Gemmein's access gate still answers who the person is and what they hold.

05 / FOR YOUR CODING AGENT

Give your agent the full task.

Building with Cursor, Claude, Bolt, or Lovable? Paste this so your agent wires the key the safe way from the start.

Prompt for your coding agentCopy and paste

Read https://docs.gemmein.com/llms.txt and https://docs.gemmein.com/ai. I do not want my OpenAI key in the browser or app bundle. Show me how Gemmein holds the provider key server-side (pasted in the dashboard) and how my app calls a named AI tool by name with inputs, without sending the key or a prompt. Include the tool definition file and the client call.

06 / FAQ

Frequently asked questions.

What if I put the key in the frontend?

Any key in client code ships in the app bundle, where anyone who opens the site or app can read it and spend against your account. Obfuscation does not help. The key has to stay server-side, which is what a named tool gives you.

Which providers can I connect?

OpenAI, Anthropic, Google, Deepgram, Replicate, fal, AssemblyAI, ElevenLabs, and Runway.

Can I still call the provider directly?

Yes. For embeddings, images, audio, or your own model, call the provider from your own server with your own key. Gemmein's gate still answers who the person is and what they hold.

Does the key ever reach the browser?

No. The browser sends a tool name and inputs. Raw provider calls from the browser are off by default, and the key is never in a request your app can read.

07 / RELATED

Related.

How to charge credits for AI features · AI tools on the product page · Gemmein vs Supabase for AI apps · AI docs

See if Gemmein fits your app.

Point your coding agent at docs.gemmein.com/llms.txt and ask it to confirm the fit before it builds.

Read the builder guide