Transforming Privileged Access: A Dialogue on Secretless, Zero Trust Architecture
Watch the Replay
Teleport logoTry For Free
Fork me on GitHub

Teleport

Protect Google Cloud API Access with Teleport

  • Available for:
  • OpenSource
  • Enterprise
  • Cloud

You can use Teleport to manage access to CLI tools that interact with Google Cloud's APIs. This lets you control access to your infrastructure's management APIs using the same RBAC system that you use to protect your infrastructure itself.

The Teleport Application Service manages access to Google Cloud's APIs by proxying requests from CLI applications. The Application Service authenticates these requests using tokens retrieved from Google Cloud. This enables Teleport operators to control the service accounts that users can assume in order to interact with Google Cloud APIs.

The Teleport Application Service connects to the Teleport Proxy Service over a reverse tunnel, so you can run the Application Service in a private network and prevent unauthorized access to your organization's Google Cloud service accounts.

Prerequisites

  • A running Teleport cluster. For details on how to set this up, see the Getting Started guide.

  • The tctl admin tool and tsh client tool version >= 15.1.10.

    See Installation for details.

To check version information, run the tctl version and tsh version commands. For example:

tctl version

Teleport v15.1.10 git:api/14.0.0-gd1e081e go1.21

tsh version

Teleport v15.1.10 go1.21

Proxy version: 15.1.10Proxy: teleport.example.com
  • A running Teleport Enterprise cluster. For details on how to set this up, see the Enterprise Getting Started guide.

  • The Enterprise tctl admin tool and tsh client tool version >= 15.1.10.

    You can download these tools by visiting your Teleport account workspace.

To check version information, run the tctl version and tsh version commands. For example:

tctl version

Teleport Enterprise v15.1.10 git:api/14.0.0-gd1e081e go1.21

tsh version

Teleport v15.1.10 go1.21

Proxy version: 15.1.10Proxy: teleport.example.com
  • A Teleport Enterprise Cloud account. If you don't have an account, sign up to begin a free trial.

  • The Enterprise tctl admin tool and tsh client tool version >= 15.1.9.

    You can download these tools from the Cloud Downloads page.

To check version information, run the tctl version and tsh version commands. For example:

tctl version

Teleport Enterprise v15.1.9 git:api/14.0.0-gd1e081e go1.21

tsh version

Teleport v15.1.9 go1.21

Proxy version: 15.1.9Proxy: teleport.example.com
  • A Google Cloud account with permissions to create IAM roles and service accounts, as well as create IAM role bindings for service accounts and projects.

  • The gcloud CLI tool. Follow the Google Cloud documentation page to install and authenticate to gcloud.

    While this guide focuses on gcloud, once you set up Google Cloud API access with Teleport, you can also manage access to gsutil and other Google Cloud CLI tools using the Teleport Application Service.

  • Either a Google Compute Engine VM where you will run the Teleport Application Service or permissions to create VMs in your Google Cloud project. If you are using a pre-existing VM, it must be running a Linux distribution, and you must have permissions to attach service accounts to Google Compute Engine VMs.

Using existing service accounts

In this guide, we will demonstrate Google Cloud CLI access by creating a service account for Teleport users to authenticate as, teleport-vm-viewer. If you would like to enable access to any existing service accounts in your Google Cloud project, you can replace teleport-vm-viewer with these as you work through the guide.

  • To check that you can connect to your Teleport cluster, sign in with tsh login, then verify that you can run tctl commands using your current credentials. tctl is supported on macOS and Linux machines. For example:
    tsh login --proxy=teleport.example.com --user=[email protected]
    tctl status

    Cluster teleport.example.com

    Version 15.1.10

    CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.

Step 1/4. Configure Google Cloud

The Teleport Application Service needs permissions from Google Cloud to proxy requests from Teleport users to Google Cloud's APIs. In this step, you will configure these permissions before you launch the Teleport Application Service.

When setting up Google Cloud API access with Teleport, you will configure service accounts with two different functions:

  • Controlling service account: The Application Service uses this service account to impersonate other service accounts and sign requests to Google Cloud APIs. In this guide, we will create a controlling service account called teleport-google-cloud-cli.
  • Target service accounts: These are the service accounts you would like Teleport users in your organization to assume when accessing Google Cloud APIs. In this guide, we will create one target service account, teleport-vm-viewer, and you can follow the same steps to enable access to other target service accounts.

