Key safety
Where the AI provider's key is stored, and how an app reaches the provider without carrying it.
Key in the app
The provider's API key ships inside the app, which calls the provider directly. Every request that carries the key is billed to your account.
The app on the phone holds the provider key and sends it with each request straight to the AI provider.
Doesn't protect against
- Anyone who copies the key from your app's files or network traffic, who can then spend on your account from anywhere until you rotate it
Key on a server
The app sends its requests to your server or gateway, which adds the key and calls the provider. The key never ships in the app.
The app on the phone holds no key and sends its request to your server. The server adds the key and calls the AI provider.
Protects against
- Copying the key from the app's files or traffic
Doesn't protect against
- Anyone calling your server directly: it now spends for whoever reaches it, unless it also checks the app, the user and their limits
Split key
Half of the key ships in the app and the other half stays on a server, which joins them for each request.
The app holds half of the key and sends it with each request to a server, which adds the other half and calls the AI provider with the joined key.
Protects against
- Using an extracted half directly with the provider
Doesn't protect against
- Calling the server with the extracted half, which still needs an app check such as DeviceCheck
Runtime secrets
A service delivers the key to the app only after an app check passes, instead of building it into the app.
A secrets service checks the app, then delivers the key to it. The app holds the key in memory and sends it with each request to the AI provider.
Protects against
- Finding the key by unpacking the app's files
- Keeping an old key alive: it can be rotated without an app update
Doesn't protect against
- Reading the key from memory on a compromised device, where it stays for minutes at a time
- Heavy use by one user: everyone shares the same key
Ephemeral provider tokens
Short-lived credentials that an AI provider issues to your server, which passes them to the app. They mostly cover realtime and voice APIs.
Your server holds the key and uses it to get a short-lived token, which it gives to the app. The app calls the AI provider with the token until it expires.
Protects against
- Lasting damage from a leaked credential: it expires within seconds to minutes
Doesn't protect against
- Deciding who gets one: your server still has to check the app and the user before asking for a token
- Ordinary text requests, which most providers don't offer these tokens for
Proving a request comes from your app
Checks that tell a server whether a request comes from your genuine app on a real device, rather than from a script or a modified copy.
App Attest
Apple's proof that a request comes from a genuine copy of your app on a real Apple device. The app creates a key in the device's Secure Enclave and Apple certifies it once. The app then signs every request with that key, covering the request's contents and a counter that only goes up. It needs iOS 14 or later and doesn't work in the Simulator.
Protects against
- Scripts and command-line tools calling your server
- Modified or re-signed copies of your app
- Simulators and emulators
- Replaying or changing a signed request
Doesn't protect against
- Your genuine app on a jailbroken device, hooked to sign an attacker's requests
- Telling users apart: each install gets its own key, and a reinstall gets a new one
- Heavy use: a genuine app can still make expensive calls
DeviceCheck
Apple's older service. The app gets a token showing it runs on a real Apple device, and your server can store two bits per device with Apple, which survive the app being deleted and reinstalled.
Protects against
- Requests from anything that isn't an Apple device
- Repeat free trials after a reinstall, using the two stored bits
Doesn't protect against
- Modified copies of your app: it vouches for the device, not the app
- Tokens passed from a real device to a script
Play Integrity
Google's verdict on an Android request: whether the app is the one you published on Google Play, whether the device is certified, and whether the user got the app from Google Play. A request can include a hash of the call it protects.
Protects against
- Modified copies of your app
- Emulators, and rooted devices at the stronger levels
- Reusing a verdict for another call, when the request hash is checked
Doesn't protect against
- Devices without Google Play services, such as recent Huawei phones
- Well-hidden root at the basic level
- High volume: the default quota is 10,000 checks a day
Firebase App Check
Firebase's wrapper around App Attest, DeviceCheck, Play Integrity and reCAPTCHA. It turns their results into Firebase tokens that Firebase services, or your own server, can check.
Protects against
- The same as the check underneath, on iOS, Android and the web
- Replays, with limited-use tokens that work once
Doesn't protect against
- Copied tokens, unless you use limited-use tokens: standard tokens last from 30 minutes to 7 days
- Telling users apart
Third-party app protection tokens
A vendor's SDK checks the app and the device, then attaches a proof to each request for your server or gateway to verify. Depending on the vendor, the proof lasts a few minutes or is made for each call. You pay the vendor and add its SDK to your app.
Examples: Approov, Talsec AppiCrypt, Promon Verify, Zimperium zDefend, Appdome, Licel, Guardsquare.
Protects against
- Scripts, modified apps and emulators, on iOS and Android with one SDK
- Jailbroken or rooted devices and hooking tools, which these SDKs look for
Doesn't protect against
- Telling users apart or limiting their spending: the server still needs sign-in and limits
- An attacker with full control of a device, given enough time
Jailbreak, root and hooking detection
Code inside the app that detects jailbroken or rooted devices, debuggers, hooking tools such as Frida and tampered builds, and reacts, for example by refusing to run. Often called RASP or app shielding, and combined with code obfuscation.
Protects against
- Casual tampering and reverse engineering
- Hooking a genuine app to misuse it, until someone bypasses the detection
Doesn't protect against
- Requests that don't come from the app at all, unless a server also checks a proof
- An attacker who patches the checks out: they run on a device the attacker controls
Certificate pinning
The app only trusts your server's own certificate or public key, so a proxy presenting a different certificate can't read the traffic.
Protects against
- Reading requests and tokens with traffic-inspection tools on the user's own phone
- Interception on hostile networks
Doesn't protect against
- Jailbroken or rooted devices, where tools switch pinning off
- Anyone calling your server directly with a copied token
Replay protection
The server accepts each proof only once, using a nonce, a counter or single-use tokens.
Protects against
- Capturing one valid request and sending it again
Doesn't protect against
- New valid proofs made by a hooked genuine app
Knowing who the user is
Identities a server can count limits against. Only the ones it can verify are hard to fake.
Sign-in tokens
Your sign-in provider, such as Sign in with Apple or an authentication service, gives the app a signed ID token (a JWT) that names the user, and the gateway verifies the signature before each call.
Protects against
- Strangers calling your backend without an account
- One user using up everyone's budget, because limits can count per user
- Banned users, once you block them
Doesn't protect against
- Bots creating many free accounts
- Calls from outside your app: a user can copy their own token into a script, so pair sign-in with an app check
Anonymous accounts
Accounts created silently, without an email or password, so every user has an ID from the first launch.
Protects against
- Needing a sign-up screen before free features
Doesn't protect against
- New identities on demand: a reinstall or sign-out creates a new account, so its limits start again
Device and install IDs
Identifiers such as Apple's identifierForVendor, or an ID the app generates when it is installed.
Protects against
- Mixing up installs in analytics and rough limits
Doesn't protect against
- Forgery: the server only sees what the app sends, unless the ID is inside a signed proof
- Reinstalls: identifierForVendor changes once all your apps are deleted from the device
User IDs in headers
Some gateways let the caller name the user in a header or field, to attribute usage and apply limits.
Protects against
- Mixing up usage, when the header comes from your own trusted backend
Doesn't protect against
- Abuse from an app: anyone can send any user ID, so limits keyed on it are easy to dodge
Checking who has paid
Ways for a server to confirm a subscription before it allows paid features.
App Store purchase verification
The app sends its StoreKit 2 transaction, which Apple signs, and your server verifies it, or asks the App Store Server API for the user's current subscription status.
Protects against
- Free users reaching paid features
- Forged purchases
Doesn't protect against
- Changes you don't process: refunds and expirations arrive as server notifications
- Android users
Google Play purchase verification
Your server checks an Android purchase token with the Google Play Developer API and follows Google's real-time notifications.
Protects against
- Free users reaching paid features
- Forged purchases
Doesn't protect against
- Changes you don't process: cancellations and refunds arrive as notifications
- iOS users
Subscription platforms
A third-party service verifies App Store and Google Play purchases for you, and reports what each user is entitled to through its API, webhooks, or a claim written into the user's sign-in token.
Protects against
- Building purchase verification for both stores yourself
Doesn't protect against
- Delays when the entitlement travels in a sign-in token, which updates only when the token refreshes
- Outages and price changes at the service, which you now depend on
Entitlements in sign-in tokens
A claim such as paid: true written into the user's sign-in token, so a gateway can check payment without calling a store.
Protects against
- A store lookup on every request
Doesn't protect against
- Up-to-date status: the token keeps its claim until it refreshes, often for up to an hour
- Users who aren't signed in
Limiting use and cost
Ceilings that keep a verified app and user from spending more than you intend. A limit is only as strong as the identity it counts.
Per-user rate limits
A ceiling on how often each verified user can call, such as 20 requests a minute or 200 a day.
Protects against
- A runaway loop or one heavy user draining your budget
Doesn't protect against
- Many accounts used together
- Very large requests: counting requests ignores their size
Per-install limits
Limits counted per install of your app, identified by its App Attest key, a stored install ID or a DeviceCheck device. Useful for free features without sign-in.
Protects against
- Heavy use of a free feature from one install
Doesn't protect against
- Reinstalls, which create a new App Attest key, unless DeviceCheck bits remember the device
- Someone with many real devices
Per-IP limits
Limits counted per network address.
Protects against
- Crude floods from one machine
Doesn't protect against
- Mobile networks, where many real users share one address
- Attackers who rotate through proxies
Per-app rate limits
One ceiling on requests for all users together, per minute or per day.
Protects against
- Unlimited spending when every other check fails
Doesn't protect against
- One abuser using up the allowance and blocking everyone else
Budget limits
Budgets counted in tokens or estimated cost, per user or per app, over a day or a month, often with a hard stop when reached.
Protects against
- A few very large requests that request counts miss
Doesn't protect against
- Exact cut-offs: cost is known only after a response, so a budget can overshoot, especially while streaming
Provider spend limits
Monthly limits set in your AI provider account.
Protects against
- A bill above the limit, whatever goes wrong before the request reaches the provider
Doesn't protect against
- Fairness: when the limit is hit, every user is cut off at once
- Precise timing: some providers apply the limit with a delay
Model allowlist
Only the models you choose can be called through your gateway.
Protects against
- Requests switched to your most expensive model
Doesn't protect against
- Expensive use of a model you allow
Pinned prompts and output caps
The server sets the instructions, tools and maximum answer length for each feature, so the app sends only the user's input.
Protects against
- Using your endpoint as a general-purpose model API
- Very long answers that inflate cost
Doesn't protect against
- Overuse of the intended feature itself, which limits handle
Limits per plan
Different limits for free and paying users, based on a verified entitlement.
Protects against
- Free users using paid-plan capacity
Doesn't protect against
- Payment fraud: it is only as good as the payment check behind it
Moderation and personal-data filters
Checks, often called guardrails, that block harmful content or remove personal data before a prompt reaches the model, or before an answer reaches the user.
Protects against
- Prompts that break your content policy
- Personal data reaching the provider
Doesn't protect against
- Cost abuse: harmless-looking requests still cost money
Seeing what happens
Records and signals that show who uses your AI features and what they cost.
Request logs
A record of each call: time, user, model, tokens, result and cost. Some gateways also store the prompt and answer text, which you may be able to switch off.
Helps with
- Investigating abuse, errors and unexpected costs
Doesn't help with
- Privacy, when prompts are stored: they may contain personal data
Usage and cost per user
Totals of requests, tokens and cost for each user.
Helps with
- Finding who drives your bill
- Setting plan prices from real usage
Doesn't help with
- Stopping abuse on its own: that takes limits
Alerts
Notifications by email, chat or webhook when spending, errors or one user's usage cross a threshold.
Helps with
- Reacting before the monthly bill arrives
Doesn't help with
- Blocking anything by itself
Routing and capabilities
What a gateway can do with a request on its way to the provider.
Streaming
The answer arrives a few words at a time, over server-sent events, instead of all at once.
Helps with
- Responsive chat interfaces
Doesn't help with
- Exact budgets: cost is known only when the stream ends, and an interrupted stream may go uncounted
Realtime and voice sessions
Long-lived WebSocket or WebRTC connections for live voice and conversation.
Helps with
- Voice features with low delay
Doesn't help with
- Checking every message: a session is usually verified once, when it opens
Fallbacks
When a provider fails or rate-limits a request, the gateway retries with another model or provider.
Helps with
- Provider outages and rate-limit errors
Doesn't help with
- Consistent answers: the backup model behaves differently
Gateway caching
The gateway answers identical requests from its own cache instead of calling the provider again. It differs from the providers' prompt caching, which only makes a repeated start of a prompt cheaper.
Helps with
- Cost and speed for questions that repeat exactly
Doesn't help with
- Personal prompts, which rarely repeat word for word
OpenAI-compatible API
The gateway accepts OpenAI's request format, so existing OpenAI client code works by changing the base URL.
Helps with
- Switching providers with little code change
Doesn't help with
- Provider-specific features that the shared format can't express
To see how these protections fit together in one app, read How to protect your OpenAI API key in an iOS app. The comparison of AI gateways for mobile apps shows which products include which of them. App AI Gateway, the product we build, combines App Attest on every request, optional sign-in and purchase checks, rate limits and budgets in one gateway, hosted or self-hosted.
