# Add sign-in with another identity provider

Let people sign in to your project with Google, Microsoft, Okta, GitHub, GitLab, or any OpenID Connect or SAML 2.0 identity provider.

A _connection_ lets people sign in to your project with an account they already have at another identity provider. Your applications do not change: they still talk to your project, and receive the same tokens.

Use this guide to connect a provider that speaks OpenID Connect or OAuth 2.0, such as Google or GitHub, or one that speaks SAML 2.0.

## Before you begin

You need:

- An AuthFI project and its issuer, the project's URL. This guide uses `https://acme.authfi.io`.
- Permission to add connections and applications in the AuthFI console.
- Administrator access to the identity provider, to register your project with it.
- The values in this table, from the provider.

| Provider                    | Protocol       | You need from the provider                                            |
| --------------------------- | -------------- | --------------------------------------------------------------------- |
| Google                      | OpenID Connect | Client ID and client secret                                           |
| Google Workspace            | OpenID Connect | Client ID and client secret, and your email domains                   |
| Microsoft Entra ID          | OpenID Connect | Directory ID, client ID and client secret, and your email domains     |
| Okta                        | OpenID Connect | Your Okta domain, client ID and client secret, and your email domains |
| GitHub, GitLab              | OAuth 2.0      | Client ID and client secret                                           |
| Any OpenID Connect provider | OpenID Connect | Issuer, client ID and client secret                                   |
| Any SAML 2.0 provider       | SAML           | Entity ID, sign-on URL and signing certificate                        |

For Microsoft, use the Microsoft Entra ID connection, with your directory ID. For GitHub, each person's GitHub account needs a public email, because every account in AuthFI has an email.

## Connect an OpenID Connect or social provider

Follow this procedure for Google, Google Workspace, Microsoft Entra ID, Okta, GitHub, GitLab, or any OpenID Connect provider.

<Steps>

### Create the connection

1. In the console, open **Integrations > Connections** and choose **Connect something**.
2. Choose the provider. A dialog titled **Federate**, followed by the provider's name, opens.
3. Fill in the fields, then choose **Federate**.

| Field             | Enter                                                                                         |
| ----------------- | --------------------------------------------------------------------------------------------- |
| **Name**          | A name for the connection, for example `Okta`                                                 |
| **Protocol**      | **OIDC** for an OpenID Connect provider, or **Social**                                        |
| **Issuer**        | The provider's issuer, an `https` URL such as `https://acme.okta.com`. Shown for **OIDC**.    |
| **Client ID**     | The client ID from the provider                                                               |
| **Client secret** | The client secret from the provider                                                           |
| **Email domains** | Optional. The email domains to send through this provider, for example `acme.com, acme.co.uk` |

**Email domains** decides which people are sent to this connection. Leave it empty to offer the connection to the whole project.

The console confirms that the connection is federated and that people can sign in through it. The connection appears as a card on the **Connections** tab, with a reference you can copy.

Some providers open a guided flow instead of the dialog, with the steps **Choose**, **Settings**, **Review** and **Done**. Enter a **Name** and the provider's values, choose **Review**, then **Connect**. The **Done** step shows the values to register with the provider, each with a copy control.

### Register the redirect URI with the provider

The provider sends each person back to your project after they sign in. In the provider's own settings, register this URL as the allowed redirect URI:

```text
https://acme.authfi.io/v1/auth/{connection_id}/callback
```

Replace `{connection_id}` with the connection's ID.

</Steps>

## Connect a SAML provider

With a SAML connection, your project is the _service provider_ (SP) and the other side is the _identity provider_ (IdP) that signs people in. In the console, a SAML identity provider is registered on **Integrations > Applications**, not on **Connections**.

<Steps>

### Register the identity provider

1. In the console, open **Integrations > Applications** and select the **Identity arrives** tab.
2. Choose **Register an identity provider**. You can also choose **Register**, select **SAML**, and then select **They sign us in**.
3. Fill in the fields with the provider's values.

| Field                         | Enter                                                                     |
| ----------------------------- | ------------------------------------------------------------------------- |
| **Handle**                    | A short name for the connection. It appears in its URLs as `{name}`.      |
| **Display name**              | A name for the provider                                                   |
| **Their entity ID**           | The provider's entity ID                                                  |
| **Their SSO URL**             | The provider's sign-on URL                                                |
| **Their signing certificate** | The provider's certificate in PEM, including the `BEGIN CERTIFICATE` line |
| **Email domains**             | The email domains of the people who sign in through this provider         |

### Configure the identity provider

After you register, the console shows the values to paste into the provider's side. In the provider's settings, add your project as a SAML application with them.

| Shown in the console | Value                                                          |
| -------------------- | -------------------------------------------------------------- |
| **Metadata URL**     | `https://acme.authfi.io/saml/sp/{name}/metadata`               |
| **ACS URL**          | `https://acme.authfi.io/saml/sp/{name}/acs`                    |
| **SP entity ID**     | `https://acme.authfi.io/saml/metadata`, unless you set another |

