> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genesiscomputing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Additional Sign-In Options

> Let a second group of people, such as Genesis staff or contractors, sign in through an identity provider you run, next to your organization's own

Genesis normally signs everyone in through one identity provider (IdP): your organization's, such as Microsoft Entra ID or Okta. You can add more. Each additional IdP becomes another button on the Genesis sign-in screen.

A common reason: Genesis staff or contractors need to work in your Genesis instance, but adding them to your corporate directory, even as guests, is not an option. Instead, you set up a small separate IdP that you control, invite only those people to it, and tell Genesis to trust it. Your corporate IdP is not touched.

Each person who signs in through any IdP gets their own Genesis user, so roles, permissions and audit history work exactly as they do for your own users.

<Note>
  This applies to deployments that use native OIDC or Auth0 sign-in (`authProvider: oidc` or `auth0`). It covers sign-in to the Genesis web app. The `genesis login` command line and MCP clients keep using your primary IdP.
</Note>

## What your users see

With no additional IdP configured, Genesis sends people straight to your organization's sign-in page, as it does today.

With one or more configured, people first see a **Sign in to Genesis** screen:

* **Sign in with your organization's account**: your primary IdP.
* One button per additional IdP, with a label you choose, for example **Genesis staff**.

Genesis remembers which button a person used, so their session renews against that same IdP and **Sign out** signs them out of it. After signing out, the screen asks again.

## Before you start

You need:

* An IdP you control that speaks OpenID Connect (OIDC). Auth0, Okta, Keycloak, Amazon Cognito, Ping and most other OIDC providers work. A free developer tenant is usually enough for a handful of people.
* The address people use to reach Genesis, for example `https://genesis.example.com`. Below it is called **your Genesis address**.
* Access to the Genesis configuration file of your deployment (with Helm, the file you pass as `genesisConfig.content`), and permission to upgrade the deployment.

<Warning>
  Plain Google OAuth ("Sign in with Google" as a bare OAuth client) does not work as an additional IdP, because it requires a client secret that a browser app cannot keep. Use an IdP that supports public clients with PKCE. Most of them, including Auth0 and Okta, can still offer Google as a login method inside them.
</Warning>

## Step 1: Set up the identity provider

<Steps>
  <Step title="Create an application for Genesis">
    In your IdP, create an application of type **Single Page Application** (in Okta: *OIDC - Single-Page Application*). It must use the authorization code flow with PKCE and **no client secret**.

    Set:

    | Setting | Value |
    | - | - |
    | Allowed callback / sign-in redirect URL | your Genesis address, e.g. `https://genesis.example.com` |
    | Allowed logout / sign-out redirect URL | your Genesis address |
    | Allowed web origins / CORS origins | your Genesis address |
    | Grant types | Authorization Code; Refresh Token (recommended) |

    Use the address exactly as people type it: scheme and host, no path, no trailing slash.

    Create one application per Genesis instance. Genesis accepts only tokens issued to the application you name in Step 2, so a separate application per instance keeps access to each instance separate.
  </Step>

  <Step title="Decide who can sign in">
    Anyone who can sign in to this application gets a Genesis user on your instance. So:

    * Turn **self sign-up off**.
    * Turn off any login method you do not intend to offer, such as social logins that let anyone in.
    * Invite or create only the people who should have access, and assign them to the application.
    * Require multi-factor authentication if your policy calls for it.

    When someone should lose access, remove or block them here. They can no longer sign in to Genesis.
  </Step>

  <Step title="Collect three values">
    You need these for Step 2:

    | Value | Where to find it | Example |
    | - | - | - |
    | **Issuer** | the `issuer` field of `<your IdP>/.well-known/openid-configuration` | `https://example-staff.us.auth0.com/` |
    | **JWKS URL** | the `jwks_uri` field of the same document | `https://example-staff.us.auth0.com/.well-known/jwks.json` |
    | **Client ID** | the application you created | `Hk3Zp...` |

    Copy the issuer exactly, including any trailing slash. Genesis compares it with the issuer inside every token.
  </Step>
</Steps>

<Accordion title="Example: Auth0">
  1. **Applications → Applications → Create Application**, choose **Single Page Web Applications**.
  2. On **Settings**, put your Genesis address in **Allowed Callback URLs**, **Allowed Logout URLs** and **Allowed Web Origins**, then save. Note the **Client ID**.
  3. **Settings → Advanced Settings → Grant Types**: keep **Authorization Code** and **Refresh Token** checked.
  4. **Authentication → Database**: open the connection you use, turn on **Disable Sign Ups**, and on its **Applications** tab enable only the applications that should use it. Turn off social connections you do not want for this application on the application's **Connections** tab.
  5. **User Management → Users**: create or invite the people who should have access.
  6. Issuer: `https://<your-tenant>.<region>.auth0.com/` (with the trailing slash). JWKS URL: `https://<your-tenant>.<region>.auth0.com/.well-known/jwks.json`.
</Accordion>

