Turn it on
- In Xcode, add the App Attest capability to your app target. It adds
com.apple.developer.devicecheck.appattest-environmentto the entitlements:developmentfor debug builds,productionfor TestFlight and the App Store. - In the dashboard, enter your Apple team ID (10 letters and digits, in your Apple Developer account under Membership).
- Choose a mode:
Nothing changes in your code. PoolKit attests a key the first time it needs cloud assist, then signs each request.
What it covers
- Cloud assist: naming things, answers (also streamed), profiles and rules. These are the calls that cost units.
- Registering an install and downloading models are not signed. They hold nothing about a person and cost nothing.
- Everything on the device keeps working whatever the mode, including when a request is refused.
Test keys and the Simulator
The Simulator has no App Attest, so test keys only ever report, even under Enforce. A live key accepts only keys from App Attest’s production environment, so a debug build signed for development needs a test key.How a request is checked
- PoolKit makes a key in the Secure Enclave and asks Pool for a one-time challenge.
- Apple attests the key over that challenge. Pool checks the certificate chain up to Apple’s App Attestation root, that the key is the one named, and that it was made for your team and bundle ID, then keeps its public key.
- Each cloud assist request carries
X-Pool-Attest-KeyandX-Pool-Assertion: a signature over the exact request body. Pool checks it against the stored key, and checks that the signature’s counter was not used before, so a request cannot be replayed.
PoolError.service(status: 401). See Service API for the wire format.