Create a service account for the Application Service

The Application Service uses the controlling service account to access Google Cloud APIs by generating signed tokens for target service accounts, which it uses to sign requests from Teleport users before forwarding them to Google Cloud. This way, local Google Cloud CLI tools have no access to these tokens.

In this section, we will create a controlling service account for the Application Service and assign permissions to it.

Create a service account called teleport-google-cloud-cli:

gcloud iam service-accounts create teleport-google-cloud-cli \ --description="Google Cloud CLI access" \ --display-name="teleport-google-cloud-cli"

Enable your service account to act as other service accounts by assigning it the predefined "Service Account User" role:

gcloud projects add-iam-policy-binding google-cloud-project \ --member="serviceAccount:teleport-google-cloud-cli@google-cloud-project.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser"

Set up a service account that Teleport users can access

When a Teleport user executes a Google Cloud CLI command against the Teleport Application Service, the Application Service will use the teleport-google-cloud-cli service account we created earlier to impersonate a target service account.

In this section, we will show you how to grant the Application Service permissions to impersonate target service accounts.

Create a service account and enable it to view resources

If you are enabling access to an existing service account, you can skip to the next section.

Create a target service account:

gcloud iam service-accounts create teleport-vm-viewer \ --description="Sample service account to demonstrate Teleport" \ --display-name="teleport-vm-viewer"

Bind this service account to the predefined "Compute Viewer" role, which allows users with the role to list Google Compute Engine resources:

gcloud projects add-iam-policy-binding google-cloud-project \ --member="serviceAccount:teleport-vm-viewer@google-cloud-project.iam.gserviceaccount.com" \ --role="roles/compute.viewer"

Enable teleport-google-cloud-cli to impersonate target service accounts

Enable the teleport-google-cloud-cli service account to impersonate teleport-vm-viewer in order to authenticate user requests. To do so, bind the teleport-google-cloud-cli account to the predefined "Service Account Token Creator Role" for the teleport-vm-viewer service account:

To enable Google Cloud CLI access for pre-existing service accounts, you must run this command for each service account.

gcloud iam service-accounts add-iam-policy-binding \ teleport-vm-viewer@google-cloud-project.iam.gserviceaccount.com \ --member=serviceAccount:teleport-google-cloud-cli@google-cloud-project.iam.gserviceaccount.com \ --role="roles/iam.serviceAccountTokenCreator"

Step 2/4. Deploy the Teleport Application Service

At this point, you have created a controlling service account and enabled this service account to impersonate the service accounts you would like Teleport users to access.

In this step, you will attach the controlling service account to a Google Compute Engine VM, then run the Teleport Application Service.

Enable the Application Service to access Google Cloud

Now that you have created a controlling service account and attached a role to it, associate your service account with a virtual machine running the Teleport Application Service. The instructions depend on whether you are using a pre-existing virtual machine for the Teleport Application Service or launching a new one:

Create a new virtual machine with the teleport-google-cloud service account attached:

gcloud compute instances create teleport-app-service \ --service-account=teleport-google-cloud-cli@google-cloud-project.iam.gserviceaccount.com \ --scopes=cloud-platform \ --zone=google-cloud-zone \ --image=https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-11-bullseye-v20231212

You must use the service-account and scopes flags as we list them here, otherwise the VM will fail to obtain the required authorization to access Google Cloud. You should adjust the remaining flags and include new ones according to the needs of your environment.

Stop your VM so you can attach your service account to it:

gcloud compute instances stop vm-name --zone=google-cloud-zone

Attach your service account to the instance:

gcloud compute instances set-service-account vm-name \ --service-account teleport-google-cloud-cli@google-cloud-project.iam.gserviceaccount.com \ --zone google-cloud-zone \ --scopes=cloud-platform

You must use the scopes flag in the gcloud compute instances set-service-account command. Otherwise, your Google Cloud VM will fail to obtain the required authorization to access Google Cloud.

Once you have attached the service account, restart your VM:

gcloud compute instances start vm-name --zone google-cloud-zone

Get a join token

Establish trust between your Teleport cluster and your new Application Service instance by creating a join token:

tctl tokens add --type=app --ttl=1h --format=text
abcd123-insecure-do-not-use-this

On the host where you will install the Teleport Application Service, create a file called /tmp/token that consists only of your token:

echo join-token | sudo tee /tmp/token

