Fork me on GitHub

Teleport

SSH Authentication with Google Workspace (G Suite)

Improve
Using Google Workspace SSO with Teleport

Using Google Workspace SSO with Teleport

Length: 10:41

This guide will explain how to configure Google Workspace 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" Google group can SSH into machines running PostgreSQL.
  • Developers must never SSH into production servers.

Prerequisites

Before you get started you’ll need:

  • A Google Workspace super administrator account. We recommend setting up a separate super admin account with 2FA as opposed to granting your daily user super admin privileges.
  • Ability to create a Google Cloud project, which requires signing up for Google Cloud. Note that this guide will not require using any paid Google Cloud services.
  • Ability to set up Google Workspace groups.
  • Teleport role with access to maintaining oidc resources. This is available in the default editor role.
  • A running Teleport cluster. For details on how to set this up, see our Enterprise Getting Started guide.

  • The tctl admin tool and tsh client tool version >= 10.2.2, which you can download by visiting the customer portal.

    tctl version

    Teleport v10.2.2 go1.18

    tsh version

    Teleport v10.2.2 go1.18

  • A Teleport Cloud account. If you do not have one, visit the sign up page to begin your free trial.

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

    tctl version

    Teleport v10.1.9 go1.18

    tsh version

    Teleport v10.1.9 go1.18

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 10.2.2

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.1.9

CA pin sha256:sha-hash-here

You must run subsequent tctl commands in this guide on your local machine.

Step 1/4. Enable default OIDC authentication

Configure Teleport to use OIDC 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: oidc

Create a file called cap.yaml:

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

Create a resource:

tctl create -f cap.yaml

Step 2/4. Configure Google Workspace

The setup will consist of:

  • Determining whether your Google Workspace plan is correct for your Teleport usage
  • Creating a new project on Google Cloud Platform
  • Configuring OAuth consent for the new project
  • Creating an OAuth client ID to allow Google Workspace users to log in to your Teleport cluster
  • Creating a service account for Teleport to fetch the additional Google Groups data.

Ensure your Google Workspace plan is correct

Teleport's Google Workspace integration works differently depending on your Google Workspace plan. In this section, we will explain how to determine if Teleport supports your current Google Workspace setup.

How Google Workspace APIs differ by service level

In Google Workspace, transitive group membership takes place when a user is a member of one group by virtue of being in another group. This happens when a child group is nested within a parent group, so that a member of a child group is also a member of the parent group.

Google Workspace service accounts can determine whether a user has a transitive membership to a specific group by calling methods within the Google Workspace Cloud Identity API. These API methods are only usable for users belonging to specific Google Workspace plans:

  • Enterprise Standard
  • Enterprise Plus
  • Enterprise for Education
  • Cloud Identity Premium

The Google Workspace Directory API allows administrators to list users and groups in their Google Workspace domain, but does not enable them to query transitive group memberships. The Directory API is available for all Google Workspace plans.

How Teleport uses Google Workspace APIs

Teleport's OIDC connector uses Google Workspace's APIs differently depending on the resource version.

We will show you how to configure the connector later in the guide, but for now, you should ensure that your Google Workspace plan allows you to use Teleport as you intend.

We currently support OIDC connector versions v2 and v3.

Teleport versions prior to 8.1.2 only support v2 of the OIDC connector.

The OIDC connector maps a user's roles to the Google Workspace groups they belong to.

In order to list a user's Google Workspace groups, Teleport will first attempt to fetch credentials for calling Cloud Identity API methods, then use these credentials to query a user's transitive group memberships.

If these credentials do not exist, Teleport will fetch credentials for the Directory API instead, and will use this API to list the user's groups in your entire Google Workspace account. Groups that the user belongs to that are external to the workspace will not be listed.

The OIDC connector maps a user's roles to the Google Workspace groups they belong to.

If these credentials do not exist, Teleport will fetch credentials for the Directory API instead, and will use this API to list the user's groups within your Google Workspace domain. Any group registered on a different domain or subdomain than the user's will be ignored.

How to check your current plan

To troubleshoot whether your Google Workspace plan supports querying transitive group memberships, you can visit the Groups Inspection page in the Google Admin Console, which relies on the Cloud Identity API.

If your Google Workspace plan does not support the Cloud Identity API, you must ensure that your RBAC does not depend on transitive group memberships.

When querying transitive group memberships, we recommend blocking access to external groups at the workspace level (following these instructions), as membership in any group that the service account doesn't have full visibility on (including all groups external to the workspace) will prevent users from logging in.

Create a new project

In the GCP console, choose to Create a new project.

creation of a Google Cloud Platform project

