a73x

docs/byo-idp.md

Ref:   Size: 1.7 KiB   History

# Bring your own IdP

The console signs in through OIDC. The [self-hosting](self-hosting.md) page uses the
bundled `eitri-oidc` issuer, but any OIDC provider works—Google, Authentik,
Okta, Keycloak. Point the server at yours and you never install `eitri-oidc`;
the tarball isn't even on the box.

## Register a client

At your IdP, register a **confidential** web client with:

- **Redirect URL:** `<public_url>/auth/callback`—`public_url` is where
  browsers reach your console (e.g. `https://eitri.example.com/auth/callback`).
- **Scopes:** `openid email`. The server requires an `email` claim **and
  `email_verified: true`**; sign-in fails against an issuer that omits either —
  an unverified address cannot mint an identity.

Note the client ID and secret it gives you.

## Fill the `oidc` block

In `server.json`:

```json
"oidc": {
  "issuer": "https://id.example.com",
  "client_id": "eitri-console",
  "client_secret": "...",
  "public_url": "https://eitri.example.com",
  "allowed_domains": ["example.com"],
  "allowed_identities": ["alex@example.com"]
}
```

- `issuer` is the IdP's base URL; the server discovers its endpoints from
  `<issuer>/.well-known/openid-configuration`.
- `client_secret` is required for an external confidential client (the bundled
  issuer omits it—it's a public PKCE client).
- `public_url` builds the redirect and must match what you registered.

## The signup gate

`allowed_domains` and `allowed_identities` are the signup gate. If either is
set, an identity matching neither is rejected at callback—no tenant created.
Leave both unset for open signup (anyone your IdP authenticates gets a tenant).

Each new identity's first sign-in creates its own tenant.