Authentication With Okta as an SSO Provider
This guide covers how to configure Okta 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 for you when as part of enrolling the hosted Okta integration.
You can enroll the Okta integration from the Teleport Web UI.
Visit the Teleport Web UI and find the dropdown menu on the upper left of the screen. Select the Management option.
On the left sidebar, click Enroll New Integration to visit the "Enroll New Integration" page:
On the "Select Integration Type" menu, click the Okta tile. Teleport will then guide you through configuring the Okta integration.
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 cluster. If you want to get started with Teleport, sign up for a free trial.
-
The
tctl
admin tool andtsh
client tool.Visit Installation for instructions on downloading
tctl
andtsh
.
- A Teleport role with access to edit and maintain
saml
resources. This is available in the defaulteditor
role.
- Teleport Enterprise (Self-Hosted)
- Teleport Cloud
- The
tctl
andtsh
client tools version >= 17.0.0-dev. Read Installation for how to install these.
- The
tctl
andtsh
client tools version >= 17.0.0-dev. Read Installation for how to install these.
Step 1/4. Create & assign groups
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 "dev" role to
members of the okta-dev
Okta group, and the prest "editor" role to members of
the okta-admin
group.
If you already have Okta groups you want to assign to "dev" and "editor" roles in Teleport, you can skip to the next step.
Create Groups
Create two groups: "okta-dev" and "okta-admin". In the Okta dashboard go to the navigation bar and click Directory -> Groups, then Add group:
Repeat for the admin group:
Step 2/4. Configure Okta
In this section we will create an application in the Okta dashboard to allow our Teleport cluster to access Okta as an IdP provider. We'll also locate the address that Okta uses to provides their IdP metadata to Teleport.
First, create a SAML 2.0 Web App in Okta:
From the main navigation menu, select Applications -> Applications, and click Create App Integration. Select SAML 2.0, then click Next.
On the next screen (General Settings), provide a name and optional logo for your new app, then click Next. This will bring you to the Configure SAML section.
Configure the App
Provide the following values to their respective fields:
General
- Single sign on URL:
https://<cluster-url>:<port>/v1/webapi/saml/acs/okta
- Audience URI (SP Entity ID):
https://<cluster-url>:<port>/v1/webapi/saml/acs/okta
- Name ID format
EmailAddress
- Application username
Okta username
Replace <cluster-url>
with your Teleport Proxy Service address or Enterprise
Cloud tenant (e.g. mytenant.teleport.sh
). Replace <port>
with your Proxy
Service listening port (443
by default).
Attribute Statements
- Name:
username
| Name format:Unspecified
| Value:user.login
Group Attribute Statements
We will map our Okta groups to SAML attribute statements (special signed metadata exposed via a SAML XML response), so that Teleport can discover a user's group membership and assign matching roles.
- Name:
groups
| Name format:Unspecified
- Filter:
Matches regex
|.*
The configuration page should now look like this:
The "Matches regex" filter requires the literal string .*
in order to match all
content from the group attribute statement.
Notice that we have set "NameID" to the email format and mapped the groups with a wildcard regex in the Group Attribute statements. 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.
Once you've filled the required fields, click Next, then finish the app creation wizard.
From the Assignments tab of the new application page, click Assign. Assign the newly created groups access to the app.
Save IdP metadata path
Okta provides an IdP metadata block, used by clients to identify and verify it as a trusted source of user identity.
Since Okta serves this content over HTTPS we can configure Teleport to use this path instead of a local copy, which can go stale.
From the app's Sign On tab, scroll down to SAML Signing Certificates. Click Actions for the SHA-2 entry, then "View IdP metadata":
Copy the URL to the metadata file for use in our Teleport configuration.
You can also right click on the "View IdP metadata" link and select "Copy Link" or "Copy Link Address".
Step 3/4. Create 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 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=groups,okta-admin,editor \
--attributes-to-roles=groups,okta-dev,dev > 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:
- editor
value: okta-admin
- name: groups
roles:
- dev
value: okta-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
The attributes_to_roles
field in the connector resource maps key/value-like attributes of
the assertion from Okta into a list of Teleport roles to apply to the session.
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
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: [email protected]
--------------------------------------------------------------------------------
Authentication details:
roles:
- editor
- dev
traits:
groups:
- Everyone
- okta-admin
- okta-dev
username:
- [email protected]
username: [email protected]
--------------------------------------------------------------------------------
[SAML] Attributes to roles:
- name: groups
roles:
- editor
value: okta-admin
- name: groups
roles:
- dev
value: okta-dev
--------------------------------------------------------------------------------
[SAML] Attributes statements:
groups:
- Everyone
- okta-admin
- okta-dev
username:
- [email protected]
--------------------------------------------------------------------------------
For more details repeat the command with --debug flag.
Create the connector using tctl
:
$ tctl create okta-connector.yaml
Enable default SAML authentication
Configure Teleport to use SAML authentication as the default instead of the local user database.
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
If you need to log in again before configuring your SAML provider, use the flag --auth=local
Step 4/4. Create a developer Teleport role
Now let's create the Teleport role that we will assign to members of the
okta-dev
group. Create the local file dev.yaml
with the content below.
kind: role
version: v5
metadata:
name: dev
spec:
options:
max_session_ttl: 24h
allow:
logins: [ "{{email.local(external.username)}}", ubuntu ]
node_labels:
access: relaxed
Members of this role have are assigned several attributes:
- they are only allowed to login to nodes labelled with
access: relaxed
label. - they can log in as
ubuntu
user or a user matching their email prefix. - they do not have any "allow rules" i.e. they will not be able to see/replay past sessions or re-configure the Teleport cluster.
Notice the {{external.username}}
login. It configures Teleport to look at the
"username" Okta claim and use that field as an allowed login for each user.
This example uses email as the username format. The
email.local(external.username)
function call will remove the @domain
and
leave the username prefix. For full details on how variable expansion works in
Teleport roles, see the Teleport Access Controls
Reference.
Use tctl
to create this role in the Teleport Auth Service:
$ tctl create dev.yaml
We don't need to repeat this process for the "editor" role because this is a preset role that is available by default in all Teleport clusters.
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).
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
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. Under the Management area you can access it within the Activity tab in the Teleport Web UI.
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 Teleport's Auth Service receives a request to list Teleport Nodes (e.g., to
display Nodes in the Web UI or via tsh ls
), it only returns the Nodes that the
current user is authorized to view.
For each Node in the user's Teleport cluster, the Auth Service applies the following checks in order and, if one check fails, hides the Node from the user:
- None of the user's roles contain a
deny
rule that matches the Node's labels. - At least one of the user's roles contains an
allow
rule that matches the Node's labels.
If you are not seeing Nodes when expected, make sure that your user's roles
include the appropriate allow
and deny
rules as documented in the
Teleport Access Controls Reference.
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.