# Prerequisites

Four things you need before your first LFA login:

1. **LFA client credentials**, registered by Octet.
2. **An OIDC-capable application**, with one extra field on the token request.
3. **A stable user identifier** to send at token-exchange time.
4. **A phone with the Octet Location app**, physically in the policy region.

---

## Where LFA lives

One issuer serves every customer. Most OIDC libraries need only the issuer and
discover the rest. Brokers such as Okta do not read discovery, so the full list
is here to copy.

| | |
|---|---|
| Issuer | `https://factor.octetproof.com` |
| Discovery | `https://factor.octetproof.com/.well-known/openid-configuration` |
| Authorization | `https://factor.octetproof.com/authorize` |
| Token | `https://factor.octetproof.com/token` |
| JWKS | `https://factor.octetproof.com/.well-known/jwks.json` |
| UserInfo | `https://factor.octetproof.com/userinfo` |
| Device revoke | `https://factor.octetproof.com/v1/device/revoke` |

No trailing slashes, and the issuer has no path. Confirm any of it live:

```bash
curl -s https://factor.octetproof.com/.well-known/openid-configuration | jq
```

---

## 1. Client credentials

Clients are registered by the Octet team. There is no self-serve portal yet.
Email [hello@octetproof.com](mailto:hello@octetproof.com) with:

- your **redirect URIs**, matched exactly, HTTPS in production
- the **region policy or policies** you need (see [Policies](/docs/concepts/policies/)),
  for example "UK presence"

For a **direct integration** you receive a `client_id` and a `client_secret`.
For a **broker integration** (Okta, Entra ID, Auth0) you receive a `client_id`
only. The broker authenticates with a signed assertion rather than a shared
secret, so there is no secret to hold or rotate. Redirect URIs can be updated
the same way.

## 2. An OIDC-capable stack

LFA is a standard OIDC identity provider: authorization-code flow with PKCE.
Any stack that can federate to an external OIDC IdP can drive the login.

One requirement goes beyond standard OIDC on the **direct-integration path**:
your **token exchange must include an extra form field**, `octet_user_id`
(next section). If your OIDC library cannot add a parameter to the token
request, perform the exchange yourself. It is a single POST, shown in the
[Quick Start](/docs/getting-started/quickstart/).

:::note

Identity brokers (Okta, Entra ID, Auth0) run a fixed standard token exchange
and cannot attach `octet_user_id`. They are supported by a different mechanism:
the broker sends a **signed authorization request**
([RFC 9101](https://www.rfc-editor.org/rfc/rfc9101)) whose `login_hint` LFA
binds on, so a broker never sends `octet_user_id` at all. If you integrate
through a broker, follow [Okta](/docs/integration/okta/) instead of this page's
direct-integration steps. The [OIDC reference](/docs/reference/oidc/) has the
parameter details.

:::

## 3. A user identifier for binding

You need your own identifier for the user who is signing in. LFA uses it to
[bind the user's enrolled phone to their account](/docs/concepts/device-lifecycle/).
That binding is what makes the factor "this user's phone in this region" rather
than "any phone in this region".

How you supply it depends on your integration path. For a **direct integration**
you send it as `octet_user_id` on every token exchange. For a **broker** the
same role is played by the `login_hint` inside the signed authorization request.
LFA binds on the hint from the verified request object, so you never send
`octet_user_id`.

Whichever path you use, choose an identifier that is:

- **stable**. It should never change for the lifetime of the account
  (a database ID, not an email address).
- **opaque**. LFA stores it, so prefer an internal ID over anything personally
  identifying (see [Trust & Privacy](/docs/concepts/trust-and-privacy/)).
- **unique** per user within your client.

## 4. The phone

- An iPhone or Android phone with the **Octet Location app** installed.
  Both platforms reach the same assurance level. See the
  [FAQ](/docs/lfa/troubleshooting/faq/) for how that is achieved on each.
- Location permission granted to the app.
- The user physically inside the policy's region at login time.

There is no enrollment step for you to administer: a user's first successful
login attests and binds their phone automatically. Replacements and revocations
are covered in [Device lifecycle](/docs/concepts/device-lifecycle/).
