Docs/Concepts/Trust & Privacy

Trust & Privacy

In one sentence

The phone proves which region it is in without revealing where in that region it is, and LFA stores the minimum needed to keep the factor bound to the right device and user.

What never leaves the phone

The Octet Location app runs the location check entirely on-device: sensor reads, motion analysis, and the anti-spoof pipeline all happen locally. What leaves the phone is a signed proof whose payload is a region verdict ("inside GB") plus the cryptographic material to verify it. Raw coordinates, paths, speeds, and sensor detail never leave the device, so LFA cannot leak, sell, or disclose what it never receives.

Why a verdict can be trusted

The verdict carries no coordinates, so it is only as trustworthy as the chain that produces it. LFA verifies that chain fail-closed on every login:

  1. The proof is signed on-device, produced by the Octet SDK's location and anti-spoof pipeline (the same proof-of-location machinery as the Octet Mobile SDK).
  2. The device is hardware-attested. The signing key lives in the phone's secure hardware. Apple App Attest certifies, once, at enrollment, that a genuine, unmodified app on a genuine device created it. LFA verifies the evidence against the platform's root certificates directly (Apple's for App Attest, Google's for Android key attestation), with no runtime calls to either vendor.
  3. Every login is freshly signed, and the freshness is committed inside the proof. The phone commits this session's one-time challenge inside the signed proof, identically on both platforms. Freshness therefore travels with the proof rather than alongside it: a captured proof cannot be replayed into another login even if it is stored, forwarded, or verified later and out of band.
  4. Any failed check is a denial. Weak attestation, a stale proof, a spoof verdict below the policy floor, an unknown or revoked device: LFA denies rather than scoring the result.

What LFA stores

Stored What it is Why
Device key + attestation record The device's public key and its App Attest certification. The device ID is a hash of the key To verify each login's hardware signature
Device-to-user binding The per-client user identifier you supply (octet_user_id for a direct client, or the login_hint from the signed request object for a broker client) To pin the factor to the user's own phone
Revocation flag Whether a device has been revoked To deny lost or replaced phones

Notes on the binding: the identifier is yours. LFA never sees a password, email, or profile unless you choose to send one as the ID (send an opaque internal ID instead, see Prerequisites). Bindings are scoped per client, so identifiers are never visible across clients and LFA builds no cross-application identity graph.

The binding identifier reaches LFA one of two ways:

  • Direct clients send octet_user_id on the RP-authenticated /token call. This is the standard path and is unchanged.
  • Broker clients (Okta, Microsoft Entra ID, Auth0) run a fixed token exchange and cannot add octet_user_id, so they instead authenticate the front channel. Their /authorize request carries a signed request object, and the login_hint inside that verified object becomes the binding identifier. LFA never binds to the raw query-string login_hint. See Okta integration and the OIDC reference.
Note

Either way, what LFA stores is an opaque user identifier that the customer chose, not coordinates, credentials, or a profile.

What LFA does not store

  • Coordinates or location history. Never received in the first place.
  • User profiles or credentials. Identity stays with your IdP.
  • login_hint (direct clients). Passed through into the id_token as octet_login_hint, not persisted. For broker clients this is different: the login_hint from the signed request object is the binding identifier and is stored, exactly as octet_user_id is for a direct client (see What LFA stores). It is still an identifier you chose, with no coordinates, credentials, or profile.
  • Long-lived tokens. The login session lives 90 seconds, the authorization code 60 seconds, the location assertion 120 seconds. There are no refresh tokens.

Where to go next