High Latency with `DCAppAttestService.attestKey(_:clientDataHash:)` (4–8s) – Guidance Needed

Issue Summary

We are seeing consistently high latency when calling DCAppAttestService.shared.attestKey(_:clientDataHash:). The call routinely takes 4–5 seconds in the development environment and 7–8 seconds in production.

In contrast, other DeviceCheck operations execute very quickly on the same setup (e.g., DCDevice.generateToken takes ~100ms, and generateAssertion takes ~80ms).


Environment Details

  • Platform: iOS (reproduced on physical devices)
  • Framework: DeviceCheck / App Attest
  • Entitlements: com.apple.developer.devicecheck.appattest-environment set appropriately for each environment (development / production)
  • Execution Flow: generateKey (or keychain lookup) $\rightarrow$ attestKey $\rightarrow$ generateAssertion

Representative Timings (Development / Physical Device)

  • ensureKey (keychain reuse): 5 ms
  • generateDeviceToken: 91 ms
  • attestKey (Apple API execution): 5,196 ms
  • generateAssertion: 76 ms
  • Total Wall Time: ~5,505 ms

Steps to Reproduce

  1. On a physical iPhone, invoke DCAppAttestService.shared.generateKey() (or retrieve an existing keyId).
  2. Generate a client challenge hash (SHA256).
  3. Invoke attestKey(_:clientDataHash:completionHandler:) with the keyId and hash.
  4. Observe the multi-second delay before the completion handler returns the attestation statement.

Questions & Guidance Requested

  1. Expected Baseline: Is 4–8 seconds for a successful attestKey call considered expected behavior for Apple’s attestation servers, or does this indicate an anomaly?
  2. Environment & Regional Latency: Are there known factors (e.g., server geographic routing, network handshakes, or environment differences) that cause attestKey to be noticeably slower in production compared to development?
  3. Mitigation / Best Practices: Since attestation is recommended once per key/device lifecycle upon key generation, are there specific architectural patterns Apple recommends to avoid blocking UI or onboarding flows during this high-latency step?

Note: We can supply full sysdiagnose logs, device model/iOS version breakdowns, and code snippets if required.

Is 4–8 seconds for a successful attestKey call considered expected behavior for Apple’s attestation servers, or does this indicate an anomaly?

Remember, the attestKey: API call round-trips Apple servers and performs various validation steps along the way, to generate an attestation for a key.

All the other API operations are local, occurring only on the device. Thus, latency for the attestKey: API is expected, and further signifies why it should not be tied to an UI operation.

Are there known factors (e.g., server geographic routing, network handshakes, or environment differences) that cause attestKey to be noticeably slower in production compared to development?

Yes. It depends on the user's network connectivity and region. If you are experiencing particular slowness in a specific region, please file a feedback assistant, and we can evaluate expanding the App Attest server pods to different regions to improve latency.

Since attestation is recommended once per key/device lifecycle upon key generation, are there specific architectural patterns Apple recommends to avoid blocking UI or onboarding flows during this high-latency step?

This depends on your app setup, but you could create an utility that interfaces with App Attest to generate and attest a key, then kick this off in a Task following the launch of your app.

When your user enters a critical flow, where you need an attestation, you could then determine if an attestation for a key is prepared.

Sample code is something that is on my mind - please do file a feedback assistant if you think it would be helpful to see recommended usage code samples.

High Latency with `DCAppAttestService.attestKey(_:clientDataHash:)` (4–8s) – Guidance Needed
 
 
Q