Install the Teleport Application Service

Follow the instructions below on the host where you will install the Teleport Application Service.

Select an edition, then follow the instructions for that edition to install Teleport.

Teleport Edition

The following command updates the repository for the package manager on the local operating system and installs the provided Teleport version:

curl https://goteleport.com/static/install.sh | bash -s 15.1.10

Download Teleport's PGP public key

sudo curl https://apt.releases.teleport.dev/gpg \-o /usr/share/keyrings/teleport-archive-keyring.asc

Source variables about OS version

source /etc/os-release

Add the Teleport APT repository for v15. You'll need to update this

file for each major release of Teleport.

echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} stable/v15" \| sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null

sudo apt-get update
sudo apt-get install teleport-ent

For FedRAMP/FIPS-compliant installations, install the teleport-ent-fips package instead:

sudo apt-get install teleport-ent-fips

Source variables about OS version

source /etc/os-release

Add the Teleport YUM repository for v15. You'll need to update this

file for each major release of Teleport.

First, get the major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v15/teleport.repo")"
sudo yum install teleport-ent

Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs)

echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path

For FedRAMP/FIPS-compliant installations, install the teleport-ent-fips package instead:

sudo yum install teleport-ent-fips

Source variables about OS version

source /etc/os-release

Add the Teleport Zypper repository for v15. You'll need to update this

file for each major release of Teleport.

First, get the OS major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")

Use zypper to add the teleport RPM repo

sudo zypper addrepo --refresh --repo $(rpm --eval "https://zypper.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport-zypper.repo")
sudo yum install teleport-ent

Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs)

echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path

For FedRAMP/FIPS-compliant installations, install the teleport-ent-fips package instead:

sudo yum install teleport-ent-fips

Source variables about OS version

source /etc/os-release

Add the Teleport YUM repository for v15. You'll need to update this

file for each major release of Teleport.

First, get the major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")

Use the dnf config manager plugin to add the teleport RPM repo

sudo dnf config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v15/teleport.repo")"

Install teleport

sudo dnf install teleport-ent

Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs)

echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path

For FedRAMP/FIPS-compliant installations, install the teleport-ent-fips package instead:

sudo dnf install teleport-ent-fips

Source variables about OS version

source /etc/os-release

Add the Teleport Zypper repository.

First, get the OS major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")

Use Zypper to add the teleport RPM repo

sudo zypper addrepo --refresh --repo $(rpm --eval "https://zypper.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v15/teleport-zypper.repo")

Install teleport

sudo zypper install teleport-ent

For FedRAMP/FIPS-compliant installations, install the teleport-ent-fips package instead:

sudo zypper install teleport-ent-fips

In the example commands below, update $SYSTEM_ARCH with the appropriate value (amd64, arm64, or arm). All example commands using this variable will update after one is filled out.

curl https://cdn.teleport.dev/teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-bin.tar.gz.sha256

<checksum> <filename>

curl -O https://cdn.teleport.dev/teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-bin.tar.gz
shasum -a 256 teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-bin.tar.gz

Verify that the checksums match

tar -xvf teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-bin.tar.gz
cd teleport-ent
sudo ./install

For FedRAMP/FIPS-compliant installations of Teleport Enterprise, package URLs will be slightly different:

curl https://cdn.teleport.dev/teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-fips-bin.tar.gz.sha256

<checksum> <filename>

curl -O https://cdn.teleport.dev/teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-fips-bin.tar.gz
shasum -a 256 teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-fips-bin.tar.gz

Verify that the checksums match

tar -xvf teleport-ent-v15.1.10-linux-$SYSTEM_ARCH-fips-bin.tar.gz
cd teleport-ent
sudo ./install

OS repository channels

The following channels are available for APT, YUM, and Zypper repos. They may be used in place of stable/v15 anywhere in the Teleport documentation.

Channel nameDescription
stable/<major>Receives releases for the specified major release line, i.e. v15
stable/cloudRolling channel that receives releases compatible with current Cloud version
stable/rollingRolling channel that receives all published Teleport releases

Add the Teleport repository to your repository list:

Download Teleport's PGP public key

sudo curl https://apt.releases.teleport.dev/gpg \-o /usr/share/keyrings/teleport-archive-keyring.asc

Source variables about OS version

source /etc/os-release

Add the Teleport APT repository for cloud.

echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} stable/cloud" \| sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null

