Entitlements reference
When you add the App Attest capability in Xcode, the only file that changes is your target’s entitlements file. This page documents the one key that matters.
The key
com.apple.developer.devicecheck.appattest-environment
Values
development— for builds signed with a development provisioning profile (running from Xcode on your device).production— for builds signed with a distribution profile (TestFlight, App Store, Enterprise distribution).
The value Xcode writes depends on how the build is signed. You do not usually set this by hand.
What the file looks like
Minimal example — YourApp.entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/property-list-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.devicecheck.appattest-environment</key>
<string>development</string>
</dict>
</plist>
In a typical project the file will also contain other entitlements (App Groups, Keychain Sharing, Push Notifications, and so on). Those are unrelated to App Attest and can coexist safely.
How the environment maps to AppAttest
AppAttest uses the attestation environment reported by Apple to decide which environment’s secrets to deliver.
| Entitlement value | Apple attestation server | AppAttest environment |
|---|---|---|
development | Apple sandbox | development secrets |
production | Apple production | production secrets |
This means the same device, running the same app binary signed two different ways, will get two different sets of secrets. That is the intended behavior: your development key goes to development builds, your production key goes to App Store builds.
Automatic signing vs. manual signing
With automatic signing (the default), Xcode sets the value correctly based on the build configuration and the signing identity:
- Debug build, development team →
development. - Release build, distribution team →
production. - Archive for App Store →
production.
With manual signing, you control the provisioning profile selection. The value in the entitlements file should match the type of profile you use.
If you edit the file by hand
Do not. Xcode will overwrite it the next time it manages the capability. If you need to share one entitlements file across configurations with different values, use a separate entitlements file per configuration and wire them up in Build Settings (CODE_SIGN_ENTITLEMENTS). That’s rare and is not something you should do unless an Apple DTS engineer tells you to.
Verifying at runtime
If the entitlement is missing or malformed, attest() throws AppAttestError.attestationUnsupported. Same error is thrown on older devices and simulators — check the underlying DCAppAttestService.isSupported before deciding which path you’re on. See the SDK’s ErrorHandling.md for every case.
Troubleshooting
Entitlement missing after adding the capability
DerivedData can hold a stale entitlement snapshot. See the troubleshooting section in Xcode setup.
Capability disappears after merging a colleague’s changes
Your project file has a conflict. Open .pbxproj and confirm the entitlements-file reference is present for your target’s build configurations. The path should match a file that exists in your source tree.
Attestation works in development but fails in TestFlight
The distribution profile does not have App Attest enabled on the App ID. Re-check Apple Developer Console setup — the capability has to be enabled on the identifier you use to sign distribution builds.
What’s next
- For AI agents — how an AI helping a developer should walk through this setup.