API key handling in React Native
Why live keys can't ship in mobile bundles, and the proxy pattern.
Critical
Never embed a ohms_live_* key in a mobile app bundle.
Why
When you ship an iOS or Android app, anyone can:
- Download the IPA / APK.
- Run
apktool,strings, or open the JS bundle in a text editor. - Find every string constant — including any API key compiled into the bundle.
If that key is a live OHM key, the attacker can call your API on your dime, mint as many extractions as they want, and pollute your logs.
What the SDK enforces
@ohm_studio/sdk-react-native's constructor refuses to initialise when:
- The runtime is React Native (
navigator.product === "ReactNative"), - The supplied
apiKeystarts withohms_live_, - And
acknowledgeBundledKey: trueis not passed.
You'll get a OHMConfigError with a link back to this page.
Patterns
✅ Test-mode keys for local dev
Mint an ohms_test_* key from the Studio Keys page. Test-mode keys:
- Are explicitly safe in mobile bundles.
- Run against the same API endpoints, with the same Foundation Block + safety priors.
- Have configurable separate rate limits.
- Are easy to rotate / revoke without affecting production.
✅ Production: backend proxy
Run a small proxy on your backend. The proxy holds the live key. Your RN app talks to your backend with your session token, and your backend forwards to OHM.
import { OHM } from "@ohm_studio/sdk";
const ohm = new OHM({ apiKey: process.env.OHM_LIVE_KEY! });
app.post("/extract", requireSession, async (req, res) => {
const { transcript, apiSlug } = req.body;
const result = await ohm.extract({ apiSlug, text: transcript });
res.json(result);
});const r = await fetch(`${MY_API_BASE}/extract`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${userSessionToken}`,
},
body: JSON.stringify({ apiSlug: "opd", transcript }),
});⚠️ Last resort: acknowledgeBundledKey: true
If you have a tightly-controlled enterprise distribution (internal-only iOS via MDM, no public side-loading) and you've signed off on the risk, you can pass acknowledgeBundledKey: true to override the safeguard.
Even then, prefer test-mode keys with low rate limits and frequent rotation.
Detection & response
We surface every key's lastUsedAt and lastUsedIp in the Studio Keys page. If you see a key being used from an unexpected geography:
- Revoke the key immediately.
- Mint a new key, deploy, ship.
- Investigate — review the audit log for the affected API.
Revocation is instant.