How to Extract API Keys from iOS Apps
2026-02-28 · KVProxy Team
If you've ever wondered how hard it is for someone to steal an API key from your iOS app, the answer is: not very.
Anyone with a copy of your app (from the App Store, TestFlight, or an ad-hoc build) can extract embedded secrets in a few minutes using tools that ship with macOS. No jailbreak, no special hardware.
This post walks through exactly how it's done, using a small example app that calls the ChatGPT API with a hardcoded key. By the end, you'll see why shipping API keys in mobile binaries is a losing game, and what to do instead.
Why This Matters
Mobile apps are distributed binaries. Everything you compile into the app: code, resources, and yes, string literals like API keys — ends up in a form that can be inspected. Obfuscation and "security through obscurity" might slow a casual snoop, but they don't stop a determined attacker.
Once a key is extracted:
- Usage abuse — Someone can run up your API bill or hit rate limits.
- Account compromise — Keys tied to your account can be revoked or used for fraud.
- Reputational risk — Leaked keys can be sold or shared.
The only robust approach is to never put the key in the app in the first place. Before we get to that, here's how the extraction actually works.
The Example App
Imagine a simple iOS app that uses the OpenAI Chat Completions API. The developer has added a service that holds the base URL and API key in code:
struct ChatGPTService {
private let baseURL = "https://api.openai.com/v1/chat/completions"
private let apiKey = "sk-abcdef1234567890abcdef1234567890abcdef12"
func generateText(prompt: String) async throws -> String {
...
}
}
The key is marked private, but that only affects Swift's visibility rules. At compile time, the string "sk-abcdef1234567890abcdef1234567890abcdef12" is embedded in the app binary. Private doesn't mean "not in the binary"; it just means "not exposed to other Swift code."
Step 1: Get an IPA
To extract secrets, an attacker needs the app in a form they can unpack.
IPA files can be exported from iOS devices using off-the-shelf tools like Apple Configurator or iMazing.
For this demo, we'll assume we have an IPA file for the example app named Extraction.ipa.
Step 2: Unzip the IPA
An IPA is just a ZIP archive. Unzip it and you get a Payload folder containing the app bundle:
unzip Extraction.ipa
Example output:
Archive: Extraction.ipa
creating: Payload
creating: Payload/Extraction.app
creating: Payload/Extraction.app/_CodeSignature
inflating: Payload/Extraction.app/embedded.mobileprovision
inflating: Payload/Extraction.app/Extraction
inflating: Payload/Extraction.app/Info.plist
inflating: Payload/Extraction.app/PkgInfo
inflating: Payload/Extraction.app/_CodeSignature/CodeResources
The main executable is Payload/Extraction.app/Extraction — that's the compiled binary that contains your code and every string literal you embedded.
Step 3: Run strings and Search for Secrets
The strings command (available on macOS and Linux) prints printable character sequences from a binary. It's intended for debugging, but it's also perfect for finding embedded keys, URLs, and other literals.
Search for something distinctive — like the sk- prefix used by OpenAI API keys:
strings Payload/Extraction.app/Extraction | grep "sk"
Output:
sk-abcdef1234567890abcdef1234567890abcdef12
There it is: the full API key, in plain text, with no reverse engineering required.
What This Proves
Hardcoded API keys in iOS apps are not secret. They live in the binary as plain strings (or trivially decoded data).
What to Do Instead
The fix is simple in principle: never put the key in the app. Something you control — a backend or a proxy — should hold your secrets and communicate with the 3rd party service on behalf on your app.
Building and maintaining your own backend just to proxy API calls is a lot of work. For many teams, that's overkill when all you need is to call an API without shipping the key.
KVProxy was designed for this exact purpose. Just add your API keys in the KVProxy dashboard and update a single line of code to your iOS app. Your app will then automatically route relevant requests through KVProxy, which securely injects your keys—so your app never touches them directly.
Ready to try it? Head to kvproxy.com to get started, or check out the KVProxy iOS Demo to see it in action.