Create your appAttest account.
Sign up with your email. We verify with a one-time code. Add a team — your Apple Team ID becomes the work + billing boundary.
Get started
End-to-end, this takes about ten minutes on a real device. Each step is small. The docs go deeper on every part — this page is the path.
Sign up with your email. We verify with a one-time code. Add a team — your Apple Team ID becomes the work + billing boundary.
In the dashboard, click New app. Enter the bundle identifier from your Xcode project — they must match exactly. Pick a team. Two environments are created: development and production.
Open the app in the dashboard, select the development environment, click Add secret, give it a name (e.g. OPENAI_API_KEY) and paste the value. Repeat for each secret. Production values come later, when you're ready to ship.
App Attest is an Apple capability you turn on per-identifier. Open developer.apple.com → Certificates, Identifiers & Profiles → Identifiers → your app identifier. Scroll to App Services. Enable App Attest. Save.
In Xcode, open your project. Select your app target. Go to Signing & Capabilities. Click + Capability and add App Attest. Xcode adds the entitlement automatically.
In Xcode: File → Add Package Dependencies. Paste the SDK URL. Pick "Up to Next Major Version" from the latest tagged release. Add the AppAttest product to your app target.
https://github.com/AppAttest/sdk The SDK has no configuration. Bundle ID and Team ID come from the signed app at runtime — there is no key to paste in. One synchronous call in your App init runs the whole bootstrap.
import SwiftUI
import AppAttest
@main
struct MyApp: App {
init() { AppAttest.start() }
var body: some Scene {
WindowGroup { ContentView() }
}
} Wherever your code needs a value, ask for it by the name you used in the dashboard. The read is a synchronous subscript on a process-wide observable; SwiftUI re-renders any view reading it when the value changes.
struct ContentView: View {
var body: some View {
if let key = AppAttest.secrets["OPENAI_API_KEY"] {
Text("Ready")
} else {
ProgressView("Loading…")
}
}
} App Attest needs real Apple-signed hardware to produce attestations — the simulator does not work without a debug stub. Build and run on a device. In the dashboard, open your app and watch Recent activity for one attestation.succeeded and one sync.succeeded with the count of delivered secrets.
Add production secrets in the production environment. Click Subscribe in the dashboard — subscribing IS going live. Signed-store builds then attest as production and receive production values; debug builds keep getting sandbox values.
The keys live in Keychain on the device that attested. They never ship in your binary. Rotate a secret in the dashboard and running apps pick it up within ~15 minutes of foregrounding.