Configure Single Sign-On
Teleport users can log in to servers, Kubernetes clusters, databases, web applications, and Windows desktops through their organization's Single Sign-On (SSO) provider.
- Azure Active Directory (AD): Configure Azure Active Directory SSO for SSH, Kubernetes, databases, desktops and web apps.
- Active Directory (ADFS): Configure Windows Active Directory SSO for SSH, Kubernetes, databases, desktops and web apps.
- Google Workspace: Configure Google Workspace SSO for SSH, Kubernetes, databases, desktops and web apps.
- GitHub: Configure GitHub SSO for SSH, Kubernetes, databases, desktops, and web apps.
- GitLab: Configure GitLab SSO for SSH, Kubernetes, databases, desktops and web apps.
- OneLogin: Configure OneLogin SSO for SSH, Kubernetes, databases, desktops and web apps.
- OIDC: Configure OIDC SSO for SSH, Kubernetes, databases, desktops and web apps.
- Okta: Configure Okta SSO for SSH, Kubernetes, databases, desktops and web apps.
How Teleport uses SSO
You can register your Teleport cluster as an application with your SSO provider. When a user signs in to Teleport, your SSO provider will execute its own authentication flow, then send 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 a short-lived certificate to the user. Teleport also creates a temporary user on the Auth Service backend.
Temporary user
resources
After a user completes an SSO authentication flow, Teleport creates a temporary
user
resource for the user.
When a user signs in to Teleport with tsh login
, they can configure the TTL of
the user
Teleport creates. Teleport enforces a limit of 30 hours (the default
is 12 hours).
In the Teleport audit log, you will see an event of type user.create
with
information about the temporary user.
How can I inspect a temporary user resource?
You can inspect a temporary user
resource created via your SSO integration
by using the tctl
command:
# Log in to your cluster with tsh so you can use tctl remotely
$ tsh login --proxy=example.teleport.sh
$ tctl get users/<username>
Here is an example of a temporary user
resource created when the GitHub user
myuser
signed in to GitHub to authenticate to Teleport. This resource
expires 12 hours after creation. The created_by
field indicates that the
resource was created by Teleport's GitHub SSO integration:
kind: user
metadata:
expires: "2022-06-15T04:02:34.586688054Z"
id: 0000000000000000000
name: myuser
spec:
created_by:
connector:
id: github
identity: myuser
type: github
time: "2022-06-14T16:02:34.586688441Z"
user:
name: system
expires: "0001-01-01T00:00:00Z"
github_identities:
- connector_id: github
username: myuser
roles:
- editor
- access
- auditor
status:
is_locked: false
lock_expires: "0001-01-01T00:00:00Z"
locked_time: "0001-01-01T00:00:00Z"
recovery_attempt_lock_expires: "0001-01-01T00:00:00Z"
traits:
github_teams:
- my-team
kubernetes_groups: null
kubernetes_users: null
logins:
- root
version: v2
Certificates for SSO users
Along with creating a temporary user, Teleport issues SSH and X.509 certificates to a successfully authenticated SSO user's machine. This enables SSO users to authenticate to your cluster without Teleport needing to create a permanent record of them.
In the X.509 certificate, for example, the Subject
field contains the same
information defined in the temporary user
resource. This enables Teleport to
enforce RBAC rules for the authenticated user when they access resources in your
cluster.
This is a Subject
field for a certificate that Teleport issued for the GitHub
user myuser
, who signed in to a Teleport cluster via the GitHub SSO
integration:
Subject: L=myuser/street=teleport.example.com/postalCode={"github_teams":["my-team"],"kubernetes_groups":null,"kubernetes_users":null,"logins":["root"]}, O=access, O=editor, O=auditor, CN=myuser/1.3.9999.1.7=teleport.example.com
The user belongs to the GitHub team my-team
, which this Teleport cluster maps
to the access
, editor
, and auditor
roles in Teleport. (Read the guide for
your SSO provider to determine how to configure role mapping.)
Inspecting your certificate subject
To inspect the contents of an X.509 certificate issued for your user after you sign in to Teleport via SSO, run the following commands:
$ TELEPORT_CLUSTER=<your cluster>
$ SSO_USER=<your username within your SSO provider>
$ openssl x509 -text -in ~/.tsh/keys/${TELEPORT_CLUSTER}/${SSO_USER}-x509.pem | grep "Subject:"
You can inspect an SSH certificate issued for your Teleport user with the following command:
$ ssh-keygen -L -f ~/.tsh/keys/${TELEPORT_CLUSTER}/${SSO_USER}-ssh/${TELEPORT_CLUSTER}-cert.pub
Multiple SSO providers
Since Teleport creates temporary users and issues short-lived certificates when
a user authenticates via SSO, it is straightforward to integrate Teleport with
multiple SSO providers. Besides the temporary user
resource, no persistent
backend data in Teleport is tied to a user's account with the SSO provider.
This also means that if one SSO provider becomes unavailable, the end user only needs to choose another SSO provider when signing in to Teleport. While the user may be locked out of their account with the first SSO provider, signing in via the second provider is sufficient for Teleport to issue a new certificate and grant the user access to your infrastructure.
Note that if the username of an SSO user already belongs to a user registered
locally with the Auth Service (i.e., created via tctl users add
), the SSO
login will fail.
Logging in via SSO
Users can log in to Teleport via your SSO provider by executing a command
similar to the following, using the --auth
flag to specify the provider:
# This command will automatically open the default web browser and take a user
# through the login process with an SSO provider
$ tsh login --proxy=proxy.example.com --auth=github
The command opens a browser window and shows a URL the user can visit in the terminal to complete their SSO flow:
If browser window does not open automatically, open it by clicking on the link:
http://127.0.0.1:45235/055a310a-1099-43ea-8cf6-ffc41d88ad1f
Teleport will wait for up to 3 minutes for a user to authenticate. If
authentication succeeds, Teleport will retrieve SSH and X.509 certificates and
store them in the ~/.tsh/keys/<clustername>
directory. The tool will also will
add SSH cert to an SSH agent if there's one running.
Configuring SSO
Teleport works with SSO providers by relying on the concept of an authentication connector. An authentication connector is a configuration resource that controls how SSO users log in to Teleport—and which Teleport roles they will assume once they do.
This means that you can apply fine-grained RBAC policies to your Teleport cluster without needing to change the solution you use for on– and offboarding users.
Supported connectors
The following authentication connectors are supported:
- Commercial
- Teleport Community Edition
Type | Description |
---|---|
None | If no authentication connector is created, Teleport will use local authentication based user information stored in the Auth Service backend. You can manage user data via the web UI Users page and the tctl users command. |
saml | The SAML connector type uses the SAML protocol to authenticate users and query their group membership. |
oidc | The OIDC connector type uses the OpenID Connect protocol to authenticate users and query their group membership. |
github | The GitHub connector uses GitHub SSO to authenticate users and query their group membership. |
Type | Description |
---|---|
None | If no authentication connector is created, Teleport will use local authentication based user information stored in the Auth Service backend. You can manage user data via the web UI Users page and the tctl users command. |
github | The GitHub connector uses GitHub SSO to authenticate users and query their group membership. |
Creating an authentication connector
- Commercial
- Teleport Community Edition
Before you can create an authentication connector, you must enable authentication via that connector's protocol.
To set the default authentication type as saml
or oidc
, either modify your
Auth Service configuration file (if using a self-hosted edition of Teleport) or
create a cluster_auth_preference
resource.
- Static Config (Self-Hosted)
- Dynamic Resources (All Editions)
Update /etc/teleport.yaml
in the auth_service
section and restart the teleport
daemon.
auth_service:
authentication:
# Set as saml, oidc, or github
type: saml|oidc|github
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
Create a file called cap.yaml
:
kind: cluster_auth_preference
metadata:
name: cluster-auth-preference
spec:
# Set as saml, oidc, or github
type: saml|oidc|github
version: v2
Create the resource:
# Log in to your cluster with tsh so you can run tctl commands.
$ tsh login --proxy=mytenant.teleport.sh --user=myuser
$ tctl create -f cap.yaml
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
Next, define an authentication connector. Create a file called connector.yaml
based on one of the following examples.
- Okta
- OneLogin
- OIDC
- Google Workspace
- ADFS
- SAML
- GitHub
#
# Example resource for a SAML connector
# This connector can be used for SAML endpoints like Okta
#
kind: saml
version: v2
metadata:
# the name of the connector
name: okta
spec:
# connector display name that will be appended to the title of "Login with"
# button on the cluster login screen so it will say "Login with Okta"
display: Okta
# SAML provider will make a callback to this URL after successful authentication
# cluster-url is the address the cluster UI is reachable at.
# The last segment of the URL must be identical to the connector metadata name.
acs: https://<cluster-url>/v1/webapi/saml/acs/new_saml_connector
# Controls whether IdP-initiated SSO is allowed. If false, all such requests will be rejected with an error.
allow_idp_initiated: false
attributes_to_roles:
- name: groups
value: okta-admin
roles:
- editor
- name: groups
value: okta-dev
roles:
- access
# Provides a path to the IdP metadata.
entity_descriptor_url: https://example.okta.com/app/your-app-id/sso/saml/metadata
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
kind: saml
version: v2
metadata:
name: OneLogin
spec:
acs: https://teleport.example.com/v1/webapi/saml/acs/onelogin
attributes_to_roles:
- name: groups
roles:
- editor
value: admin
- name: groups
roles:
- access
value: dev
audience: https://teleport.example.com:443/v1/webapi/saml/acs/onelogin
cert: ""
display: OneLogin
entity_descriptor: |
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.example.com/00000000000000000000">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false"
entity_descriptor_url: ""
issuer: ""
service_provider_issuer: https://teleport.example.com:443/v1/webapi/saml/acs/onelogin
sso: ""
version: v2
kind: oidc
metadata:
name: oidc_connector
spec:
claims_to_roles:
- claim: groups
roles:
- access
value: users
- claim: groups
roles:
- editor
value: admins
client_id: <CLIENT-NAME>
client_secret: <CLIENT-SECRET>
issuer_url: https://idp.example.com/
redirect_url: https://mytenant.teleport.sh:443/v1/webapi/oidc/callback
max_age: 24h
version: v3
kind: oidc
metadata:
name: google
spec:
claims_to_roles:
- claim: groups
roles:
- auditor
value: auditor@google-workspace-group-email.com
- claim: groups
roles:
- access
value: teleport-[email protected]
client_id: <GOOGLE-WORKSPACE-CLIENT-ID>.apps.googleusercontent.com
client_secret: <OAUTH-CLIENT-SECRET>
display: Google
google_admin_email: <GOOGLE-WORKSPACE-ADMIN-EMAIL>
google_service_account: |
{
"type": "service_account",
"project_id": "<PROJECT-ID>",
"private_key_id": "<PRIVATE-KEY-ID>",
"private_key": "-----BEGIN PRIVATE KEY-----\n<PRIVATE-KEY-CONTENTS>\n-----END PRIVATE KEY-----\n",
"client_email": "<TELEPORT-SERVICE-ACCOUNT-EMAIL>",
"client_id": "<CLIENT-ID>",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/teleport-service-account%40access-304316.iam.gserviceaccount.com"
}
issuer_url: https://accounts.google.com
redirect_url: https://<SELF-HOSTED-CLUSTER-URL|TENANT-ID.teleport.sh>/v1/webapi/oidc/callback
scope:
- openid
- email
version: v3
# This example connector uses SAML to authenticate against
# Active Directory Federation Services (ADFS)
kind: saml
version: v2
metadata:
name: adfs_connector
spec:
# display allows to set the caption of the "login" button
# in the Web interface
# Using the work 'Microsoft' will show the windows symbol in the UI.
display: Microsoft
# "adfs" provider setting tells Teleport that this SAML connector uses ADFS
# as a provider
provider: adfs
# Controls whether IdP-initiated SSO is allowed. If false, all such requests will be rejected with an error.
allow_idp_initiated: false
# entity_descriptor XML can either be copied into connector or fetched from a URL
entity_descriptor: |
<EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
...
</md:EntityDescriptor>
# entity_descriptor_url is commented out, as only one is required to setup adfs.
# if you're running Teleport in FIPS mode entity_descriptor_url with Azure AD may
# fail
#entity_descriptor_url: "https://example.com"
# issuer typically comes from the "entity_descriptor" but can be overridden here
issuer: "foo"
# sso typically comes from the "entity_descriptor" but can be overridden here
sso: "bar"
# cert typically comes from the "entity_descriptor" but can be overridden here
cert: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
acs: "https://<cluster-url>.example.com:3080/v1/webapi/saml/acs"
# if "service_provider_issuer" is not set, comes from "acs"
service_provider_issuer: "https://<cluster-url>.example.com:3080/v1/webapi/saml/acs"
# if "audience" is not set, comes from "acs"
audience: "https://<cluster-url>.example.com:3080/v1/webapi/saml/acs"
# if "signing_key_pair" is not set, teleport will generate a self signed
# signing key pair
signing_key_pair:
private_key: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
cert:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
attributes_to_roles:
- name: "http://schemas.xmlsoap.org/claims/Group"
value: "Administrators"
roles: ["editor"]
- name: "http://schemas.xmlsoap.org/claims/Group"
value: "Users"
roles: ["access"]
#
# Example resource for a SAML connector
# This connector can be used for SAML endpoints like Okta
#
kind: saml
version: v2
metadata:
# the name of the connector
name: okta
spec:
# connector display name that will be appended to the title of "Login with"
# button on the cluster login screen so it will say "Login with Okta"
display: Okta
# SAML provider will make a callback to this URL after successful authentication
# cluster-url is the address the cluster UI is reachable at.
# The last segment of the URL must be identical to the connector metadata name.
acs: https://<cluster-url>/v1/webapi/saml/acs/new_saml_connector
# Controls whether IdP-initiated SSO is allowed. If false, all such requests will be rejected with an error.
allow_idp_initiated: false
attributes_to_roles:
- name: groups
value: okta-admin
roles:
- editor
- name: groups
value: okta-dev
roles:
- access
# Provides a path to the IdP metadata.
entity_descriptor_url: https://example.okta.com/app/your-app-id/sso/saml/metadata
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
kind: github
version: v3
metadata:
name: github
spec:
# GitHub OAuth app client ID
client_id: <client-id>
# GitHub OAuth app client secret
client_secret: <client-secret>
# GitHub will make a callback to this URL after successful authentication
# cluster-url is the address the cluster UI is reachable at
redirect_url: "https://<cluster-url>/v1/webapi/github/callback"
# connector display name that will be appended to the title of "Login with"
# button on the cluster login screen so it will say "Login with GitHub"
display: Github
# mapping of GitHub team memberships to Teleport cluster roles
teams_to_logins:
- logins:
- access
- editor
organization: <github-org>
team: <github-team>
You may use entity_descriptor_url
, in lieu of entity_descriptor
, to fetch
the entity descriptor from your IDP.
We recommend "pinning" the entity descriptor by including the XML rather than fetching from a URL.
Next, define an authentication connector. Create a file called connector.yaml
with the following content:
kind: cluster_auth_preference
metadata:
name: cluster-auth-preference
spec:
type: github
webauthn:
# Replace with the address of your Teleport cluster
rp_id: 'example.teleport.sh'
version: v2
Create the connector:
$ tctl create -f connector.yaml
User logins
Often it is required to restrict SSO users to their unique UNIX logins when they connect to Teleport Nodes. To support this:
- Use the SSO provider to create a field called
unix_login
(you can use another name). - Make sure the
unix_login
field is exposed as a claim via SAML/OIDC. - Update a Teleport role to include the
{{external.unix_login}}
variable in the list of allowed logins:
kind: role
version: v5
metadata:
name: sso_user
spec:
allow:
logins:
- '{{external.unix_login}}'
node_labels:
'*': '*'
Provider-Specific Workarounds
Certain SSO providers may require or benefit from changes to Teleport's SSO
flow. These provider-specific changes can be enabled by setting the
spec.provider
property of the connector definition to one of the following
values to match your identity provider:
adfs
(SAML): Required for compatibility with Active Directory (ADFS); refer to the full ADFS guide for details.netiq
(OIDC): Used to enable NetIQ-specific ACR value processing; refer to the OIDC guide for details.ping
(SAML and OIDC): Required for compatibility with Ping Identity (including PingOne and PingFederate).okta
(OIDC): Required when using Okta as an OIDC provider.
At this time, the spec.provider
field should not be set for any other identity providers.
Working with an external email identity
Along with sending groups, an SSO provider will also provide a user's email address. In many organizations, the username that a person uses to log in to a system is the same as the first part of their email address, the "local" part.
For example, [email protected]
might log in with the username dave.smith
.
Teleport provides an easy way to extract the first part of an email address so
it can be used as a username. This is the {{email.local}}
function.
If the email claim from the identity provider (which can be accessed via
{{external.email}}
) is sent and contains an email address, you can extract the
"local" part of the email address before the @ sign like this:
{{email.local(external.email)}}
Here's how this looks in a Teleport role:
kind: role
version: v5
metadata:
name: sso_user
spec:
allow:
logins:
# Extracts the local part of [email protected], so the login will
# now support dave.smith.
- '{{email.local(external.email)}}'
node_labels:
'*': '*'
Working with multiple SSO providers
Teleport can also support multiple connectors. For example, a Teleport
administrator can define and create multiple connector resources using
tctl create
as shown above.
To see all configured connectors, execute this command on the Auth Server:
$ tctl get connectors
To delete/update connectors, use the usual tctl rm
and tctl create
commands
as described in the Resources Reference.
If multiple authentication connectors exist, the clients must supply a
connector name to tsh login
via --auth
argument:
# use "okta" SAML connector:
$ tsh --proxy=proxy.example.com login --auth=okta
# use local Teleport user DB:
$ tsh --proxy=proxy.example.com login --auth=local --user=admin
Refer to the following guides to configure authentication connectors of both SAML and OIDC types:
- SSH Authentication with Okta
- SSH Authentication with OneLogin
- SSH Authentication with ADFS
- SSH Authentication with OAuth2 / OpenID Connect
SSO customization
Use the display
field in an authentication connector to control the appearance
of SSO buttons in the Teleport Web UI.
Provider | YAML | Example |
---|---|---|
GitHub | display: GitHub | |
Microsoft | display: Microsoft | |
display: Google | ||
BitBucket | display: Bitbucket | |
OpenID | display: Okta |
Troubleshooting
Troubleshooting SSO configuration can be challenging. Usually a Teleport administrator must be able to:
- Self-Hosted
- Ensure that HTTP/TLS certificates are configured properly for both Teleport proxy and the SSO provider.
- 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.
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. You can access it in the Activity tab of 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",
"method": "oidc",
"success": false,
"time": "2019-06-15T19:38:07Z",
"uid": "cd9e45d0-b68c-43c3-87cf-73c4e0ec37e9"
}
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
Next steps
The roles we illustrated in this guide use external
traits,
which Teleport replaces with values from the single sign-on provider that the
user used to authenticate with Teleport. For full details on how variable
expansion works in Teleport roles, see the Teleport Access Controls
Reference.