Hi there,
I am wondering
How to handle Hardware-backed keystore in biometric authentication?
regards and thanks
Here’s a practical, step‑by‑step way to use the Touch ID Plugin in an OutSystems 11 mobile app to implement biometric login.
CheckTouchIdPlugin
TouchId
Success = True
Success = False
Make sure the device:
Create a simple screen to verify the plugin is working:
Check Fingerprint
Success
Success=True
Pseudo‑logic:
OnClick: CheckTouchIdPlugin If Not IsAvailable ShowMessage("Fingerprint not available or not configured.") Exit TouchId If Success ShowMessage("Fingerprint authenticated.") Else ShowMessage("Fingerprint failed or cancelled.")
This is the minimal pattern described in the Forge component examples.Touch ID Plugin
Typical requirement:
On your Login screen:
Login
BiometricEnabled = True
BiometricEnabled
On the same Login screen, when the app starts:
True
Success=False
High‑level flow:
OnAppStart or OnLoginScreenInit: If BiometricEnabled Show "Login with Touch ID" button OnTouchIdLoginButtonClick: CheckTouchIdPlugin If Not Available ShowMessage("Touch ID not available.") Exit TouchId If Success // Quick login logic (e.g., call REST with stored device token) NavigateToHome Else ShowMessage("Fingerprint failed. Use username and password.")
This is essentially what the Touch ID Login Sample Forge component demonstrates.Touch ID Plugin
“Touch Id is not defined” error
Plugin doesn’t prompt for fingerprint
Beginner: login then fingerprint only afterwards
If you want to see real logic and screens:
If you describe what your current login flow looks like (e.g., OutSystems built‑in login vs REST backend), I can map this Touch ID step‑by‑step onto your exact architecture.
In OutSystems 11 you don’t handle the hardware‑backed keystore directly in your app logic; you let the native OS + plugin do it, and you design your biometric flow so the secrets/tokens are always stored and accessed through that hardware‑backed storage.
There are two practical levels you can use:
This is the supported way to get OS‑level, hardware‑backed protection without writing native code yourself.
So your OutSystems code doesn’t know if it’s a Secure Enclave or TEE; it just knows: “I can store a secret, and the OS will only release it after biometric/lock‑screen auth.”
First (full) login
KeyStorePlugin.SetValue
RefreshToken
DeviceToken
IsBiometricEnabled = True
KeyAuthentication = True
Quick login (biometric)
KeyStorePlugin.GetValue
/token/refresh
/auth/quick-login
Key point: no credentials are stored on the device, only tokens, and they live in hardware‑backed keystore guarded by biometrics. This is aligned with the guidance not to store passwords locally.Mobile Application Architecture – Security > Data Storage and Encryption Best Practices
If your requirement is not just “protect a token with biometrics” but specifically:
then you need a custom mobile plugin; OutSystems doesn’t ship one that exposes GenerateKeyPair/Sign out of the box.Get Public key from Plugin Touch Id
GenerateKeyPair
Sign
Native layer (inside your custom plugin)
SecKeyCreateRandomKey
KeyPairGenerator
KeyGenParameterSpec
setUserAuthenticationRequired(true)
OutSystems plugin wrapper
GenerateKeyPair()
Sign(Challenge)
Sign()
Server‑side (REST in OutSystems or external)
/auth/challenge
/auth/verify
Again, OutSystems just calls plugin actions; the hardware‑backed keystore behaviour is enforced by native APIs you use inside the plugin.
In both cases, from OutSystems’ side you “handle” the hardware‑backed keystore by:
In this context, it means the OS will force the user to unlock the device (PIN/pattern/password and/or biometrics) before your app can read a secret stored in the Key Store Plugin.
Concretely, in OutSystems 11 with the Key Store Plugin:
You store a secret with KeyAuthentication = True In the SetValue client action, there is a parameter called KeyAuthentication.
SetValue
KeyAuthentication
KeyAuthentication = False
What the user sees when you call GetValue
GetValue
GetValue.Value
GetValue.Success
Why this is important for biometric flows
Prerequisite: device must be “secure”
So, “require user authentication before a value can be read” = set KeyAuthentication = True when storing the secret, which makes the OS show its lock/biometric prompt each time you try to read that secret, and only returns it if the user successfully authenticates.