Skip to main content

Protect Google Cloud API Access with Teleport

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 version 17.0.0-dev or above. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl admin tool and tsh client tool.

    Visit Installation for instructions on downloading tctl and tsh.

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

    tip

    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. For example:
    $ tsh login --proxy=teleport.example.com --user=email@example.com
    $ tctl status
    # Cluster teleport.example.com
    # Version 17.0.0-dev
    # 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"

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

tip

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:

tip

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.

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.

Install Teleport on your Linux server:

  1. Assign edition to one of the following, depending on your Teleport edition:

    EditionValue
    Teleport Enterprise Cloudcloud
    Teleport Enterprise (Self-Hosted)enterprise
    Teleport Community Editionoss
  2. Get the version of Teleport to install. If you have automatic agent updates enabled in your cluster, query the latest Teleport version that is compatible with the updater:

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

    Otherwise, get the version of your Teleport cluster:

    $ TELEPORT_DOMAIN=example.teleport.com
    $ TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/ping | jq -r '.server_version')"
  3. Install Teleport on your Linux server:

    $ curl https://cdn.teleport.dev/install-v15.4.11.sh | bash -s ${TELEPORT_VERSION} edition

    The installation script detects the package manager on your Linux server and uses it to install Teleport binaries. To customize your installation, learn about the Teleport package repositories in the installation guide.

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

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
tip

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.

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
Denying access to Google Cloud service accounts

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.

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: teleport-vm-viewer@my-project.iam.gserviceaccount.com
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
warning

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
info

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.