Provide your Teleport domain to query the latest compatible Teleport version

export TELEPORT_DOMAIN=example.teleport.com
export TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

Update the repo and install Teleport and the Teleport updater

sudo apt-get update
sudo apt-get install "teleport-ent=$TELEPORT_VERSION" teleport-ent-updater

Source variables about OS version

source /etc/os-release

Add the Teleport YUM repository for cloud.

First, get the OS major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport-yum.repo")"

Provide your Teleport domain to query the latest compatible Teleport version

export TELEPORT_DOMAIN=example.teleport.com
export TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

Install Teleport and the Teleport updater

sudo yum install "teleport-ent-$TELEPORT_VERSION" teleport-ent-updater

Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs)

echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path

Source variables about OS version

source /etc/os-release

Add the Teleport YUM repository for cloud.

First, get the OS major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")

Use the dnf config manager plugin to add the teleport RPM repo

sudo dnf config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport-yum.repo")"

Provide your Teleport domain to query the latest compatible Teleport version

export TELEPORT_DOMAIN=example.teleport.com
export TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

Install Teleport and the Teleport updater

sudo dnf install "teleport-ent-$TELEPORT_VERSION" teleport-ent-updater

Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs)

echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path

Source variables about OS version

source /etc/os-release

Add the Teleport Zypper repository for cloud.

First, get the OS major version from $VERSION_ID so this fetches the correct

package version.

VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+")

Use Zypper to add the teleport RPM repo

sudo zypper addrepo --refresh --repo $(rpm --eval "https://zypper.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport-zypper.repo")

Provide your Teleport domain to query the latest compatible Teleport version

export TELEPORT_DOMAIN=example.teleport.com
export TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

Install Teleport and the Teleport updater

sudo zypper install "teleport-ent-$TELEPORT_VERSION" teleport-ent-updater

OS repository channels

The following channels are available for APT, YUM, and Zypper repos. They may be used in place of stable/v15 anywhere in the Teleport documentation.

Channel nameDescription
stable/<major>Receives releases for the specified major release line, i.e. v15
stable/cloudRolling channel that receives releases compatible with current Cloud version
stable/rollingRolling channel that receives all published Teleport releases

Before installing a teleport binary with a version besides v15, read our compatibility rules to ensure that the binary is compatible with Teleport Enterprise Cloud.

Teleport uses Semantic Versioning. Version numbers include a major version, minor version, and patch version, separated by dots. When running multiple teleport binaries within a cluster, the following rules apply:

  • Patch and minor versions are always compatible, for example, any 8.0.1 component will work with any 8.0.3 component and any 8.1.0 component will work with any 8.3.0 component.
  • Servers support clients that are one major version behind, but do not support clients that are on a newer major version. For example, an 8.x.x Proxy Service instance is compatible with 7.x.x agents and 7.x.x tsh, but we don't guarantee that a 9.x.x agent will work with an 8.x.x Proxy Service instance. This also means you must not attempt to upgrade from 6.x.x straight to 8.x.x. You must upgrade to 7.x.x first.
  • Proxy Service instances and agents do not support Auth Service instances that are on an older major version, and will fail to connect to older Auth Service instances by default. You can override version checks by passing --skip-version-check when starting agents and Proxy Service instances.

Configure the Teleport Application Service

On the host where you will run the Teleport Application Service, create a file at /etc/teleport.yaml with the following content:

version: v3
teleport:
  join_params:
    token_name: "/tmp/token"
    method: token
  proxy_server: "teleport.example.com:443"
auth_service:
  enabled: off
proxy_service:
  enabled: off
ssh_service:
  enabled: off
app_service:
  enabled: true
  apps:
  - name: google-cloud-cli
    cloud: GCP

Edit /etc/teleport.yaml to replace teleport.example.com:443 with the host and port of your Teleport Proxy Service or Teleport Cloud tenant, e.g., mytenant.teleport.sh:443.

The app_service field configures the Teleport Application Service. Each item within app_service.apps is an application configuration.

In the example above, we have enabled Google Cloud CLI access by registering an application called google-cloud-cli with the cloud field set to GCP. The Teleport Application Service will forward requests to this application to Google Cloud.

Run the Teleport Application Service

On the host where you will run the Teleport Application Service, execute the following command, depending on whether you installed Teleport using a package manager or via a TAR archive:

