# Direct OIDC Integration

LFA is a standard OIDC identity provider. Any stack that can federate to an
external OIDC IdP, or perform an authorization-code flow, can consume LFA. You
redirect to LFA, the user proves presence on their phone, and you get back an
id_token whose claims carry the location verdict.

The [Quick Start](/docs/lfa/getting-started/quickstart/) walks the wire protocol end to
end. This page covers the integration decisions around it.

---

## The one non-standard requirement

This is the **direct** path, where your app drives the OIDC flow itself. On this
path your **token exchange must include `octet_user_id`**, your stable, opaque
identifier for the user signing in. It drives
[device-to-user binding](/docs/lfa/concepts/device-lifecycle/), and an exchange without it
is rejected (`invalid_request`).

:::note
If you federate through an identity **broker** such as Okta, the broker runs a fixed token exchange and cannot add `octet_user_id`.
That path is supported: the broker authenticates the front channel with a
signed `/authorize` request instead, and the device binds to the verified
`login_hint`. See [Okta](/docs/lfa/integration/okta/). The rest of this page assumes the
direct path.
:::

This requirement determines how you use your OIDC library. Any OIDC library can
handle the `/authorize` redirect. For the token exchange, either:

- your library lets you add a custom form field to the token request, so use it,
  or
- perform the exchange yourself. It is one POST (see the
  [Quick Start](/docs/lfa/getting-started/quickstart/#3-exchange-the-code-with-octet_user_id)),
  and you can hand the resulting tokens back to your session layer.

Your callback handler already has the identifier of the user who is mid-login,
because you initiated the redirect from their session or your primary IdP's.

## Selecting a policy per login

Pass `octet_policy_id` on `/authorize` to choose which registered
[policy](/docs/lfa/concepts/policies/) this login must satisfy. One client can use many
policies:

```bash
&octet_policy_id=country_uk
```

Omit it to use your client's pinned default. An unknown id is rejected rather
than falling back, so a typo cannot silently weaken the check.

## `login_hint`

If you pass `login_hint` on `/authorize`, LFA echoes it back in the id_token as
the namespaced, **unverified** `octet_login_hint` claim. It is useful for
correlating the response with the login you started. On the direct path it is
pure passthrough: LFA does not verify or persist it, does not bind to it
(`octet_user_id` on `/token` is the binding identifier), and never reflects it
into identity claims such as `email`.

## Protocol constraints

A misconfigured request fails immediately rather than falling back to weaker
behaviour:

- PKCE **S256 is required**. `state` and `nonce` are **both mandatory**.
- Scopes are `openid octet.location`. Extra scopes a library adds
  (`profile email`) are ignored, and no profile claims come back.
- There are no refresh tokens. Run a new login when you need fresh proof of
  presence.
- Authorization codes are single-use with a **60-second** redemption window.

The full tables (endpoints, parameters, claims, errors) live in the
[OIDC Reference](/docs/lfa/reference/oidc/).

## Gating on the result

There are two ways to use the result:

- **Simple gate.** Require `acr == "urn:octet:loc:strong"` in the id_token. That
  single check means hardware-attested presence with the policy passed.
- **Audit or downstream verification.** Keep the `octet_location_assertion`
  claim, also mirrored as top-level `location_assertion` in the token response.
  It is a signed, 120-second statement of the region verdict, verifiable against
  the same JWKS.

## Client registration

Clients are registered by the Octet team. Email
[hello@octetproof.com](mailto:hello@octetproof.com) with your redirect URIs and
the policies you need. See [Prerequisites](/docs/lfa/getting-started/prerequisites/).

## Where to go next

- [Device lifecycle](/docs/lfa/concepts/device-lifecycle/). Binding, new phones, and
  revocation: the operational side of `octet_user_id`.
- [OIDC Reference](/docs/lfa/reference/oidc/). Every endpoint, parameter, claim, and error.