On the OAuth consent screen page of the GCP console, select"Internal" as your User Type.

configuration of the OAuth consent screen

Configure the appearance of your connector by picking a visible name, user support email, etc.

Select scopes

Select the .../auth/userinfo.email and openid scopes. select email and openid scopes

Enable the Cloud Identity API or the Admin SDK API for transitive and direct group membership, respectively. Enabling both is fine.

Your Google Workspace account must enable support for the API you choose to use.

Please consult the documentation for your chosen API to ensure that you have the correct Google Workspace plan.

Create an OAuth client ID

In the Create an OAuth client ID page of the GCP console, select "Web application" as the Application type, pick a name, then add the following as an authorized redirect URI.

https://<address of proxy server>:3080/v1/webapi/oidc/callback

OAuth client ID creation

Copy the Client ID and Client Secret from the next screen or by clicking "Download OAuth client". OAuth client data

Create a service account

On the Create a service account page, pick a name for your service account. Leave project access grants and user access grants empty. service account creation

Click the newly-created account to view its details, and copy the Unique ID for later. service account unique ID

Create a new key for the service account, select JSON as the key type, and save the resulting JSON file. service account key creation Later, we will make this JSON available to the Teleport Auth Server via the OIDC Connector configuration, either by referencing a local file or pasting the JSON into the configuration YAML. If you plan to take the first approach, you will need to upload the JSON to the Auth Server.

Note

Teleport requires the service account JSON to be available to all Teleport Auth Server hosts when deploying Teleport in a High Availability configuration. Unless you paste the JSON into the OIDC Connector configuration, you will need to upload the JSON file to all Auth Server hosts.

Configure domain-wide delegation

Configure domain-wide delegation for your newly-created service account:

Click "Add new" and add the numeric Unique ID that you've copied earlier. domain-wide delegation

Add either the https://www.googleapis.com/auth/cloud-identity.groups.readonly scope or the https://www.googleapis.com/auth/admin.directory.group.readonly scope. The scope granted to the service account will determine if Teleport will fetch both direct and indirect groups or just direct groups, respectively.

Step 3/4. Create an OIDC connector

Create the following OIDC connector resource spec as gworkspace-connector.yaml. We will explain how to choose values for fields within the resource spec below.

kind: oidc
metadata:
  name: google
spec:
  claims_to_roles:
  - claim: groups
    roles:
    - auditor
    value: <[email protected]>
  - claim: groups
    roles:
    - access
    value: [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_uri: file:///var/lib/teleport/gworkspace-creds.json
  issuer_url: https://accounts.google.com
  redirect_url: https://<cluster-url>:3080/v1/webapi/oidc/callback
  scope:
  - openid
  - email
version: v3

kind: oidc
metadata:
  name: google
spec:
  claims_to_roles:
  - claim: groups
    roles:
    - auditor
    value: <[email protected]>
  - claim: groups
    roles:
    - access
    value: [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://<cluster-url>:3080/v1/webapi/oidc/callback
  scope:
  - openid
  - email
version: v3

The email that you set for google_admin_email must be the email address of a user that has permission to list all groups, users, and group membership in your Google Workspace account. This user will generally need super admin or group admin privileges.

Do not use the email of the service account for google_admin_email. The configuration display will look the same, but the service account will not have the required domain-wide delegation.

The client_id field must be the unique ID number captured from the Google Cloud Platform UI. An indicator that this is misconfigured is if you see "invalid Google Workspace credentials for scopes [...]" in your log.

Create the connector using the tctl tool:

tctl create gworkspace-connector.yaml

If you have a configured connector from a version of Teleport older than 8.1.2, you can upgrade your connector from v2 to v3:

First, fetch the connector data:

umask 077
tctl get --with-secrets oidc/connectorname > connector.yaml

Next, edit connector.yaml to change the version number from v2 to v3, and then update the connector:

tctl create -f connector.yaml
rm connector.yaml

Then, to start fetching transitive groups instead of just direct groups, edit the domain-wide delegation for your service account and swap out the OAuth scopes for https://www.googleapis.com/auth/cloud-identity.groups.readonly. To undo the change, remove that scope and add https://www.googleapis.com/auth/admin.directory.group.readonly again.

While a v3 connector is configured, you can no longer downgrade Teleport to a version before 8.1.2. Before such a downgrade, follow the above instructions and change the version number back to v2.

Step 4/4. Test your Google Workspace OIDC connector

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

tsh --proxy=proxy.example.com login

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

Tip

Teleport can use multiple OIDC connectors. In this case a connector name can be passed via tsh login --auth=google

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

Further reading