Configure the Teleport Application Service to start automatically when the host boots up by creating a systemd service for it. The instructions depend on how you installed the Teleport Application Service.

On the host where you will run the Teleport Application Service, enable and start Teleport:

sudo systemctl enable teleport
sudo systemctl start teleport

On the host where you will run the Teleport Application Service, create a systemd service configuration for Teleport, enable the Teleport service, and start Teleport:

sudo teleport install systemd -o /etc/systemd/system/teleport.service
sudo systemctl enable teleport
sudo systemctl start teleport

You can check the status of the Teleport Application Service with systemctl status teleport and view its logs with journalctl -fu teleport.

Step 3/4. Enable your user to access Google Cloud CLIs

The next step is to authorize your Teleport user to access a target service account and execute Google Cloud CLI commands via Teleport. You will protect access to the service account using Teleport's RBAC system, where a user's roles determine which Google Cloud service accounts (if any) they can access.

There are two approaches you can take to authorize users to access Google Cloud service accounts:

ApproachDescriptionSupported User Types
DynamicA Teleport role includes a template variable that grants a user access to all Google Cloud service accounts assigned directly to them.Local users, OIDC, SAML
StaticA Teleport role explicitly specifies the Google Cloud service accounts a user is allowed to assume.Local users, OIDC, SAML, GitHub

We recommend using the dynamic approach, since it scales more easily as you add service accounts to your Google Cloud account. If you have configured an open source Teleport cluster to authenticate users via GitHub SSO, you must use the static approach, as OAuth-based GitHub applications do not support custom claims.

Approach

Create a file called google-cloud-cli-access.yaml with the following content:

kind: role
version: v7
metadata:
  name: google-cloud-cli-access
spec:
  allow:
    app_labels:
      '*': '*'
    gcp_service_accounts:
      - '{{internal.gcp_service_accounts}}'

When a user with the google-cloud-cli-access role authenticates to a Google Cloud CLI via Teleport, the Teleport Auth Service populates the {{internal.gcp_service_accounts}} template variable with any Google Cloud service accounts you have assigned to the user.

Assign the target service account we created earlier (or another service account) to your Teleport user by running the following command:

tctl users update teleport-user \--set-gcp-service-accounts teleport-vm-viewer@google-cloud-project.iam.gserviceaccount.com

This command uses the --set-gcp-service-accounts flag to add Google Cloud service accounts to a user. You can assign multiple service accounts to a user by setting --set-gcp-service-accounts to a comma-separated list of service account URIs.

Create the role:

tctl create -f google-cloud-cli-access.yaml

In your identity provider, define a custom SAML attribute or OIDC claim called gcp_service_accounts. Each user's gcp_service_accounts attribute or claim must be a list of Google Cloud service account URIs, using the following format:

<service_account_name>@<project_id>.iam.gserviceaccount.com

For example, you can set a user's gcp_service_accounts to teleport-vm-viewer by using the following URI, replacing <project_id> with the name of your Google Cloud project:

Create a file called google-cloud-cli-access.yaml with the following content:

kind: role
version: v7
metadata:
  name: google-cloud-cli-access
spec:
  allow:
    app_labels:
      '*': '*'
    gcp_service_accounts:
      - '{{external.gcp_service_accounts}}'

When a user with the google-cloud-cli-access role authenticates to a Google Cloud CLI via Teleport, the Teleport Auth Service populates the {{external.gcp_service_accounts}} template variable with any Google Cloud service accounts you have assigned to the user.

Create the role:

tctl create -f google-cloud-cli-access

Define a role with access to specific Google Cloud service accounts, which means that Teleport users who assume this role can use those (and only those) identities to execute commands via a Google Cloud CLI.

Create a file called google-cloud-cli-access.yaml with the following content, replacing my-project with the ID of your Google Cloud project in the value of gcp_service_accounts:

kind: role
version: v7
metadata:
  name: google-cloud-cli-access
spec:
  allow:
    app_labels:
      '*': '*'
    gcp_service_accounts:
      - [email protected]

This role grants a user access to any Teleport-registered application, such as the google-cloud-cli application we defined earlier, and allows that user to assume the teleport-vm-viewer service account you created earlier.

Create the role:

tctl create -f google-cloud-cli-access.yaml

You can define a Teleport role that denies a user access to one or more Google Cloud service accounts. To do so, assign values to the gcp_service_accounts field within the spec.deny section of a role resource.

