Attestation (Driver Layer)#
At the Driver Layer, attestation is the protocol that lets the Curity Identity Server trust that an HAAPI request originates from a genuine, unmodified copy of a registered app. Both platforms wrap their native attestation services and exchange the resulting attestation data for a Client Attestation Token (CAT), which the client then uses to obtain an HAAPI access token. For the conceptual overview, see Attestation and Fallback .
Per-Platform Mechanisms#
The iOS Driver uses Apple’s DCAppAttestService (the DeviceCheck framework) to attest the cryptographic key that signs HAAPI requests. The attestation protocol is performed automatically when HaapiTokenManager first acquires a CAT.
Configuration on the server side carries the Apple-assigned app-id (team ID plus bundle ID):
<attestation>
<ios>
<app-id>01234abcde.app.curity.io</app-id>
</ios>
</attestation>Optionally configure an iOS attestation policy under facilities/client-attestation/ios-policy to switch between production and non-production modes or to override certificate-chain validation.
The Android Driver uses hardware-backed Key Attestation through the Android Keystore. The TEE or StrongBox produces a certificate chain rooted in Google’s hardware-attestation CA, which the server validates as part of issuing a CAT.
Configuration on the server side carries the Android package name and the SHA-256 hash of the signing certificate (Base64-encoded):
<attestation>
<android>
<package-name>com.example.client.app</package-name>
<signature-digest>Z2DK...9oKQ=</signature-digest>
</android>
</attestation>To obtain the signature-digest, run ./gradlew signingReport, take the SHA-256 line, and convert it to Base64.
Custom Policies for Emulators and Development#
Hardware attestation does not work on emulators, simulators, or jailbroken devices. For development builds, define a custom attestation policy under facilities/client-attestation and reference it from the client.
Custom policies relax the security guarantees that attestation provides. Use them for development and emulator scenarios only — never in production.
<facilities xmlns="https://curity.se/ns/conf/base">
<client-attestation>
<ios-policy xmlns="https://curity.se/ns/conf/client-attestation">
<id>non-prod-policy</id>
<mode>non-production</mode>
<override-certificate-chain-validation>
<do-not-validate-certificate-chain/>
</override-certificate-chain-validation>
</ios-policy>
</client-attestation>
</facilities>Reference the policy from the client configuration via attestation/ios/ios-policy.
<facilities xmlns="https://curity.se/ns/conf/base">
<client-attestation>
<android-policy xmlns="https://curity.se/ns/conf/client-attestation">
<id>emulator-policy</id>
<verify-boot-state>false</verify-boot-state>
<minimum-security-level>software</minimum-security-level>
<override-certificate-chain-validation>
<do-not-validate-certificate-chain/>
</override-certificate-chain-validation>
</android-policy>
</client-attestation>
</facilities>Reference the policy from the client configuration via attestation/android/android-policy.
DCR Fallback#
When attestation fails — older operating system versions, jailbroken devices, or rare hardware faults reported by Apple as Error Domain=com.apple.devicecheck.error Code=3 — the Driver Layer raises a non-attestation error. The next step depends on whether the client is configured for Dynamic Client Registration fallback:
- With DCR configured: the client registers a per-device dynamic OAuth client and uses that for subsequent token requests. The fallback is wired up via the SDK Layer’s
HaapiAccessorrather than at the Driver Layer directly. - Without DCR configured: the flow halts. The application surfaces the failure to the user, typically directing them through an alternative authentication path or to support.
For the conceptual model and security trade-offs, see Dynamic Client Registration (DCR) .
Disabling Attestation for Testing#
For controlled testing scenarios, attestation validation can be disabled per-client on the server. The client still performs the attestation protocol, but the server does not validate the attestation data.
<attestation>
<disable-attestation-validation/>
</attestation>
Do not use this in production. When attestation validation is disabled, any application can act as the configured client. Restrict this setting to non-production environments — for example, integration testing where the real attestation services are unavailable.
How to implement this: iOS Driver · Android Driver · How to Configure DCR Fallback · Attestation and Fallback