Fork me on GitHub

Teleport

SSH Authentication with Okta

Improve
Setting up Okta SSO with Teleport

Setting up Okta SSO with Teleport

Length: 09:16

How to use Okta as a single sign-on (SSO) provider for SSH

This guide will cover how to configure Okta 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

  • Okta account with admin access. Your account must include users and at least two groups.
  • Teleport role with access to maintaining saml resources. This is available in the default editor 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 tctl admin tool and tsh client tool version >= 11.1.0, which you can download by visiting the customer portal.

    tctl version

    Teleport v11.1.0 go1.19

    tsh version

    Teleport v11.1.0 go1.19

  • A Teleport Cloud account, which includes a running Auth Service and Proxy Service. If you do not have a Teleport Cloud account, visit the sign up page to begin your free trial.

  • The tctl admin tool and tsh client tool version >= 10.3.8. To download these tools, visit the Downloads page.

    tctl version

    Teleport v10.3.8 go1.19

    tsh version

    Teleport v10.3.8 go1.19

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

tsh login --proxy=teleport.example.com [email protected]
tctl status

Cluster teleport.example.com

Version 11.1.0

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 status

Cluster myinstance.teleport.sh

Version 10.3.8

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

Create a file called cap.yaml:

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

Create a resource:

tctl create -f cap.yaml

Configure Okta

First, create a SAML 2.0 Web App in Okta configuration section

1. Select Create New App

Select Web Platform and SAML 2.0 Sign On Method. Create APP

Configure the App

We are going to map the Okta groups we've created above to the SAML Attribute statements (special signed metadata exposed via a SAML XML response).

GENERAL

  • Single sign on URL https://teleport-proxy.example.com:443/v1/webapi/saml/acs/connectorName
  • Audience URI (SP Entity ID)https://teleport-proxy.example.com:443/v1/webapi/saml/acs/connectorName
  • Name ID format EmailAddress
  • Application username Okta username

SINGLE ATTRIBUTE STATEMENTS

  • Name: username | Name format: Unspecified | Value: user.login

GROUP ATTRIBUTE STATEMENTS

  • Name: groups | Name format: Unspecified
  • Filter: Matches regex | .*

Configure APP

Note: RegEx requires .*

Configure APP

tip

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 URL to the same value.

Create & Assign Groups

Create Groups

We are going to create two groups: "okta-dev" and "okta-admin":

Create Group Devs

...and the admin:

Create Group Devs

Assign groups and people to your SAML app:

Configure APP

Make sure to download the metadata in the form of an XML document. It will be used it to configure a Teleport connector:

Download metadata

Create a SAML Connector

Now, create a SAML connector resource:

#
# 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: new_saml_connector
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
    roles:
    - editor
    value: okta-admin
  - name: groups
    roles:
    - access
    value: okta-dev
  # Note that the entire XML document is indented by 4 spaces. This is
  # required because the pipe symbol indicates what follows is raw text.
  # Below is an Example. Replace with your XML
  entity_descriptor: |
    <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.example.com/00000000000000000000">
      <md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:KeyDescriptor use="signing">
          <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
              <ds:X509Certificate>Lu4bLZ57YSPClo5x1RHtXihqSdBfwqTU1tiPnL3i5QrHAXnyrmwscJ1VnutbfaTWCsPlICYQAVin
    vSAArSQU5WTjvZut9UeEenrYY72xDCLNe5vHimOEHFRvPeP626vx7/gkKSSL5F0Se+YYhLLCWcz8
    DYrQn41YZb72PBt5T0vIRS3FMZOYz55Ww8XbIWAwIKKmRfm00bPpMYPTD34ZCnVGTXSkHzHDCehu
    pQMug4IpWIcy45ffbi6sXoFD1ud8vG8H0RFhUk8MBFSCSsYHkrgz5cB8sbPLs0PocxN/nYIFJ2A1
    U68y2d3U/ClLfOb/kh4w3EcKvqtSwsMdLgxHjrDGtPgiAZDJhriZnpCQ0WvgBcAOYjRjsFncTRWH
    DqpTXsQzjkRa3A/KD3pA6bd5aYSF21nKAR7aVj7Aq0ogWEb4owZL5/W2lEnuwKSfGcnrz6GmJSaT
    113wKahleH/VPb1KoaGJ81h5Om1DZI3ohYuxQYC/jwDhOlPXpdECkJe11gSTp34WQ1a93uSYkGo9
    MZ/7WI2LXpD6pjGtz5YSVKR1naj2pci5jwGi86KwL2MqXX288vguvGqcGZXUwi+383Ct99WLBNgo
    9A6kIFvexILcscyeKthsoBGzu+MBipoGnSYuw+vlSa/0jIoluQqYpqYIg7ZBWoOjrKDDFdv01BtL
    nnVBFR43wCIm77obPQ5+103KYWcs42wpAxtX78HdlTav/D35D45GnGxM/fadpth65BSejgoPnd+z
    MXwMOv2W8B+fuolEcQGLrXw+mHtc2p3A7XKGhexY5A+FkSlAs3RMa0weizcylDlW2vj7ksdmZ/Ag
    AQ6EetT85DS6gV9wn3pBaWRhFU/OqFT/PezFcnxjiHVwfil+G9nhYhmjaspLqSLTkGPnyYabReZw
    ZtnSnKnWfwEr5GDqfYxHkBdZUtiofNhu/K/gs/aLTGoxWVac6F9y1xzXYnXPEPkmNsFfwn/H+LuL
    M01dKisWCfMPHCeBTxKSMB3IrixUym64cxlqkvk/rPXrUcktfvPhd/1I9jWIzQwPfbWyW9wpYzBm
    xYqZ1MocFyZhfh1UHOwaOiMlgAlOTDn6irtT1BW/a45nAkCl8jqgFKPSJ6kusj+HffSL6xDQJ0vA
    L5BGENThmToTm7euueLzYY0JDqhqo18wnha5MSCJtB3dcqKTeK+jiyF7FRHfZt/qJolXCufZyN48
    DQGrdrUjjolHvE8jmtgPkYuq9pdTciUnJIQN8vtQ/tOgk0Ui3n03FSM0YNARyaTZ0vgj+GLfGMc6
    VFKf6t/sSgFO8W4dgi2e0VwryOd8Etrq5NFul</ds:X509Certificate>
            </ds:X509Data>
          </ds:KeyInfo>
        </md:KeyDescriptor>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
        <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://www.example.com/app/teleport/00000000000000000000"/>
        <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://www.example.com/app/teleport/00000000000000000000"/>
      </md:IDPSSODescriptor>
    </md:EntityDescriptor>

Enabling the 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 the connector using tctl tool:

tctl create okta-connector.yaml

Create a Developer Teleport Role

We are going to create a new role that'll pull in external information from Okta. Notice {{external.username}} login. It configures Teleport to look at "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.trait) function will remove the @domain and just have the username prefix.

kind: role
version: v5
metadata:
  name: dev
spec:
  options:
    max_session_ttl: 24h
  allow:
    logins: [ "{{email.local(external.username)}}", ubuntu ]
    node_labels:
      access: relaxed
  • Devs are only allowed to login to nodes labelled with access: relaxed label.
  • Developers can log in as ubuntu user
  • Developers also do not have any "allow rules" i.e. they will not be able to see/replay past sessions or re-configure the Teleport cluster.

We'll use tctl to create this role on the auth server:

tctl create dev.yaml

Testing

The Web UI will now contain a new button: "Login with Okta". The CLI is the same as before:

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

This command will print 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 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.

Audit Log Entry for SSO Login error

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.
  • None of the user's roles contain a deny rule that matches the user's login.
  • At least one of the user's roles contains an allow rule that matches the Node's labels.
  • At least one of the user's roles contains an allow rule that matches the user's login.

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