For example, this role denies the user access to all Google Cloud service accounts:

kind: role
version: v7
metadata:
  name: "no-google-cloud"
spec:
  allow:
    app_labels:
      '*': '*'
  deny:
    gcp_service_accounts:
      - '*'

The no-google-cloud role enables the user to access all registered applications, but makes use of the wildcard character (*) within the deny.gcp_service_accounts field to prevent the user from assuming any Google Cloud service account.

Unlike values of allow.gcp_service_accounts, values of deny.gcp_service_accounts can include wildcard expressions in addition to the URIs of specific Google Cloud service accounts.

The Teleport Auth Service gives deny rules precedence over allow rules when evaluating a user's roles.

Assign the google-cloud-cli-access role to your Teleport user by running the appropriate commands for your authentication provider:

  1. Retrieve your local user's roles as a comma-separated list:

    ROLES=$(tsh status -f json | jq -r '.active.roles | join(",")')
  2. Edit your local user to add the new role:

    tctl users update $(tsh status -f json | jq -r '.active.username') \ --set-roles "${ROLES?},google-cloud-cli-access"
  3. Sign out of the Teleport cluster and sign in again to assume the new role.

  1. Retrieve your github authentication connector:

    tctl get github/github --with-secrets > github.yaml

    Note that the --with-secrets flag adds the value of spec.signing_key_pair.private_key to the github.yaml file. Because this key contains a sensitive value, you should remove the github.yaml file immediately after updating the resource.

  2. Edit github.yaml, adding google-cloud-cli-access to the teams_to_roles section.

    The team you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the team must include your user account and should be the smallest team possible within your organization.

    Here is an example:

      teams_to_roles:
        - organization: octocats
          team: admins
          roles:
            - access
    +       - google-cloud-cli-access
    
  3. Apply your changes:

    tctl create -f github.yaml
  4. Sign out of the Teleport cluster and sign in again to assume the new role.

  1. Retrieve your saml configuration resource:

    tctl get --with-secrets saml/mysaml > saml.yaml

    Note that the --with-secrets flag adds the value of spec.signing_key_pair.private_key to the saml.yaml file. Because this key contains a sensitive value, you should remove the saml.yaml file immediately after updating the resource.

  2. Edit saml.yaml, adding google-cloud-cli-access to the attributes_to_roles section.

    The attribute you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

    Here is an example:

      attributes_to_roles:
        - name: "groups"
          value: "my-group"
          roles:
            - access
    +       - google-cloud-cli-access
    
  3. Apply your changes:

    tctl create -f saml.yaml
  4. Sign out of the Teleport cluster and sign in again to assume the new role.

  1. Retrieve your oidc configuration resource:

    tctl get oidc/myoidc --with-secrets > oidc.yaml

    Note that the --with-secrets flag adds the value of spec.signing_key_pair.private_key to the oidc.yaml file. Because this key contains a sensitive value, you should remove the oidc.yaml file immediately after updating the resource.

  2. Edit oidc.yaml, adding google-cloud-cli-access to the claims_to_roles section.

    The claim you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

    Here is an example:

      claims_to_roles:
        - name: "groups"
          value: "my-group"
          roles:
            - access
    +       - google-cloud-cli-access
    
  3. Apply your changes:

    tctl create -f oidc.yaml
  4. Sign out of the Teleport cluster and sign in again to assume the new role.

Step 4/4. Use Google Cloud CLIs with Teleport

Now that you have started the Teleport Application Service and authorized your Teleport user to access Google Cloud CLIs, you can run Google Cloud CLI commands through Teleport.

List your Google Cloud CLI application

Verify that your Teleport user can see the google-cloud-cli application you registered earlier:

tsh apps ls
Application Description Type Public Address Labels---------------- ----------- ---- ------------------------------------- -------------------google-cloud-cli HTTP google-cloud-cli.teleport.example.com teleport.dev/origin

Log in to use a Google Cloud CLI

Log in to the application, specifying that you would like to assume the teleport-vm-viewer service account:

tsh apps login google-cloud-cli --gcp-service-account teleport-vm-viewer

This command validates the value of the --gcp-service-account flag against the ones the user is authorized to assume. The value of the flag can either be the full URI of the service account or the name of the identity, e.g., teleport-vm-viewer.

A user can omit the --gcp-service-account flag if they are only authorized to access a single Google Cloud service account, but otherwise an empty --gcp-service-account flag will result in an error.

