OHMOHM Studio

API key handling in React Native

Why live keys can't ship in mobile bundles, and the proxy pattern.

View as Markdown

Critical

Never embed a ohms_live_* key in a mobile app bundle.

Why

When you ship an iOS or Android app, anyone can:

  1. Download the IPA / APK.
  2. Run apktool, strings, or open the JS bundle in a text editor.
  3. 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 apiKey starts with ohms_live_,
  • And acknowledgeBundledKey: true is 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.

your-backend/extract.ts
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);
});
your-rn-app/api.ts
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:

  1. Revoke the key immediately.
  2. Mint a new key, deploy, ship.
  3. Investigate — review the audit log for the affected API.

Revocation is instant.