Trust & Privacy
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 location check runs entirely on the phone. What leaves the phone is a signed proof whose payload is a region verdict ("inside GB") plus what is needed to verify it. Coordinates and raw readings never leave the device. LFA never receives them, so it cannot disclose them.
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:
- 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).
- The device is hardware-attested. The signing key lives in the phone's secure hardware. At enrollment the platform certifies, once, that the genuine Octet Location app created it on a genuine device: Apple App Attest on iOS, hardware key attestation on Android. LFA verifies the evidence against the platform's root certificates directly (Apple's for App Attest, Google's for Android key attestation).
- 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.
- Any failed check is a denial. Weak attestation, a stale proof, a spoof tier the policy does not accept, 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 platform attestation (App Attest on iOS, key attestation on Android) | To verify each login's hardware signature |
| Push token and device details | The phone's push token, platform, an optional display name, enrollment time, and last successful login time | To send a sign-in request to a bound phone |
| 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 |
| Usage counts | Daily sign-in counts per client, by outcome. No user ID, device, or location | To count usage for billing |
On a direct integration you choose the binding identifier, and LFA never sees a password, email, or profile unless you send one as the ID (send an opaque internal ID instead, see Prerequisites). On a broker path LFA stores the username your broker signs, which is often an email address. 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_idon the RP-authenticated/tokencall. This is the standard path. - Broker clients (such as Okta) run a fixed token
exchange and cannot add
octet_user_id, so they instead authenticate the front channel. Their/authorizerequest carries a signed request object, and thelogin_hintinside that verified object becomes the binding identifier. LFA never binds to the raw query-stringlogin_hint. See Okta integration and the OIDC reference.
Either way, what LFA stores is a user identifier, with no coordinates, credentials, or profile. On a direct integration we recommend an opaque internal ID.
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 asoctet_login_hint, not persisted. For broker clients this is different: thelogin_hintfrom the signed request object is the binding identifier and is stored, exactly asoctet_user_idis for a direct client (see What LFA stores). It is still only an identifier, with no coordinates, credentials, or profile.- Long-lived tokens. The login session lives 90 seconds (180 seconds for a broker login), the authorization code 60 seconds, the location assertion 120 seconds. There are no refresh tokens.
Where to go next
- Device lifecycle. Enrollment, replacement, and revocation of the bound device.
- How a login works. The full flow the chain above protects.