# Authentication With Okta as an SSO Provider

This guide covers how to configure [Okta](https://www.okta.com/) to provide single sign on (SSO) identities to Teleport Enterprise and Teleport Enterprise Cloud. When used in combination with role-based access control (RBAC), this allows Teleport administrators to define policies like:

- Only members of the "DBA" group can access PostgreSQL databases.
- Developers must never SSH into production servers.
- Members of the HR group can view audit logs but not production environments.

Automated SSO connection with Okta integration

In Teleport Enterprise Cloud and Self-Hosted Teleport Enterprise, Teleport can automatically configure an SSO connector as part of [enrolling Okta integration](https://goteleport.com/docs/identity-governance/integrations/okta.md).

To start Okta integration enrollment, visit the Teleport Web UI, click **Add New** in the left sidebar and click **Integration**:

![Enroll an Access Request plugin](/docs/assets/images/okta-tile-1c91005b7f21c831a7a5d6d7cdcd2ac3.png)

Then follow the instructions for the [guided Okta single sign-on integration](https://goteleport.com/docs/identity-governance/integrations/okta/guided-sso.md).

## How it works

You can register your Teleport cluster as an application with Okta, then create an **authentication connector** resource that provides Teleport with information about your application. When a user signs in to Teleport, Okta executes its own authentication flow, then sends an HTTP request to your Teleport cluster to indicate that authentication has completed.

Teleport authenticates users to your infrastructure by issuing short-lived certificates. After a user completes an SSO authentication flow, Teleport issues short-lived TLS and SSH certificates to the user. Teleport also creates a temporary user on the Auth Service backend.

Teleport roles are encoded in the user's certificates. To assign Teleport roles to the user, the Auth Service inspects the **role mapping** within the authentication connector, which associates user data on Okta with the names of one or more Teleport roles.

## Prerequisites

- An Okta account with admin access. Your account must include users and at least two groups. If you don't already have Okta groups you want to assign to Teleport roles don't worry, we'll create example groups below.

* A running Teleport Enterprise cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

* The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

- A Teleport role with access to edit and maintain `saml` resources. This is available in the default `auditor` and `editor` roles.

## Step 1/3. Configure Okta

Okta indicates a user's group membership as a SAML assertion in the data it provides to Teleport. We will configure Teleport to assign the "access" role to members of the `devs` Okta group, and the preset "auditor" and "editor" roles to members of the `admins` group.

If you already have Okta groups you want to assign to "access", "auditor" and "editor" roles in Teleport, you can skip to the [next step](#step-13-configure-okta).

### Create Groups

Create two groups: "devs" and "admins".

1. In Okta Console go to the go to **Directory** -> **Groups**, then click **Add group**.
2. Add groups "devs" and "admins" with optional description.

### Create and configure an Okta app

Okta Integration Network support is still in beta. If unsure please proceed with the Custom SAML 2.0 app.

**Okta Integration Network**

Add Teleport app to Okta:

1. In Okta Console, go to **Applications**.
2. Click **Browse App Catalog**.
3. Search for and select **Teleport**, and then click **Add Integration**.
4. Complete the fields on the settings page and click **Done**.
5. Go to the **General** tab and click **Edit** on the top-right corner of the tab.
6. Scroll down to the `groups` attribute, then select `Match regex` and type in `.*` in the input field.

![Set groups attribute](/docs/assets/images/group-regex-bff3b37cf8dc118360916d3febfe9cc5.png)

7. Scroll down and click **Save**.

**Custom SAML 2.0 app (legacy)**

---

NOTE

Please note this is a legacy way of setting up the Teleport SSO app. The preferred way is to use Okta Integration Network app.

---

1. In Okta Console, go to **Applications**.

2. Click **Create App Integration**.

3. Select "SAML 2.0" and click **Next**.

4. Give your app a name, e.g. "Teleport" and optionally upload a logo and click **Next**.

5. That will bring you to the "Configure SAML" step where you'll have to provide a several values:

   - Single sign on URL:

     ```
     https://example.teleport.sh/v1/webapi/saml/acs/okta

     ```

   - Audience URI (SP Entity ID):

     ```
     https://example.teleport.sh/v1/webapi/saml/acs/okta

     ```

   - Name ID format `EmailAddress`

   - Application username `Okta username`

   ![SAML general settings](/docs/assets/images/legacy-general-settings-fe23dfb6475dd3e797fadad601c549d8.png)

6. Click **Next**. That will bring you to the "Feedback" step where you can just click **Finish**.

7. Now you should be in your newly created SAML app configuration screen in the **Sign On** tab. Scroll down to the **Attribute statements** and click **Add expression**. Provide values like below and click **Save**.

   - Name: `groups`
   - Expression: `user.getGroups({'group.type': {'OKTA_GROUP', 'APP_GROUP', 'BUILT_IN'}}).![profile.name]`
   - Name: `username`
   - Expression: `user.profile.login`

   ![Set groups attribute](/docs/assets/images/legacy-group-expression-e022c16d1402928525199b7e764d1701.png)

Notice that we have set "NameID" to the email format and mapped the groups with an expression returning all groups. We have also set the "Audience" and SSO URLs to the same value. This is so Teleport can read and use Okta users' email addresses to create their usernames in Teleport, instead of relying on additional name fields.

### Assign user groups

1. In the same Okta Teleport app, go to the **Assignments** tab and click the **Assign** dropdown.

2. Select "Assign to Groups" and search for the "devs" and "admins" Okta groups created in the previous step.

3. Click **Assign** next to each selected group and click **Done**.

   ![Assign user groups](/docs/assets/images/assign-groups-fbf3fbc629b2b979f3e78cb3076d6b33.png)

### Save IdP metadata path

1. Go to the **Sign On** tab and scroll down to "Metadata URL".

2. Copy the Metadata URL using the **Copy** button below it.

   ![Copy metadata URL](/docs/assets/images/copy-metadata-url-d7ba5644539143e4607a2d452cd3507e.png)

3. Store the URL to the metadata file for later use.

## Step 2/3. Connect Okta to Teleport

In this section, you will create an authentication connector that provides Teleport with the information it needs to exchange SAML messages with Okta and issue certificates to users.

### Assign a role mapping

When a user authenticates to Teleport, the Teleport Auth Service issues SSH and TLS certificates to the user that contain the user's Teleport roles.

For SSO authentication connectors, the Auth Service determines which roles to encode in the certificate by reading the authentication connector's **role mapping**. The role mapping indicates which Teleport roles to assign based on data that your identity provider stores about the user.

When you configure an authentication connector using the `tctl` CLI, a role mapping takes the following format:

```
<attribute_name>,<attribute_value>,<teleport_role_1>,<teleport_role_2>,...,<teleport_role_n>

```

For example, the following role mapping means that any user with the attribute `groups` with the value `admins` receives the Teleport roles `auditor` and `editor`:

```
groups,admins,auditor,editor

```

For the purpose of this guide, assign two separate role mappings:

- A more permissive role mapping: mapping\_1
- A more restrictive role mapping: mapping\_2

### Configure a SAML connector

Define an Okta SAML connector using `tctl`. Update this example command with the path to your metadata file, and edit the `--attributes-to-roles` values for custom group assignment to roles. See [tctl sso configure saml](https://goteleport.com/docs/reference/cli/tctl.md) for a full reference of flags for this command:

```
$ tctl sso configure saml --preset=okta \
--entity-descriptor "https://example.okta.com/app/000000/sso/saml/metadata" \
--attributes-to-roles=mapping_1 \
--attributes-to-roles=mapping_2 > okta-connector.yaml
```

The contents of `okta-connector.yaml` should resemble the following:

```
kind: saml
metadata:
  name: okta
spec:
  acs: https://teleport.example.com:443/v1/webapi/saml/acs/okta
  attributes_to_roles:
  - name: groups
    roles:
    - auditor
    - editor
    value: admins
  - name: groups
    roles:
    - access
    value: dev
  audience: https://teleport.example.com:443/v1/webapi/saml/acs/okta
  cert: ""
  display: "Okta"
  entity_descriptor: ""
  entity_descriptor_url: https://example.okta.com/app/000000/sso/saml/metadata
  issuer: ""
  service_provider_issuer: https://teleport.example.com:443/v1/webapi/saml/acs/okta
  sso: ""
version: v2

```

IdP-initiated SSO

Enabling the `spec.allow_idp_initiated` flag in SAML connectors allows users to log in to Teleport with one click from the dashboard provided by the IdP.

This feature is potentially unsafe and should be used with caution.

Enabling IdP-initiated login comes with notable security risks such as:

- Possibility of replay attacks on the SAML payload giving an attacker a secret web session
- Increased risk of session hijacking and impersonation attacks based on intercepting SAML communications

### Test the connector

You can test the connector before applying it to your cluster. This is strongly encouraged to avoid interruption to active clusters:

```
$ cat okta-connector.yaml | tctl sso test
If browser window does not open automatically, open it by clicking on the link:
 http://127.0.0.1:52519/0222b1ca...
Success! Logged in as: alice@example.com
--------------------------------------------------------------------------------
Authentication details:
   roles:
   - auditor
   - editor
   - access
   traits:
     groups:
     - Everyone
     - admins
     - devs
     username:
     - alice@example.com
   username: alice@example.com
--------------------------------------------------------------------------------
[SAML] Attributes to roles:
- name: groups
  roles:
  - auditor
  - editor
  value: admins
- name: groups
  roles:
  - dev
  value: devs

--------------------------------------------------------------------------------
[SAML] Attributes statements:
groups:
- Everyone
- admins
- devs
username:
- alice@example.com

--------------------------------------------------------------------------------
For more details repeat the command with --debug flag.
```

Create the connector using `tctl`:

```
$ tctl create okta-connector.yaml
```

## Step 3/3. Configure authentication preferences

Edit your cluster authentication preferences so you can make the authentication connector you configured in this guide the default authentication method for your Teleport cluster.

Open the Teleport Web UI. From the left sidebar, navigate to **Zero Trust Access** > **Auth Connectors**. Find the connector you would like to make the default and, from its three-dot menu, select **Set as default**.

If you are managing your Teleport resources as configuration files, you can choose a default authentication connector using a dynamic resource. In this case, use `tctl` to edit the `cluster_auth_preference` value:

```
$ tctl edit cluster_auth_preference
```

Set the value of `spec.type` to `saml`:

```
kind: cluster_auth_preference
metadata:
  ...
  name: cluster-auth-preference
spec:
  ...
  type: saml
  ...
version: v2

```

After you save and exit the editor, `tctl` will update the resource:

```
cluster auth preference has been updated

```

Additional ways to edit cluster auth preferences

The cluster auth preference is available as a Teleport Terraform provider resource. Find a list of configuration options in the [Cluster Auth Preferences Resource Reference](https://goteleport.com/docs/reference/infrastructure-as-code/teleport-resources/cluster-auth-preferences.md).

If you self-host Teleport, you can edit your Teleport Auth Service configuration file to include the following:

```
# Snippet from /etc/teleport.yaml
auth_service:
  authentication:
    type: saml

```

If you need to log in again before configuring your identity provider, use the flag `--auth=local`.

## Testing

The Web UI now contains a new "Okta" button at the login screen. To authenticate via the `tsh` CLI, specify the Proxy Service address and `tsh` will automatically use the default authentication type:

```
$ tsh login --proxy=proxy.example.com
```

This command prints the SSO login URL (and will try to open it automatically in a browser).

---

TIP

Teleport can use multiple SAML connectors. In this case a connector name can be passed via the `--auth` flag. For the connector we created above:

```
$ tsh login --proxy=proxy.example.com --auth=okta
```

---

## Next steps

Now that you have connected Teleport to your identity provider, you can customize the way Teleport includes IdP data in Teleport roles.

With **role templates**, you can include user data from your IdP directly in Teleport roles. If you use the `external` template variable in the value of a role field, Teleport passes that value from your IdP. In this example, all of the role options you can use for allowing users to assume certain principals on remote systems come from your IdP:

```
kind: role
version: v7
metadata:
  name: sso-users
spec:
  allow:
    logins: ['{{external.logins}}']
    aws_role_arns: ['{{external.aws_role_arns}}']
    azure_identities: ['{{external.azure_identities}}']
    db_names: ['{{external.db_names}}']
    db_roles: ['{{external.db_roles}}']
    db_users: ['{{external.db_users}}']
    desktop_groups: ['{{external.desktop_groups}}']
    gcp_service_accounts: ['{{external.gcp_service_accounts}}']
    host_groups: ['{{external.host_groups}}']
    host_sudoers: ['{{external.host_sudoers}}']
    kubernetes_groups: ['{{external.kubernetes_groups}}']
    kubernetes_users: ['{{external.kubernetes_users}}']
    windows_desktop_logins: ['{{external.windows_desktop_logins}}']

```

For more information on using the `external` template variable, see [Role Templates](https://goteleport.com/docs/zero-trust-access/rbac-get-started/role-templates.md).

For an explanation of the fields listed above, see the [Role Reference](https://goteleport.com/docs/reference/access-controls/roles.md).

If you need to transform your IdP user data before you include it in Teleport roles, you can do so using **Login Rules**. Login Rules allow you to include external traits within Teleport roles even if your IdP provides user data in a different format than the one expected by Teleport. Read more about [Login Rules](https://goteleport.com/docs/zero-trust-access/sso/login-rules.md).

## Troubleshooting

Troubleshooting SSO configuration can be challenging. Usually a Teleport administrator must be able to:

- Be able to see what SAML/OIDC claims and values are getting exported and passed by the SSO provider to Teleport.
- Be able to see how Teleport maps the received claims to role mappings as defined in the connector.
- For self-hosted Teleport Enterprise clusters, ensure that HTTP/TLS certificates are configured properly for both the Teleport Proxy Service and the SSO provider.

If something is not working, we recommend to:

- Double-check the host names, tokens and TCP ports in a connector definition.

### Using the Web UI

If you get "access denied" or other login errors, the number one place to check is the Audit Log. To view the recording, select **Audit** in the Teleport Web UI, then click **Session Recordings** in the menu.

![Audit Log Entry for SSO Login error](/docs/assets/images/teleportauditlogssofailed-4e41f7109e748750a157651c2f702dac.png)

Example of a user being denied because the role `clusteradmin` wasn't set up:

```
{
  "code": "T1001W",
  "error": "role clusteradmin is not found",
  "event": "user.login",
  "message": "Failed to calculate user attributes.\n\trole clusteradmin is not found",
  "method": "oidc",
  "success": false,
  "time": "2024-11-07T15:41:25.584Z",
  "uid": "71e46f17-d611-48bb-bf5e-effd90016c13"
}

```

### Teleport does not show the expected Nodes

When the Teleport Auth Service receives a request to list Teleport-connected resources (e.g., to display resources in the Web UI or via `tsh ls`), it only returns the resources that the current user is authorized to view.

For each resource in the user's Teleport cluster, the Auth Service applies the following checks in order and, if one check fails, hides the resource from the user:

- None of the user's roles contain a `deny` rule that matches the resource's labels.
- At least one of the user's roles contains an `allow` rule that matches the resource's labels.

If you are not seeing resources when expected, make sure that your user's roles include the appropriate `allow` and `deny` rules as documented in the [Access Controls Reference](https://goteleport.com/docs/reference/access-controls/roles.md).

When configuring SSO, ensure that the identity provider is populating each user's traits correctly. For a user to see a Node in Teleport, the result of populating a template variable in a role's `allow.logins` must match at least one of a user's `traits.logins`.

In this example a user will have usernames `ubuntu`, `debian` and usernames from the SSO trait `logins` for Nodes that have a `env: dev` label. If the SSO trait username is `bob` then the usernames would include `ubuntu`, `debian`, and `bob`.

```
kind: role
metadata:
  name: example-role
spec:
  allow:
    logins: ['{{external.logins}}', ubuntu, debian]
    node_labels:
      'env': 'dev'
version: v5

```

### Single sign-on fails with OIDC

When encountering the error message **"Failed to verify JWT: oidc: unable to verify JWT signature: no matching keys"**, it typically indicates a discrepancy between the algorithm used to sign the JWT token and the algorithm(s) supported by the JSON Web Key Set (JWKS). Specifically, the token might be signed with one algorithm, e.g., HS256, while the JWKS only lists keys for a different algorithm. e.g., RS256. This issue predominantly arises when using identity providers that offer extremely low-level functionality.

Here are some things to check:

- Verify the JWT header specifies the correct signing algorithm. This should match one of the algorithms listed in the keys section of the JWKS endpoint response.
- Ensure the JWKS endpoint is returning all relevant public keys. Sometimes key rotation can cause valid keys to be omitted.

To resolve the issue, align the JWT algorithm header with a supported algorithm in the JWKS. Rotate keys if necessary. Verify the JWKS only publishes the active public keys. With proper configuration, the signature should validate successfully.
