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

## How it works

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. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* 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](https://cloud.google.com/sdk/docs/install-sdk) 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 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, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  19.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](#enable-teleport-google-cloud-cli-to-impersonate-target-service-accounts).

---

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:

**New Virtual Machine**

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.

**Existing Virtual Machine**

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
```

---

WARNING

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
```

Assign join-token to your token and, on the host where you will install the Teleport Application Service, run the following command to 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.

To install a Teleport Agent on your Linux server:

The recommended installation method is the cluster install script. It will select the correct version, edition, and installation mode for your cluster.

1. Assign teleport.example.com:443 to your Teleport cluster hostname and port, but not the scheme (https\://).

2. Run your cluster's install script:

   ```
   $ curl "https://teleport.example.com:443/scripts/install.sh" | sudo bash
   ```

### 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: false
proxy_service:
  enabled: false
ssh_service:
  enabled: false
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.

**Package Manager**

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

```
$ sudo systemctl enable teleport
$ sudo systemctl start teleport
```

**TAR Archive**

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:

| Approach    | Description                                                                                                                            | Supported User Types            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| **Dynamic** | A 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         |
| **Static**  | A 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.

---

### Dynamic identities

If you are using dynamic identities, the approach you choose depends on whether you use local or SSO Teleport users:

**Local Users**

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, setting teleport-user to the name of your Teleport user:

```
$ 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
```

---

TIP

You can also create and edit roles using the Web UI. Go to **Access -> Roles** and click **Create New Role** or pick an existing role to edit.

---

**SAML/OIDC Connectors**

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:

```
teleport-vm-viewer@my-project.iam.gserviceaccount.com

```

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.yaml
```

---

TIP

You can also create and edit roles using the Web UI. Go to **Access -> Roles** and click **Create New Role** or pick an existing role to edit.

---

### Static identities

If you are using static identities, complete the following instructions.

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

```

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
```

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:

**Local User**

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.

**GitHub**

1. Open your `github` authentication connector in a text editor:

   ```
   $ tctl edit github/github
   ```

2. Edit the `github` connector, 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 by saving and closing the file in your editor.

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**SAML**

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.

**OIDC**

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: 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
```

### Use Google Cloud CLI applications without `tsh`

In addition to running `gcloud` 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` command via `tsh gcloud`, `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](https://goteleport.com/docs/identity-governance/access-requests/role-requests.md) and [Access Request plugins](https://goteleport.com/docs/identity-governance/access-requests/plugins.md).
- You can proxy any `gcloud` command via Teleport. For a full reference of commands, view the Google Cloud documentation for [`gcloud`](https://cloud.google.com/sdk/gcloud/reference).
- For full details on how Teleport populates the `internal` and `external` traits we illustrated in the Teleport roles within this guide, see the [Access Controls Reference](https://goteleport.com/docs/reference/access-controls/roles.md).
- After following this guide, you can also secure usage of the legacy `gsutil` command with Teleport. Users can execute `gsutil` commands with `tsh gsutil`. For more information, see the `tsh gsutil` entry in the [CLI Reference](https://goteleport.com/docs/reference/cli/tsh.md#tsh-gsutil).