If the command succeeds, you will see information about the user's chosen Google Cloud service account similar to the following:

Logged into GCP app "google-cloud-cli".
Your service account: [email protected]
Example command: tsh gcloud compute instances list

Execute Google Cloud CLI commands

At this point, you can run gcloud commands using the Teleport Application Service by prefixing them with tsh. Since your user authenticated to your Google Cloud CLI application with a service account that can list VMs, for example, run this command to do so:

tsh gcloud compute instances list

You should see a list of virtual machines in your Google Cloud project.

However, your Teleport user cannot create a VM, since its service account does not have this authorization:

tsh gcloud compute instances create another-instance --zone=google-cloud-zone
ERROR: (gcloud.compute.instances.create) Could not fetch resource: - Required 'compute.instances.create' permission for 'projects/my-project/zones/my-zone/instances/another-instance'
ERROR: exit status 1
Using gsutil with tsh

You can also use the google-cloud-cli application you registered with Teleport to run gsutil commands via the Teleport Application Service. As with gcloud, prefix a gsutil command with tsh in order to run it:

tsh gsutil ls

Use Google Cloud CLI applications without tsh

In addition to running gcloud and gsutil commands via tsh, you can grant secure access to any CLI application that executes commands against Google Cloud's APIs.

To do this, use tsh to start a local proxy that forwards traffic from your CLI application to the Teleport Application Service. The Application Service uses the teleport-google-cloud-cli service account we created earlier to fetch an authentication token from Google Cloud. Your CLI application uses this token to authenticate requests to Google Cloud's APIs.

To start the local proxy, run the following tsh command:

tsh proxy gcloud

The command will print the address of the local proxy server along with export commands for assigning environment variables. Google Cloud CLI applications read these variables in order to request an authentication token for Google Cloud's APIs:

Started GCP proxy on http://127.0.0.1:50614.
To avoid port randomization, you can choose the listening port using the --port flag.

Use the following credentials and HTTPS proxy setting to connect to the proxy:

  export BOTO_CONFIG=/Users/myuser/.tsh/gcp/teleport.example.com/google-cloud-cli/00000000_boto.cfg
  export CLOUDSDK_AUTH_ACCESS_TOKEN=00000000000000000000000000000000
  export CLOUDSDK_CONFIG=/Users/myuser/.tsh/gcp/teleport.example.com/google-cloud-cli/gcloud
  export CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE=/Users/myuser/.tsh/keys/teleport.example.com/myuser-google-cloud-cli/teleport.example.com/google-cloud-cli-localca.pem
  export CLOUDSDK_CORE_PROJECT=my-project
  export HTTPS_PROXY=http://127.0.0.1:50614

tsh proxy gcloud runs the local proxy in the foreground, so don't interrupt the process or exit the terminal where you ran the command until you're ready to close the local proxy.

Copy the export commands and paste them into a second terminal. In that terminal, you can now run your Google Cloud CLI application of choice. For example, you can run the following command to list Google Compute Engine VMs:

gcloud compute instances list

Recall that you could run gcloud iam service-accounts create in a shell earlier in this guide. After you enter the export commands printed by tsh proxy gcloud, this command runs as a restricted user, resulting in authorization issues:

gcloud iam service-accounts create demo-service-account
ERROR: (gcloud.iam.service-accounts.create) User [myuser] does not have permission to access projects instance [myproject] (or it may not exist): Permission 'iam.serviceAccounts.create' denied on resource (or it may not exist).- '@type': type.googleapis.com/google.rpc.ErrorInfo domain: iam.googleapis.com metadata: permission: iam.serviceAccounts.create reason: IAM_PERMISSION_DENIED

When you run a gcloud or gsutil command via tsh gcloud or tsh gsutil, tsh starts the local proxy in the background and uses it to execute the command.

Next steps

  • Now that you know how to protect access to Google Cloud CLIs using Teleport, ensure that your Teleport users can only manage Google Cloud resources temporarily, with no longstanding admin roles for attackers to hijack. View our documentation on Role Access Requests and Access Request plugins.
  • You can proxy any gcloud or gsutil command via Teleport. For a full reference of commands, view the Google Cloud documentation for gcloud and gsutil.
  • For full details on how Teleport populates the internal and external traits we illustrated in the Teleport roles within this guide, see the Teleport Access Controls Reference.