Security / Going live
Going live
Every Onelo app is either in Development or Production mode. Development is deliberately fail-open so you can build without fighting the security gates; Production enforces every one of them. To stop a fail-open app from ever receiving a real key, Onelo won't issue or rotate a live key until the app has cleared the readiness bar for its type — a live app is verified by construction.
App Mode — Development vs Production
The mode is a single flag on the app (applications.is_live), toggled under Settings → App Mode with Go Live / Back to dev. It decides whether the SDK-facing security checks are enforced or skipped:
| Mode | What’s enforced | Use it for |
|---|---|---|
| Development | Fail-open. SDK requests are accepted from anywhere — no Allowed Domains check, no Bundle ID / attestation check, no IP allowlist. Nothing is blocked. | Building and iterating. You can wire the SDK, test locally, and run on any device before your identity checks are set up. |
| Production | Every gate is enforced: Allowed Domains (web origin), attestation / Bundle ID (native binary), and the IP allowlist (server). Requests that don’t match are rejected. | Shipping to real users. Turn it on once your domains and/or bundles are verified. |
What Development mode limits
Development mode is meant for building, not running a real product on — so a draft app carries two caps. They are the same for every app type and every language (web, native, server), and both lift automatically the moment you go live. You never configure them.
| Limit | What happens at the ceiling | Why |
|---|---|---|
| 10 usersunique signed-up users | The 11th sign-up is refused with go_live_required (403) across every sign-up path — hosted auth, OAuth, and the store. Existing users keep working. The app owner also gets a one-time email. | A forcing function: once a draft has real users, it should be secured. The cap is flat and plan-independent — you can’t buy your way past it, you go live (verify a domain or register a bundle). |
| 50,000 requests / dayper app, per UTC day | Over the cap, SDK requests are refused with draft_volume_exceeded (429) until the next UTC day. | A generous anti-abuse backstop on an un-secured draft key — high enough never to bother real development, low enough to blunt a bot hammering a leaked draft key. |
The Production Readiness gate
Going live and getting a live key are two separate things — and the live key is the one Onelo guards. A developer could otherwise mint a pk_live_* with nothing configured, ship it in a binary, and only discover at runtime that the gate is wide open (no verified domain, no bundle ID). So Onelo will not issue or rotate a live key until the app passes the readiness checks for its type.
This is enforced server-side, not just in the dashboard UI. A rotate request for a live key on an app that isn't ready is refused with HTTP 412 and the error code live_key_preflight_failed — the response carries the per-check preflight breakdown so you can see exactly what's missing. Nothing is minted until every blocking check passes.
What each app type must clear
The readiness requirement mirrors the security gate that matters for that platform. A check that reports missing hard-blocks the live key; a pending check is a non-blocking advisory that still surfaces in the UI.
| App type | Requirement to issue a live key |
|---|---|
| Web | At least one verified domain — a domain added and passed through domain verification (DNS TXT record or the hosted well-known file). See Allowed domains. |
| Native | iOS, macOS, Android, Electron, React Native, Flutter — at least one cryptographically verified Bundle ID. A hand-typed Bundle ID does not count: it must be registered from a real build via the discovery window (App Attest / codesign / Play Integrity, depending on platform). See App identity. |
| Server | No hard requirement — the IP allowlist is advisory and the live pk is only an app identifier (real auth happens via your secret key). You're reminded if no secret key is configured, but it won't block going live. |