DEV Community

Cover image for How I stopped leaking my Anthropic API key in React Native
Leboisdolivier
Leboisdolivier

Posted on

How I stopped leaking my Anthropic API key in React Native

If you've ever built a React Native or Expo app with the Anthropic API,
you've probably done this at some point:

EXPO_PUBLIC_ANTHROPIC_API_KEY=sk-ant-...
Enter fullscreen mode Exit fullscreen mode

It works. The app calls Claude. Everything is fine.

Until you realize that EXPO_PUBLIC_ means the key is bundled
into your APK and your web build — visible to anyone who downloads
the app or opens DevTools.

The fix: a server-side proxy

The solution is straightforward: never call Anthropic directly from
the client. Put a thin proxy in between.

Your app → (Bearer token) → Proxy → (Anthropic key) → Claude

Your Anthropic key never leaves the server.

I open-sourced mine

I kept building this proxy from scratch for every project, so I
cleaned it up and published it as a template:

👉 atelier-claude-proxy

Two flavors, same interface:

Firebase Functions — uses Firebase Auth ID tokens.
If you're already on Firebase, it's a near-zero-config drop-in.
Deploys in ~5 minutes.

Cloudflare Worker — framework-agnostic, ~0ms cold start,
100k requests/day on the free tier. Deploys in ~3 minutes.

Both are ~100 lines of vanilla JS with no dependencies
beyond the platform SDK.

Usage

const res = await fetch('https://YOUR_PROXY_URL', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`,
  },
  body: JSON.stringify({
    messages: [{ role: 'user', content: 'Hello!' }],
  }),
});

const data = await res.json();
console.log(data.content[0].text);
Enter fullscreen mode Exit fullscreen mode

The response is the raw Anthropic API response — no transformation.

What it handles

  • API key stored in Secret Manager / Workers Secrets
  • Auth verified on every request
  • CORS locked to your origins
  • Hard token cap to protect your bill
  • Usage logged per user (uid + token count)

Feedback welcome — especially on the auth model for the
Cloudflare version.

Top comments (0)