Skip to main content
ClarioDesk does not use bearer tokens for end users. Identity is the device, proven by a non-extractable hardware keypair. This removes an entire class of setup (no HMAC secret, no “secure mode”, no token refresh) and makes a leaked publishable key a non-event.

How it works

On first launch the SDK generates an ECDSA P-256 keypair inside the device’s secure hardware:
  • iOS — Secure Enclave when present (most iPhones since the 5s), software Keychain otherwise. Requires iOS 13+.
  • Android — StrongBox when supported (Pixel 3+, recent Samsung), TEE-backed Keystore otherwise. Requires API 23+ (Marshmallow).
The private key is never extractable. The SDK registers the public key with the backend via a challenge-response handshake, then signs every authenticated request (and the realtime handshake) with the private key. The backend records which tier produced the key — secure_enclave, tee, strongbox, or software.
React Native + Expo Go: native modules can’t load in Expo Go, so the SDK transparently falls back to a software ECDSA P-256 key. You can evaluate the entire flow in Expo Go and ship hardware-backed with no code change. The backend records the software attestation either way.

The publishable key

You ship one publishable key (pk_live_…) in your app binary. Its only capability is letting a fresh install register a device. It cannot read tickets, list users, or impersonate anyone. If your key leaks, an attacker can register throwaway devices (rate-limited and bounded) — but they cannot touch any existing user’s data, because every authenticated call is signed by a private key that never left the original device’s secure hardware.
You ship the key, your users are secure by default. There is no separate “secure mode” to enable.

Identity is optional metadata

identify({ externalId, email, traits }) attaches your user’s identity to the device row. It is pure metadata — it grants no access, because access is already established by the device key. If you never call identify(), tickets still work; agents just see an “Unverified device” badge instead of an email. This is why identify() is safe to call unconditionally on every launch — see Identity & lifecycle.