{"abstract":[{"text":"Ensure that requests your server receives come from legitimate instances of your","type":"text"},{"text":" ","type":"text"},{"text":"app.","type":"text"}],"hierarchy":{"paths":[["doc:\/\/com.apple.documentation\/documentation\/technologies","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck"]]},"identifier":{"interfaceLanguage":"swift","url":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/establishing-your-app-s-integrity"},"kind":"article","legalNotices":{"copyright":"Copyright &copy; 2026 Apple Inc. All rights reserved.","privacyPolicy":"https:\/\/www.apple.com\/privacy\/privacy-policy","termsOfUse":"https:\/\/www.apple.com\/legal\/internet-services\/terms\/site.html"},"metadata":{"modules":[{"name":"DeviceCheck"}],"role":"article","roleHeading":"Article","title":"Establishing your app’s integrity"},"primaryContentSections":[{"content":[{"anchor":"overview","level":2,"text":"Overview","type":"heading"},{"inlineContent":[{"text":"You can’t rely on your app’s logic to perform security checks on itself because a","type":"text"},{"text":" ","type":"text"},{"text":"compromised app can falsify the results. Instead, you use the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/shared","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"instance of the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService","isActive":true,"type":"reference"},{"text":" class in your app to create a","type":"text"},{"text":" ","type":"text"},{"text":"hardware-based, cryptographic key that uses Apple servers to certify that the key","type":"text"},{"text":" ","type":"text"},{"text":"belongs to a valid instance of your app. Then you use the service to cryptographically","type":"text"},{"text":" ","type":"text"},{"text":"sign server requests using the certified key. Your app uses these measures to assert","type":"text"},{"text":" ","type":"text"},{"text":"its legitimacy with any server requests for sensitive or premium content.","type":"text"}],"type":"paragraph"},{"inlineContent":[{"identifier":"establishing_your_app_s_integrity-1","type":"image"}],"type":"paragraph"},{"inlineContent":[{"text":"This article describes how to modify your app to use the App Attest service. For","type":"text"},{"text":" ","type":"text"},{"text":"a description of the complementary logic that you add to your server, see ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/validating-apps-that-connect-to-your-server","isActive":true,"type":"reference"},{"text":".","type":"text"}],"type":"paragraph"},{"content":[{"inlineContent":[{"text":"To use the App Attest service, your app must have an App ID that you register","type":"text"},{"text":" ","type":"text"},{"text":"on the ","type":"text"},{"identifier":"https:\/\/developer.apple.com\/account\/","isActive":true,"type":"reference"},{"text":" website.","type":"text"}],"type":"paragraph"}],"name":"Note","style":"note","type":"aside"},{"anchor":"Check-for-availability","level":3,"text":"Check for availability","type":"heading"},{"inlineContent":[{"text":"Not all devices can use the App Attest service, so it’s important to have your app","type":"text"},{"text":" ","type":"text"},{"text":"run a compatibility check before accessing the service. If the user’s app doesn’t","type":"text"},{"text":" ","type":"text"},{"text":"pass the compatibility check, gracefully bypass the service. You check for availability","type":"text"},{"text":" ","type":"text"},{"text":"by reading the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/isSupported","isActive":true,"type":"reference"},{"text":" property.","type":"text"}],"type":"paragraph"},{"code":["let service = DCAppAttestService.shared","if service.isSupported {","    \/\/ Perform key generation and attestation.","}","\/\/ Continue with server access."],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"You change the behavior of both your app, as the example above shows, and your server","type":"text"},{"text":" ","type":"text"},{"text":"— which can no longer require assertions — when you find that the device doesn’t","type":"text"},{"text":" ","type":"text"},{"text":"support the service.","type":"text"}],"type":"paragraph"},{"content":[{"inlineContent":[{"text":"Action, extensible SSO, and watchOS extensions are supported. All other","type":"text"},{"text":" ","type":"text"},{"text":"extension types are not supported, even if the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/isSupported","isActive":true,"type":"reference"},{"text":"","type":"text"},{"text":" ","type":"text"},{"text":"method property is ","type":"text"},{"identifier":"doc:\/\/com.apple.documentation\/documentation\/Swift\/true","isActive":true,"type":"reference"},{"text":".","type":"text"}],"type":"paragraph"}],"name":"Important","style":"important","type":"aside"},{"anchor":"Create-a-key-pair","level":3,"text":"Create a key pair","type":"heading"},{"inlineContent":[{"text":"For each user account on each device running your app, generate a unique, hardware-based,","type":"text"},{"text":" ","type":"text"},{"text":"cryptographic key pair by calling the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/generateKey(completionHandler:)","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"method.","type":"text"}],"type":"paragraph"},{"code":["service.generateKey { keyId, error in","    guard error == nil else { \/* Handle the error. *\/ }","","    \/\/ Cache keyId for subsequent operations.","}"],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"On success, the method’s completion handler returns a key identifier that you use","type":"text"},{"text":" ","type":"text"},{"text":"later to access the key. Record the identifier in persistent storage — for example,","type":"text"},{"text":" ","type":"text"},{"text":"by writing it to a file — because there’s no way to use the key without the identifier,","type":"text"},{"text":" ","type":"text"},{"text":"and no way to get the identifier later. The device automatically stores the associated","type":"text"},{"text":" ","type":"text"},{"text":"private key in the Secure Enclave, from where the App Attest service can use it to","type":"text"},{"text":" ","type":"text"},{"text":"create signatures, but from where no process can ever directly read or modify it,","type":"text"},{"text":" ","type":"text"},{"text":"ensuring its security.","type":"text"}],"type":"paragraph"},{"content":[{"inlineContent":[{"text":"If you create a key pair in an App Clip, use the same key pair in the","type":"text"},{"text":" ","type":"text"},{"text":"corresponding app. To support this, be sure to store the identifier in a shared container","type":"text"},{"text":" ","type":"text"},{"text":"accessible from your full app. For more information about sharing data between your","type":"text"},{"text":" ","type":"text"},{"text":"App Clip and your full app, see ","type":"text"},{"identifier":"doc:\/\/com.apple.documentation\/documentation\/AppClip\/sharing-data-between-your-app-clip-and-your-full-app","isActive":true,"type":"reference"},{"text":".","type":"text"}],"type":"paragraph"}],"name":"Important","style":"important","type":"aside"},{"inlineContent":[{"text":"Don’t reuse a key among multiple users on a device because this weakens security","type":"text"},{"text":" ","type":"text"},{"text":"protections. In particular, it becomes hard to detect an attack that uses a single","type":"text"},{"text":" ","type":"text"},{"text":"compromised device to serve multiple remote users running a compromised version of","type":"text"},{"text":" ","type":"text"},{"text":"your app. For more information, see ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/assessing-fraud-risk","isActive":true,"type":"reference"},{"text":".","type":"text"}],"type":"paragraph"},{"anchor":"Certify-the-key-pairs-as-valid","level":3,"text":"Certify the key pairs as valid","type":"heading"},{"inlineContent":[{"text":"Before using a key pair, ask Apple to attest to its origin on Apple hardware running","type":"text"},{"text":" ","type":"text"},{"text":"an uncompromised version of your app. Because you can’t trust your app’s logic to","type":"text"},{"text":" ","type":"text"},{"text":"verify the attestation result, you send the result to your server. To reduce the","type":"text"},{"text":" ","type":"text"},{"text":"risk of replay attacks during this procedure, attestation embeds the hash of a unique,","type":"text"},{"text":" ","type":"text"},{"text":"one-time challenge from your server. You can create a suitable value using the ","type":"text"},{"identifier":"doc:\/\/com.apple.documentation\/documentation\/CryptoKit\/SHA256","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"implementation in CryptoKit. The challenge should be at least 16 bytes in length to ensure","type":"text"},{"text":" ","type":"text"},{"text":"sufficient entropy to ensure guessing them is infeasible.","type":"text"}],"type":"paragraph"},{"code":["import CryptoKit","","let challenge = <# Data from your server. #>","let hash = Data(SHA256.hash(data: challenge))"],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"Using the hash, along with the key pair you create in the previous section, call","type":"text"},{"text":" ","type":"text"},{"text":"the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/attestKey(_:clientDataHash:completionHandler:)","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"method to initiate attestation.","type":"text"}],"type":"paragraph"},{"code":["service.attestKey(keyId, clientDataHash: hash) { attestation, error in","    guard error == nil else { \/* Handle error and return. *\/ }","","    \/\/ Send the attestation object to your server for verification.","}"],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"If the method, which accesses a remote Apple server, returns the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCError-swift.struct\/serverUnavailable","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"error, try attestation again later with the same key. For any other error, discard","type":"text"},{"text":" ","type":"text"},{"text":"the key identifier and create a new key when you want to try again. Otherwise, send","type":"text"},{"text":" ","type":"text"},{"text":"the completion handler’s attestation object and the ","type":"text"},{"code":"keyId","type":"codeVoice"},{"text":" to your server for processing.","type":"text"}],"type":"paragraph"},{"content":[{"inlineContent":[{"text":"If your app already has millions of daily active users and you want to start calling","type":"text"},{"text":" ","type":"text"},{"text":"the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/attestKey(_:clientDataHash:completionHandler:)","isActive":true,"type":"reference"},{"text":" method to initiate","type":"text"},{"text":" ","type":"text"},{"text":"attestation from your app, please review ","type":"text"},{"identifier":"doc:\/\/com.apple.documentation\/documentation\/DeviceCheck\/preparing-to-use-the-app-attest-service","isActive":true,"type":"reference"},{"text":"","type":"text"},{"text":" ","type":"text"},{"text":"for guidance on safely ramping your users.","type":"text"}],"type":"paragraph"}],"name":"Important","style":"important","type":"aside"},{"inlineContent":[{"text":"If you use the ","type":"text"},{"identifier":"doc:\/\/com.apple.documentation\/documentation\/Foundation\/url-loading-system","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"to communicate with your server, you can send an unmodified attestation object. If","type":"text"},{"text":" ","type":"text"},{"text":"you communicate with your server by generating text-based HTTPS queries, convert","type":"text"},{"text":" ","type":"text"},{"text":"the attestation object to a Base64-encoded string first.","type":"text"}],"type":"paragraph"},{"code":["let attestationString = attestation?.base64EncodedString()"],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"Your server deems the app instance to be valid if it can successfully verify the","type":"text"},{"text":" ","type":"text"},{"text":"attestation object. In this case, be sure to persistently store the key identifier","type":"text"},{"text":" ","type":"text"},{"text":"— not the attestation object — in your app for future use in signing server requests.","type":"text"}],"type":"paragraph"},{"anchor":"Assert-your-apps-validity-as-necessary","level":3,"text":"Assert your app’s validity as necessary","type":"heading"},{"inlineContent":[{"text":"After successfully verifying a key’s attestation, your server can require the app","type":"text"},{"text":" ","type":"text"},{"text":"to assert its legitimacy for any or all future server requests. The app does this","type":"text"},{"text":" ","type":"text"},{"text":"by signing the request. In the app, first obtain a unique, one-time challenge from","type":"text"},{"text":" ","type":"text"},{"text":"the server. You use a challenge here, like for attestation, to avoid replay attacks.","type":"text"},{"text":" ","type":"text"},{"text":"Then combine the challenge with the server request to create a hash.","type":"text"}],"type":"paragraph"},{"code":["let challenge = <# A string from your server #>","let request = [ \"action\": \"getGameLevel\",","                \"levelId\": \"1234\",","                \"challenge\": challenge ]","guard let clientData = try? JSONEncoder().encode(request) else { return }","let clientDataHash = Data(SHA256.hash(data: clientData))"],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"Use this hash and the key identifier that you generate above to create an assertion","type":"text"},{"text":" ","type":"text"},{"text":"object by calling the ","type":"text"},{"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/generateAssertion(_:clientDataHash:completionHandler:)","isActive":true,"type":"reference"},{"text":" ","type":"text"},{"text":"method.","type":"text"}],"type":"paragraph"},{"code":["service.generateAssertion(keyId, clientDataHash: clientDataHash) { assertion, error in","    guard error == nil else { \/* Handle the error. *\/ }","","    \/\/ Send the assertion and request to your server.","}"],"syntax":"swift","type":"codeListing"},{"inlineContent":[{"text":"On success, pass the completion handler’s assertion object, along with the client","type":"text"},{"text":" ","type":"text"},{"text":"data, to the server. If the assertion object fails verification, it’s your responsibility","type":"text"},{"text":" ","type":"text"},{"text":"to decide how to handle the request.","type":"text"}],"type":"paragraph"},{"inlineContent":[{"text":"There’s no restriction on the number of assertions that you can make with a key.","type":"text"},{"text":" ","type":"text"},{"text":"Nevertheless, you typically reserve assertions for requests made at sensitive moments","type":"text"},{"text":" ","type":"text"},{"text":"in your app’s life cycle, like when the app downloads premium content.","type":"text"}],"type":"paragraph"},{"anchor":"Start-over-on-reinstallation","level":3,"text":"Start over on reinstallation","type":"heading"},{"inlineContent":[{"text":"The keys that you generate remain valid through regular app updates, but don’t survive","type":"text"},{"text":" ","type":"text"},{"text":"app reinstallation, device migration, or restoration of a device from a backup. In","type":"text"},{"text":" ","type":"text"},{"text":"these cases, you need to start the process from the beginning and generate a new","type":"text"},{"text":" ","type":"text"},{"text":"key. Try to limit new key generation to only these events, or to the addition of","type":"text"},{"text":" ","type":"text"},{"text":"new users. Keeping the key count low on a device helps when trying to detect certain","type":"text"},{"text":" ","type":"text"},{"text":"kinds of fraud.","type":"text"}],"type":"paragraph"}],"kind":"content"}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"seeAlsoSections":[{"anchor":"App-Attest","generated":true,"identifiers":["doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/validating-apps-that-connect-to-your-server","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/assessing-fraud-risk","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/preparing-to-use-the-app-attest-service","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/attestation-object-validation-guide","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService","doc:\/\/com.apple.documentation\/documentation\/BundleResources\/Entitlements\/com.apple.developer.devicecheck.appattest-environment"],"title":"App Attest"}],"variants":[{"paths":["\/documentation\/devicecheck\/establishing-your-app-s-integrity"],"traits":[{"interfaceLanguage":"swift"}]},{"paths":["\/documentation\/devicecheck\/establishing-your-app-s-integrity"],"traits":[{"interfaceLanguage":"occ"}]}],"references":{"doc://com.apple.DeviceCheck/documentation/DeviceCheck":{"abstract":[{"text":"Reduce fraudulent use of your services by managing device state and asserting app","type":"text"},{"text":" ","type":"text"},{"text":"integrity.","type":"text"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck","kind":"symbol","role":"collection","title":"DeviceCheck","type":"topic","url":"\/documentation\/devicecheck"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCAppAttestService":{"abstract":[{"text":"A service that you use to validate the instance of your app running on a","type":"text"},{"text":" ","type":"text"},{"text":"device.","type":"text"}],"fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"identifier","text":"DCAppAttestService"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService","kind":"symbol","navigatorTitle":[{"kind":"identifier","text":"DCAppAttestService"}],"role":"symbol","title":"DCAppAttestService","type":"topic","url":"\/documentation\/devicecheck\/dcappattestservice"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCAppAttestService/attestKey(_:clientDataHash:completionHandler:)":{"abstract":[{"text":"Asks Apple to attest to the validity of a generated cryptographic key.","type":"text"}],"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"attestKey"},{"kind":"text","text":"("},{"kind":"typeIdentifier","preciseIdentifier":"s:SS","text":"String"},{"kind":"text","text":", "},{"kind":"externalParam","text":"clientDataHash"},{"kind":"text","text":": "},{"kind":"typeIdentifier","preciseIdentifier":"s:10Foundation4DataV","text":"Data"},{"kind":"text","text":", "},{"kind":"externalParam","text":"completionHandler"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","preciseIdentifier":"s:10Foundation4DataV","text":"Data"},{"kind":"text","text":"?, (any "},{"kind":"typeIdentifier","preciseIdentifier":"s:s5ErrorP","text":"Error"},{"kind":"text","text":")?) -> "},{"kind":"typeIdentifier","preciseIdentifier":"s:s4Voida","text":"Void"},{"kind":"text","text":")"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/attestKey(_:clientDataHash:completionHandler:)","kind":"symbol","navigatorTitle":[{"kind":"text","text":"- "},{"kind":"identifier","text":"attestKey:clientDataHash:completionHandler:"}],"role":"symbol","title":"attestKey(_:clientDataHash:completionHandler:)","type":"topic","url":"\/documentation\/devicecheck\/dcappattestservice\/attestkey(_:clientdatahash:completionhandler:)"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCAppAttestService/generateAssertion(_:clientDataHash:completionHandler:)":{"abstract":[{"text":"Creates a block of data that demonstrates the legitimacy of an instance of","type":"text"},{"text":" ","type":"text"},{"text":"your app running on a device.","type":"text"}],"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"generateAssertion"},{"kind":"text","text":"("},{"kind":"typeIdentifier","preciseIdentifier":"s:SS","text":"String"},{"kind":"text","text":", "},{"kind":"externalParam","text":"clientDataHash"},{"kind":"text","text":": "},{"kind":"typeIdentifier","preciseIdentifier":"s:10Foundation4DataV","text":"Data"},{"kind":"text","text":", "},{"kind":"externalParam","text":"completionHandler"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","preciseIdentifier":"s:10Foundation4DataV","text":"Data"},{"kind":"text","text":"?, (any "},{"kind":"typeIdentifier","preciseIdentifier":"s:s5ErrorP","text":"Error"},{"kind":"text","text":")?) -> "},{"kind":"typeIdentifier","preciseIdentifier":"s:s4Voida","text":"Void"},{"kind":"text","text":")"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/generateAssertion(_:clientDataHash:completionHandler:)","kind":"symbol","navigatorTitle":[{"kind":"text","text":"- "},{"kind":"identifier","text":"generateAssertion:clientDataHash:completionHandler:"}],"role":"symbol","title":"generateAssertion(_:clientDataHash:completionHandler:)","type":"topic","url":"\/documentation\/devicecheck\/dcappattestservice\/generateassertion(_:clientdatahash:completionhandler:)"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCAppAttestService/generateKey(completionHandler:)":{"abstract":[{"text":"Creates a new cryptographic key for use with the App Attest service.","type":"text"}],"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"generateKey"},{"kind":"text","text":"("},{"kind":"externalParam","text":"completionHandler"},{"kind":"text","text":": ("},{"kind":"typeIdentifier","preciseIdentifier":"s:SS","text":"String"},{"kind":"text","text":"?, (any "},{"kind":"typeIdentifier","preciseIdentifier":"s:s5ErrorP","text":"Error"},{"kind":"text","text":")?) -> "},{"kind":"typeIdentifier","preciseIdentifier":"s:s4Voida","text":"Void"},{"kind":"text","text":")"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/generateKey(completionHandler:)","kind":"symbol","navigatorTitle":[{"kind":"text","text":"- "},{"kind":"identifier","text":"generateKeyWithCompletionHandler:"}],"role":"symbol","title":"generateKey(completionHandler:)","type":"topic","url":"\/documentation\/devicecheck\/dcappattestservice\/generatekey(completionhandler:)"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCAppAttestService/isSupported":{"abstract":[{"text":"A Boolean value that indicates whether a particular device provides the App","type":"text"},{"text":" ","type":"text"},{"text":"Attest service.","type":"text"}],"fragments":[{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"isSupported"},{"kind":"text","text":": "},{"kind":"typeIdentifier","preciseIdentifier":"s:Sb","text":"Bool"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/isSupported","kind":"symbol","navigatorTitle":[{"kind":"identifier","text":"supported"}],"role":"symbol","title":"isSupported","type":"topic","url":"\/documentation\/devicecheck\/dcappattestservice\/issupported"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCAppAttestService/shared":{"abstract":[{"text":"The shared App Attest service that you use to validate your app.","type":"text"}],"fragments":[{"kind":"keyword","text":"class"},{"kind":"text","text":" "},{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"shared"},{"kind":"text","text":": "},{"kind":"typeIdentifier","preciseIdentifier":"c:objc(cs)DCAppAttestService","text":"DCAppAttestService"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService\/shared","kind":"symbol","navigatorTitle":[{"kind":"identifier","text":"sharedService"}],"role":"symbol","title":"shared","type":"topic","url":"\/documentation\/devicecheck\/dcappattestservice\/shared"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/DCError-swift.struct/serverUnavailable":{"abstract":[{"text":"An error that indicates a failed attempt to contact the App Attest service during an attestation.","type":"text"}],"fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"var"},{"kind":"text","text":" "},{"kind":"identifier","text":"serverUnavailable"},{"kind":"text","text":": "},{"kind":"typeIdentifier","preciseIdentifier":"c:@E@DCError","text":"DCError"},{"kind":"text","text":"."},{"kind":"typeIdentifier","preciseIdentifier":"c:@E@DCError","text":"Code"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCError-swift.struct\/serverUnavailable","kind":"symbol","role":"symbol","title":"serverUnavailable","type":"topic","url":"\/documentation\/devicecheck\/dcerror-swift.struct\/serverunavailable"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/assessing-fraud-risk":{"abstract":[{"text":"Request and analyze risk data using server-to-server calls.","type":"text"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/assessing-fraud-risk","kind":"article","role":"article","title":"Assessing fraud risk","type":"topic","url":"\/documentation\/devicecheck\/assessing-fraud-risk"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/attestation-object-validation-guide":{"abstract":[{"text":"Use this guide to validate your implementation of verifying the attestation object verification process.","type":"text"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/attestation-object-validation-guide","kind":"article","role":"article","title":"Attestation Object Validation Guide","type":"topic","url":"\/documentation\/devicecheck\/attestation-object-validation-guide"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/preparing-to-use-the-app-attest-service":{"abstract":[{"text":"Test your implementation in a development environment and onboard users gradually.","type":"text"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/preparing-to-use-the-app-attest-service","kind":"article","role":"article","title":"Preparing to use the app attest service","type":"topic","url":"\/documentation\/devicecheck\/preparing-to-use-the-app-attest-service"},"doc://com.apple.DeviceCheck/documentation/DeviceCheck/validating-apps-that-connect-to-your-server":{"abstract":[{"text":"Verify that connections to your server come from legitimate instances of your app.","type":"text"}],"identifier":"doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/validating-apps-that-connect-to-your-server","kind":"article","role":"article","title":"Validating apps that connect to your server","type":"topic","url":"\/documentation\/devicecheck\/validating-apps-that-connect-to-your-server"},"doc://com.apple.documentation/documentation/AppClip/sharing-data-between-your-app-clip-and-your-full-app":{"abstract":[{"text":"Use CloudKit, Sign in with Apple, shared user defaults or containers, and the keychain to offer a smooth transition from your App Clip to your app.","type":"text"}],"identifier":"doc:\/\/com.apple.documentation\/documentation\/AppClip\/sharing-data-between-your-app-clip-and-your-full-app","kind":"article","role":"article","title":"Sharing data between your App Clip and your full app","type":"topic","url":"\/documentation\/appclip\/sharing-data-between-your-app-clip-and-your-full-app"},"doc://com.apple.documentation/documentation/BundleResources/Entitlements/com.apple.developer.devicecheck.appattest-environment":{"abstract":[{"text":"The environment for an app that uses the App Attest service to validate itself.","type":"text"}],"identifier":"doc:\/\/com.apple.documentation\/documentation\/BundleResources\/Entitlements\/com.apple.developer.devicecheck.appattest-environment","kind":"symbol","navigatorTitle":[{"kind":"identifier","text":"com.apple.developer.devicecheck.appattest-environment"}],"role":"symbol","title":"App Attest Environment","type":"topic","url":"\/documentation\/bundleresources\/entitlements\/com.apple.developer.devicecheck.appattest-environment"},"doc://com.apple.documentation/documentation/CryptoKit/SHA256":{"abstract":[{"text":"An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a","type":"text"},{"text":" ","type":"text"},{"text":"256-bit digest.","type":"text"}],"fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"SHA256"}],"identifier":"doc:\/\/com.apple.documentation\/documentation\/CryptoKit\/SHA256","kind":"symbol","navigatorTitle":[{"kind":"identifier","text":"SHA256"}],"role":"symbol","title":"SHA256","type":"topic","url":"\/documentation\/cryptokit\/sha256"},"doc://com.apple.documentation/documentation/DeviceCheck/preparing-to-use-the-app-attest-service":{"abstract":[{"text":"Test your implementation in a development environment and onboard users gradually.","type":"text"}],"identifier":"doc:\/\/com.apple.documentation\/documentation\/DeviceCheck\/preparing-to-use-the-app-attest-service","kind":"article","role":"article","title":"Preparing to use the app attest service","type":"topic","url":"\/documentation\/devicecheck\/preparing-to-use-the-app-attest-service"},"doc://com.apple.documentation/documentation/Foundation/url-loading-system":{"abstract":[{"text":"Interact with URLs and communicate with servers using standard Internet protocols.","type":"text"}],"identifier":"doc:\/\/com.apple.documentation\/documentation\/Foundation\/url-loading-system","kind":"article","role":"collectionGroup","title":"URL Loading System","type":"topic","url":"\/documentation\/foundation\/url-loading-system"},"doc://com.apple.documentation/documentation/Swift/true":{"abstract":[{"text":"A true value.","type":"text"}],"identifier":"doc:\/\/com.apple.documentation\/documentation\/Swift\/true","images":[{"identifier":"keyword-icon.svg","type":"icon"}],"kind":"symbol","navigatorTitle":[{"kind":"text","text":"true"}],"role":"symbol","title":"true","type":"topic","url":"\/documentation\/swift\/true"},"doc://com.apple.documentation/documentation/technologies":{"abstract":[],"identifier":"doc:\/\/com.apple.documentation\/documentation\/technologies","kind":"technologies","role":"overview","title":"Technologies","type":"topic","url":"\/documentation\/technologies"},"establishing_your_app_s_integrity-1":{"alt":"A diagram showing that your app receives challenges from your server and responds with an attestation and assertions, while relying on the App Attest logic.","identifier":"establishing_your_app_s_integrity-1","type":"image","variants":[{"traits":["2x","light"],"url":"\/images\/com.apple.DeviceCheck\/establishing_your_app_s_integrity-1@2x.png"},{"traits":["2x","dark"],"url":"\/images\/com.apple.DeviceCheck\/establishing_your_app_s_integrity-1~dark@2x.png"}]},"https://developer.apple.com/account/":{"identifier":"https:\/\/developer.apple.com\/account\/","title":"Apple Developer","titleInlineContent":[{"text":"Apple Developer","type":"text"}],"type":"link","url":"https:\/\/developer.apple.com\/account\/"},"keyword-icon.svg":{"alt":null,"identifier":"keyword-icon.svg","type":"image","variants":[{"traits":["1x","light"],"url":"\/images\/com.apple.Swift\/keyword-icon.svg"},{"traits":["1x","dark"],"url":"\/images\/com.apple.Swift\/keyword-icon~dark.svg"}]}},"variantOverrides":[{"patch":[{"op":"replace","path":"\/identifier\/interfaceLanguage","value":"occ"},{"op":"add","path":"\/topicSections","value":null},{"op":"replace","path":"\/seeAlsoSections","value":[{"anchor":"App-Attest","generated":true,"identifiers":["doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/validating-apps-that-connect-to-your-server","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/assessing-fraud-risk","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/preparing-to-use-the-app-attest-service","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/attestation-object-validation-guide","doc:\/\/com.apple.DeviceCheck\/documentation\/DeviceCheck\/DCAppAttestService","doc:\/\/com.apple.documentation\/documentation\/BundleResources\/Entitlements\/com.apple.developer.devicecheck.appattest-environment"],"title":"App Attest"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService\/title","value":"DCAppAttestService"},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService\/fragments","value":[{"kind":"identifier","text":"DCAppAttestService"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService\/navigatorTitle","value":[{"kind":"identifier","text":"DCAppAttestService"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1attestKey(_:clientDataHash:completionHandler:)\/title","value":"attestKey:clientDataHash:completionHandler:"},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1attestKey(_:clientDataHash:completionHandler:)\/fragments","value":[{"kind":"text","text":"- "},{"kind":"identifier","text":"attestKey:clientDataHash:completionHandler:"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1generateAssertion(_:clientDataHash:completionHandler:)\/title","value":"generateAssertion:clientDataHash:completionHandler:"},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1generateAssertion(_:clientDataHash:completionHandler:)\/fragments","value":[{"kind":"text","text":"- "},{"kind":"identifier","text":"generateAssertion:clientDataHash:completionHandler:"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1generateKey(completionHandler:)\/title","value":"generateKeyWithCompletionHandler:"},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1generateKey(completionHandler:)\/fragments","value":[{"kind":"text","text":"- "},{"kind":"identifier","text":"generateKeyWithCompletionHandler:"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1isSupported\/title","value":"supported"},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1isSupported\/fragments","value":[{"kind":"identifier","text":"supported"}]},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1shared\/title","value":"sharedService"},{"op":"replace","path":"\/references\/doc:~1~1com.apple.DeviceCheck~1documentation~1DeviceCheck~1DCAppAttestService~1shared\/fragments","value":[{"kind":"identifier","text":"sharedService"}]}],"traits":[{"interfaceLanguage":"occ"}]}]}