The _ACS URL_, or assertion consumer service URL, is where the provider posts its signed answer, the _assertion_.

To see these values again, open the provider's row on the **Identity arrives** tab. They are under **Paste into their identity provider**.

</Steps>

## Check that it works

Open the connection's sign-in URL in a browser.

For an OpenID Connect or social connection:

```text
https://acme.authfi.io/v1/auth/{connection_id}/login?return_to=/
```

The browser goes to the provider and returns to your project, signed in. `return_to` is a path on your project's issuer. Any other URL is ignored.

For a SAML connection:

```text
https://acme.authfi.io/saml/sp/{name}/login
```

This starts the sign-in from your project. A sign-in started from the provider's side is accepted too.

## Send people to the right provider

When a connection lists email domains, your project's own sign-in page sends each person to the connection that matches their email.

To do the same from your own page, ask which connection an email address belongs to, then send the browser to the path in the response.

<Endpoint method="GET" path="/v1/auth/resolve?email=ada@acme.com" />

```json
{ "login_path": "/v1/auth/7b1e.../login" }
```

A `404` means no connection claims that email domain. The person then signs in with their AuthFI password or passkey.

For SAML connections, the equivalent request is `GET /saml/sp/resolve?email=`.

## What AuthFI reads from the provider

AuthFI needs an email for every person.

### From an OpenID Connect or social provider

| From the provider | Becomes                           |
| ----------------- | --------------------------------- |
| `sub`             | The link between the two accounts |
| `email`           | The person's email                |
| `name`            | The person's name                 |

This mapping is fixed. Assign groups and roles in AuthFI: they are not read from the provider.

### From a SAML provider

AuthFI looks for the person's email in this order:

1. A NameID in email format
2. An attribute named `email` or `mail`
3. The attribute `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`
4. The attribute `urn:oid:0.9.2342.19200300.100.1.3`

If your provider uses another name, map it. A mapping takes one of the provider's attributes to `email`, `display_name` or `picture_url`. In the console, open the provider's row on the **Identity arrives** tab of **Integrations > Applications**. The mapping is under **What their identity provider sends**, in the fields **Email**, **Display name** and **Picture**.

## What AuthFI checks

AuthFI validates every answer from the provider before it signs the person in.

For an OpenID Connect or social provider:

- The ID token's signature (`RS256`), issuer, audience, expiry and `nonce` are valid.
- The provider does not report `email_verified` as `false`.
- If the connection lists email domains, the person's email is in one of them. For Google Workspace, the token's `hd` claim matches too.

For a SAML provider:

- The assertion's signature verifies against the certificate you entered.
- An answer to a request that AuthFI sent matches that request, and arrives within 10 minutes.
- The assertion has not been used before.
- The assertion carries an email.

## How accounts are linked

When a person signs in through a connection, AuthFI finds or creates their account in this order:

1. If the provider's account was linked before, the person is signed in to the same AuthFI account.
2. Otherwise, if an account with that verified email exists, the two are linked.
3. Otherwise, AuthFI creates a new, active account, with the email marked verified.

Tokens issued from the session carry `fed` in the `amr` claim. Your project's rule for multi-factor authentication (MFA) still applies after the provider has signed the person in.

## Troubleshooting

| What you see                          | Cause                                                                                                     | Fix                                                                                                         |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| An OpenID Connect sign-in is rejected | The provider reports `email_verified` as `false`                                                          | Verify the person's email at the provider                                                                   |
| An OpenID Connect sign-in is rejected | The person's email is outside the connection's email domains, or for Google Workspace `hd` does not match | Sign in with an account in one of the connection's email domains                                            |
| A SAML sign-in is rejected            | The assertion carries no email                                                                            | Send a NameID in email format, or map the provider's attribute under **What their identity provider sends** |
| A SAML sign-in is rejected            | The assertion was already used, or the answer arrived more than 10 minutes after the request              | Start the sign-in again                                                                                     |
| `404` from `/v1/auth/resolve`         | No connection claims that email domain                                                                    | Let the person sign in with their AuthFI password or passkey                                                |

## Next steps

<Cards>
  <Card href="/connections/scim" title="Provision people with SCIM">
    Create and suspend accounts from your identity provider.
  </Card>
  <Card href="/applications/sessions" title="Manage sessions, sign-out and MFA">
    Read how a person signed in, and require MFA from your application.
  </Card>
  <Card href="/concepts/access" title="Roles, groups and grants">
    Assign groups and roles to the people who sign in through a connection.
  </Card>
  <Card href="/security/keys" title="Keys and secrets">
    How AuthFI stores a connection's client secret.
  </Card>
</Cards>
