Security

    iOS Face ID and Touch ID: using biometrics securely

    A 2026 view of iOS Face ID binding a Keychain item via access control so the Secure Enclave releases a secret only after a genuine biometric match, not a trusted boolean

    Face ID and Touch ID feel like strong security, and they can be, but only if you use them the right way. The common mistake is treating biometric authentication as a yes-or-no check: ask the system "is this the right user," get back true, and open the feature. That boolean is a UI gate, not a cryptographic guarantee, and on a compromised device it can be defeated. The secure pattern binds biometrics to the Keychain, so a secret is released by the Secure Enclave only after a successful biometric check. Here is how iOS biometrics work and how to use them so they actually protect something.

    Short answer

    On iOS, biometric authentication uses the LocalAuthentication framework to verify the user with Face ID or Touch ID. Per Apple's documentation, the secure way to use it is not to trust a simple success boolean from a policy evaluation, which is only a UI gate, but to bind the biometric check to the Keychain using access control, so a protected secret is released by the Secure Enclave only after a successful authentication. Biometrics gate local access to something; they do not replace server-side authentication. Add the NSFaceIDUsageDescription string, protect secrets with biometric-gated Keychain access control, and keep your server session and tokens as the real authority.

    What you should know

    • Biometrics verify the user locally: Face ID or Touch ID via LocalAuthentication.
    • A success boolean is not security: it is a UI gate that can be bypassed.
    • Bind to the Keychain: protect a secret so it releases only after biometrics.
    • The Secure Enclave enforces it: hardware-backed, not a value your code trusts.
    • It does not replace server auth: it gates local access, not the backend.

    How does biometric authentication work on iOS?

    Through the LocalAuthentication framework, which checks the user with Face ID or Touch ID. Your app creates an authentication context and asks the system to evaluate a policy, biometrics, or biometrics with a device-passcode fallback, and the system runs the prompt and returns whether authentication succeeded. You also add an NSFaceIDUsageDescription string so iOS can explain why your app uses Face ID. This is straightforward, and that is part of the problem: the easy path is to evaluate the policy, get a success result, and then proceed in your own code, which works but leans entirely on trusting that returned boolean. How much that protects depends on what you do with the result, not on the prompt appearing.

    What is the trap with a success boolean?

    That a boolean your code checks can be bypassed on a compromised device. The table contrasts the approaches.

    ApproachWhat protects the secret
    Evaluate policy, trust the success booleanYour code's check; bypassable if the runtime is compromised
    Bind biometrics to a Keychain item via access controlThe Secure Enclave releases the secret only on success
    No binding, secret available regardlessNothing; the gate is cosmetic

    If your app simply asks for biometric success and then reads a secret it already holds, an attacker who can manipulate the runtime, on a jailbroken device, for instance, can make the check return success or skip it, since the secret was never actually tied to the authentication. The stronger design stores the secret in the Keychain with biometric access control, so the item is only decrypted and released by the Secure Enclave after a genuine biometric match. Then the authentication is enforced by hardware, not by a branch in your code that can be patched.

    How do you use biometrics securely?

    Bind the biometric check to the Keychain, and keep the server as the authority. Store the sensitive value, a token, a key, a credential, in the Keychain with an access control that requires biometric authentication, so retrieving it forces a successful Face ID or Touch ID check enforced by the Secure Enclave, rather than your code deciding based on a boolean. Choose the access control level deliberately, for example requiring the current enrolled biometrics so that adding a new fingerprint or face invalidates access. Treat biometrics as gating local access to something on the device, while your backend still authenticates the session with proper tokens, since a local biometric success says nothing to your server by itself. And add the usage-description string so Face ID is permitted. The principle is that the secret, not a boolean, should depend on the authentication.

    What to watch out for

    The first trap is trusting the policy-evaluation success result as if it were security, when it is a UI gate; bind sensitive data to the Keychain instead. The second is treating a local biometric success as backend authentication, when your server still needs its own session and tokens. The third is omitting NSFaceIDUsageDescription, which prevents Face ID use and can cause a rejection. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled IPA against OWASP MASVS and assesses how your app stores secrets and uses the Keychain, which complements reviewing whether your biometric gate actually protects a secret. The access-control design you implement in the app.

    What to take away

    • iOS biometrics use LocalAuthentication for Face ID and Touch ID, but a success boolean from a policy evaluation is a UI gate, not security.
    • The secure pattern binds the biometric check to a Keychain item via access control, so the Secure Enclave releases the secret only after a genuine match.
    • Biometrics gate local access; they do not replace server-side authentication, which still needs proper tokens and sessions.
    • Add NSFaceIDUsageDescription, protect secrets with biometric-gated Keychain access, and use a pre-submission scan such as PTKD.com to check how your app stores secrets.
    • #ios
    • #face-id
    • #touch-id
    • #biometrics
    • #localauthentication
    • #keychain
    • #app-security

    Frequently asked questions

    How do iOS biometrics work for authentication?
    Through the LocalAuthentication framework. Your app creates an authentication context and asks the system to evaluate a policy, biometrics or biometrics with a passcode fallback, and the system shows the Face ID or Touch ID prompt and returns whether authentication succeeded. You also add an NSFaceIDUsageDescription string so iOS can explain why your app uses Face ID. The framework handles the prompt; how much it protects depends on what your app does with the result.
    Is a biometric success result enough for security?
    No. A success boolean returned from a policy evaluation is a UI gate, not a cryptographic guarantee. If your app simply checks for biometric success and then reads a secret it already holds, an attacker who can manipulate the runtime on a compromised device can make the check return success or skip it, since the secret was never tied to the authentication. The stronger design binds the secret to the biometric check so hardware enforces it.
    How do I use Face ID securely?
    Store the sensitive value in the Keychain with an access control that requires biometric authentication, so retrieving it forces a successful Face ID or Touch ID check enforced by the Secure Enclave, rather than your code deciding from a boolean. Choose the access-control level deliberately, such as requiring the current enrolled biometrics so a new enrollment invalidates access. That way the secret itself depends on the authentication, not a branch in your code that could be patched.
    Do biometrics replace server-side authentication?
    No. Biometrics gate local access to something on the device, but a local biometric success says nothing to your server by itself, so your backend still needs to authenticate the session with proper tokens. Use biometrics to protect local access, such as releasing a stored token from the Keychain, and keep the server as the real authority that validates that token. Treating a local Face ID success as backend authentication would leave your server trusting an unverified client.
    How do I check my app's biometric and secret handling?
    Scan the build. A pre-submission scan such as PTKD.com reads the compiled IPA against OWASP MASVS and assesses how your app stores secrets and uses the Keychain, which complements reviewing whether your biometric gate actually protects a secret or just checks a boolean. If secrets are not bound to biometric-gated Keychain access, the fix is to store them with the appropriate access control so the Secure Enclave enforces the authentication.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free