
This guide will explain how to configure Active Directory Federation Services (ADFS) to be a single sign-on (SSO) provider to issue SSH credentials to specific groups of users. When used in combination with role based access control (RBAC), it allows SSH administrators to define policies like:
- Only members of "DBA" group can SSH into machines running PostgreSQL.
- Developers must never SSH into production servers.
Prerequisites
- ADFS installation with Admin access and users assigned to at least two groups.
- Teleport role with access to maintaining
saml
resources. This is available in the defaulteditor
role.
-
A running Teleport cluster, including the Auth Service and Proxy Service. For details on how to set this up, see our Enterprise Getting Started guide.
-
The Enterprise
tctl
admin tool andtsh
client tool version >= 12.1.1, which you can download by visiting the customer portal.tctl versionTeleport Enterprise v12.1.1 go1.19
tsh versionTeleport v12.1.1 go1.19
Please use the latest version of Teleport Enterprise documentation.
To connect to Teleport, log in to your cluster using tsh
, then use tctl
remotely:
tsh login --proxy=teleport.example.com [email protected]tctl statusCluster teleport.example.com
Version 12.1.1
CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
You can run subsequent tctl
commands in this guide on your local machine.
For full privileges, you can also run tctl
commands on your Auth Service host.
To connect to Teleport, log in to your cluster using tsh
, then use tctl
remotely:
tsh login --proxy=myinstance.teleport.sh [email protected]tctl statusCluster myinstance.teleport.sh
Version 12.1.1
CA pin sha256:sha-hash-here
You must run subsequent tctl
commands in this guide on your local machine.
Enable default SAML authentication
Configure Teleport to use SAML authentication as the default instead of the local user database.
You can either edit your Teleport configuration file or create a dynamic resource.
Update /etc/teleport.yaml
in the auth_service
section and restart the teleport
daemon.
auth_service:
authentication:
type: saml
Please use the latest version of Teleport Enterprise documentation.
Configure ADFS
You'll need to configure ADFS to export claims about a user (Claims Provider Trust in ADFS terminology) and you'll need to configure ADFS to trust Teleport (a Relying Party Trust in ADFS terminology).
For Claims Provider Trust configuration, you'll need to specify at least the
following two incoming claims: Name ID
and Group
. Name ID
should be a
mapping of the LDAP Attribute E-Mail-Addresses
to Name ID
. A group
membership claim should be used to map users to roles (for example to
separate normal users and admins).


In addition, if you are using dynamic roles (see below), it may be useful to map
the LDAP Attribute SAM-Account-Name
to Windows account name
and create
another mapping of E-Mail-Addresses
to UPN
.


You'll also need to create a Relying Party Trust. Use the below information to
help guide you through the Wizard. Note that for development purposes we recommend
using https://localhost:3080/v1/webapi/saml/acs
as the Assertion Consumer
Service (ACS) URL, but for production you'll want to change this to a domain
that can be accessed by other users as well.
- Create a claims aware trust.
- Enter data about the relying party manually.
- Set the display name to something along the lines of
Teleport
. - Skip the token encryption certificate.
- Select "Enable support for SAML 2.0 Web SSO protocol" and set the URL to
https://localhost:3080/v1/webapi/saml/acs
. - Set the relying party trust identifier to
https://localhost:3080/v1/webapi/saml/acs
as well. - For access control policy select "Permit everyone".
Once the Relying Party Trust has been created, update the Claim Issuance Policy
for it. Like before, make sure you send at least Name ID
and Group
claims to the
relying party (Teleport). If you are using dynamic roles, it may be useful to
map the LDAP Attribute SAM-Account-Name
to "Windows account name" and create
another mapping of E-Mail-Addresses
to "UPN".
Lastly, ensure the user you create in Active Directory has an email address associated with it. To check this open Server Manager then "Tools -> Active Directory Users and Computers" and select the user and right click and open properties. Make sure the email address field is filled out.
Create Teleport roles
Let's create two Teleport roles: one for administrators and the other for
normal users. You can create them using the tctl create {file name}
CLI command
or via the Web UI.
# admin-role.yaml
kind: "role"
version: "v3"
metadata:
name: "admin"
spec:
options:
max_session_ttl: "8h0m0s"
allow:
logins: [ root ]
node_labels:
"*": "*"
rules:
- resources: ["*"]
verbs: ["*"]
# user-role.yaml
kind: "role"
version: "v3"
metadata:
name: "dev"
spec:
options:
# regular users can only be guests and their certificates will have a TTL of 1 hour:
max_session_ttl: "1h"
allow:
# only allow login as either ubuntu or the 'windowsaccountname' claim
logins: [ '{{external["http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]}}', ubuntu ]
node_labels:
"access": "relaxed"
This role declares:
- Devs are only allowed to log in to nodes labeled
access: relaxed
. - Developers can log in as the
ubuntu
user. - Developers will not be able to see or replay past sessions or re-configure the Teleport cluster.
The login
{{external["http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]}}
configures Teleport to look at the
http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname
ADFS claim and use that field as an allowed login for each user. Note the
double quotes ("
) and square brackets ([]
) around the claim name—these are
important.
Next, create a SAML connector resource:
# 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"]
The acs
field should match the value you set in ADFS earlier and you can
obtain the entity_descriptor_url
from ADFS under "ADFS -> Service -> Endpoints -> Metadata".
The attributes_to_roles
is used to map attributes to the Teleport roles you
just created. In our situation, we are mapping the "Group" attribute whose full
name is http://schemas.xmlsoap.org/claims/Group
with a value of "admins"
to the "admin" role. Groups with the value "users" is being mapped to the
"users" role.
Export the signing key
For the last step, you'll need to export the signing key:
tctl saml export adfs
Save the output to a file named saml.crt
, return back to ADFS, open the
"Relying Party Trust" and add this file as one of the signature verification
certificates.
Testing
The Web UI will now contain a new button: "Login with MS Active Directory". The CLI is the same as before:
tsh --proxy=proxy.example.com login
This command will print the SSO login URL and try to open it automatically in a browser.
Teleport can use multiple SAML connectors. In this case a connector name
can be passed via tsh login --auth=connector_name
Troubleshooting
Troubleshooting SSO configuration can be challenging. Usually a Teleport administrator must be able to:
- 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