<Accordion title="Example: Okta">
  1. **Applications → Create App Integration**, choose **OIDC - OpenID Connect**, then **Single-Page Application**.
  2. **Grant type**: Authorization Code and Refresh Token. **Sign-in redirect URIs** and **Sign-out redirect URIs**: your Genesis address.
  3. **Assignments**: assign only the people or group that should have access. Note the **Client ID**.
  4. **Security → API → Trusted Origins**: add your Genesis address with **CORS** checked.
  5. Issuer: `https://<your-org>.okta.com` (the org authorization server, no trailing slash). JWKS URL: `https://<your-org>.okta.com/oauth2/v1/keys`.
</Accordion>

## Step 2: Add the IdP to Genesis

Add an `auth.additional_issuers` entry to your Genesis configuration file. With Helm, this is the file you pass as `genesisConfig.content`:

```yaml theme={null}
auth:
  additional_issuers:
    genesis-staff:
      issuer: "https://example-staff.us.auth0.com/"
      jwks_url: "https://example-staff.us.auth0.com/.well-known/jwks.json"
      login_client_id: "Hk3Zp..."
      login_label: "Genesis staff"
```

If your file already has an `auth:` section, add `additional_issuers` inside it instead of creating a second `auth:` key.

Then apply it the way you normally upgrade, for example:

```bash theme={null}
helm upgrade <release> oci://ghcr.io/genesis-computing-ai/charts/genesis \
  --namespace <namespace> \
  --reuse-values \
  --set-file genesisConfig.content=genesis-config.yaml
```

To offer more than one additional IdP, add one entry per IdP under `additional_issuers`. Each becomes its own button.

### Field reference

| Field | Required | Meaning |
| - | - | - |
| *entry name* (`genesis-staff` above) | yes | Any name. Used as the button text when `login_label` is not set. |
| `issuer` | yes | The IdP's issuer, exactly as it appears in its tokens. |
| `jwks_url` | yes | Where Genesis fetches the IdP's signing keys. An entry without it is not offered as a button. |
| `login_client_id` | yes, for a button | Client ID of the application from Step 1. An entry without it is trusted for API tokens but is not offered as a sign-in button. |
| `login_label` | no | Button text, for example `Genesis staff` or `Contractors`. |
| `login_scope` | no | OIDC scopes to request. Defaults to `openid profile email offline_access`; your primary IdP's scopes are never reused here. |
| `audience` | no | An extra `aud` value to accept, for API tokens issued by this IdP to something other than the browser app. ID tokens from the browser app (`aud` = `login_client_id`) are always accepted. Leave it unset unless you need it. |

## Step 3: Allow the network paths

* The **Genesis server** needs outbound HTTPS to the IdP's `jwks_url` to check signatures.
* **People's browsers** must be able to reach the IdP's sign-in pages. If you use a managed or enterprise browser, or a web proxy with an allowlist, add the IdP's domain.

## Step 4: Check it works

1. Open your Genesis address in a private browser window. You should see **Sign in to Genesis** with both buttons.
2. Choose the additional IdP's button, sign in, and confirm Genesis opens.
3. Sign out. The choice screen should appear again.
4. Sign in with **Sign in with your organization's account** to confirm your own users are unaffected.

People who sign in through the additional IdP get your default role. A Genesis administrator can change their roles under [Users and Roles](/docs/Setup/Users-And-Roles).

## Good to know

* **Roles from groups.** Group-to-role mapping reads the `groups` and `roles` claims of each token. An additional IdP usually sends neither, so its users start with the default role.
* **SCIM-only admission.** If your instance only admits users provisioned through [SCIM](/docs/Setup/SCIM-Inbound-Provisioning), people signing in through an additional IdP are refused unless they are provisioned too.
* **Same email, different users.** Users are matched by the IdP's subject identifier, not by email. A person who signs in through both IdPs ends up with two Genesis users.
* **Removing an IdP.** Delete its entry and upgrade. Its button disappears and its tokens stop being accepted. Users it created stay in Genesis until an administrator removes them.

## Troubleshooting

| Symptom | Likely cause |
| - | - |
| No choice screen; Genesis goes straight to your organization's sign-in | The entry has no `login_client_id`, the configuration was not applied, or the deployment does not use `oidc`/`auth0` sign-in. Check that `<your Genesis address>/api/config/frontend` lists your entry under `additional_logins`. |
| The IdP shows a "callback URL mismatch" or "redirect\_uri" error | The application's allowed callback URL does not exactly match your Genesis address. |
| Sign-in at the IdP succeeds, then Genesis shows a sign-in error or a blank screen | The IdP does not allow your Genesis address as a web or CORS origin, so the browser cannot complete the token exchange. |
| API calls fail with `Invalid token: Unknown token issuer` | `issuer` does not match the token's issuer. Copy it from the IdP's discovery document, including any trailing slash. |
| API calls fail with `Invalid token: the audience claim does not match this deployment` | `login_client_id` is not the client ID of the application people sign in to. |
| API calls fail with `Invalid token: the signature does not verify against the issuer's keys` | `jwks_url` points at a different IdP or tenant than `issuer`. |
| Sign-out leaves people signed in at the IdP | The IdP does not publish a sign-out endpoint. Genesis still ends its own session; people may be signed straight back in until the IdP session expires. |
