> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clariodesk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Device-signed SDK auth, plus optional verified cross-device identity.

ClarioDesk does not use bearer tokens for its base SDK authentication. Identity is the device,
proven by a non-extractable hardware keypair. This removes an entire class of
setup and makes a leaked publishable key a non-event. Apps that need
cross-device continuity can separately enable [Verified identity](/concepts/verified-identity)
with a host token or pinned OIDC provider.

## 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`.

<Note>
  **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.
</Note>

## 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 and your users are secure by default. There's no separate
> "secure mode" to enable.

## Label-only identity

`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](/concepts/identity-lifecycle).

When Verified identity is enabled, `identityToken` is an authorization proof,
not metadata. Invalid proofs fail closed, logout uses `clearIdentity()`, and
normal device reset is no longer the account-switch primitive.
