---
title: "Single sign-on"
description: "Signing in through your organization's own identity provider (Okta, Microsoft Entra ID, Google Workspace, Auth0, Keycloak) by OpenID Connect: setting it up, proving your email domain, people joining as they first sign in, and requiring it."
url: "https://runalf.com/docs/sso"
section: "Organization"
---

# Single sign-on

Your organization's people can sign in through its own identity provider instead of a password: Okta, Microsoft Entra ID, Google Workspace, Auth0, Keycloak, or any other that speaks OpenID Connect. Admins set it up under **Settings → Single sign-on**.

## Setting it up

1. At your provider, register an app: a web application using OpenID Connect, with the redirect (sign-in) address the settings page shows, `https://api.runalf.com/api/v1/auth/sso/callback`. It needs the scopes `openid`, `email` and `profile`.
2. Under **Settings → Single sign-on**, give its **issuer** and the app's **client ID** and **client secret**. The issuer is the address whose `/.well-known/openid-configuration` describes your provider:

   | Provider | Issuer |
   | --- | --- |
   | Okta | `https://<your-org>.okta.com` (or your authorization server's) |
   | Microsoft Entra ID | `https://login.microsoftonline.com/<tenant-id>/v2.0` |
   | Google Workspace | `https://accounts.google.com` |
   | Auth0 | `https://<tenant>.auth0.com/` |
   | Keycloak | `https://<host>/realms/<realm>` |

   Alf reads it when you connect, so a wrong address is said at once.
3. Add your **email domain**, like `acme.com`, and create the TXT record it shows at your DNS provider: `_alf-sso.acme.com` with a value starting `alf-sso=`. Then **Check now**. An identity provider can say any address, so Alf only believes it for addresses on domains you've proved.

## Signing in

On the sign-in page, **Sign in with single sign-on (SSO)**, then the work address: its domain finds your provider, and signing in there brings you back to the dashboard. Someone whose account has two-factor authentication on is still asked for its code. The command-line tool signs in through the browser, so `alf login` works the same way.

Someone signing in this way for the first time gets an account with the address their provider confirmed, and joins the organization with the role you chose (a member, unless you choose viewer or deployer). Choose **Only those already in it** to keep joining to invitations: then someone not in the organization yet is turned away until an admin adds them. An account that already has the address (made with a password, GitHub or Google) is linked, and keeps its other ways in.

## Requiring it

**Require single sign-on** asks your people on your proved domains to have signed in through the provider within the last day: otherwise the dashboard asks them to (one click, as the provider usually remembers them), and the API, the command-line tool and agents answer `403 sso_required` for everything of the organization's. That way someone switched off at your provider is out of Alf within a day, too.

- **Owners are let in anyway**, so a broken or misconfigured provider never locks the organization out.
- People on other domains (a contractor with their own address) aren't asked: invite them as usual.
- Agent tokens aren't sign-ins, so it doesn't apply to them: remove the tokens of someone who leaves (**Agents**), or use the organization's own tokens for CI.
- Signing in through the provider within the last day also counts for an organization that [requires two-factor authentication](https://runalf.com/docs/security#your-account): the provider asks for its own second factor.

Disconnecting single sign-on leaves everyone's accounts and memberships as they are: they sign in with a password, GitHub or Google again (someone who only ever used single sign-on chooses a password with "Forgot your password?").

## From the API

`GET`, `PUT` and `DELETE /organizations/{id}/sso`, and `POST /organizations/{id}/sso/domains` with `…/verify`: see the [API reference](https://runalf.com/docs/api).
