> For the complete documentation index, see [llms.txt](https://docs.carto.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.carto.com/carto-self-hosted/configuration/security/cloud-identities/use-workload-identity-in-gcp.md).

# Use Workload Identity in GCP

## What is Workload Identity?

Applications running on Google Kubernetes Engine might need access to Google Cloud APIs such as Compute Engine API, BigQuery API, or Storage APIs.

Workload Identity allows a Kubernetes service account in your GKE cluster to act as an IAM service account. Pods that use the configured Kubernetes service account automatically authenticate as the IAM service account when accessing Google Cloud APIs. **Using Workload Identity allows you to assign distinct, fine-grained identities and authorization for each application in your cluster**.

{% hint style="info" %}
Enabling Workload Identity in your Self-Hosted installation is **just available for the orchestrated container deployment** of CARTO.
{% endhint %}

## How does Workload Identity work?

When you enable Workload Identity on a cluster, GKE automatically creates a fixed workload identity pool for the cluster's Google Cloud project. A workload identity pool allows IAM to understand and trust Kubernetes service account credentials. GKE uses this pool for all clusters in the project that use Workload Identity. The workload identity pool has the following format:

`PROJECT_ID.svc.id.goog`

When you configure a Kubernetes service account in a namespace to use Workload Identity, IAM authenticates the credentials using the following member name:

`serviceAccount:PROJECT_ID.svc.id.goog[KUBERNETES_NAMESPACE/KUBERNETES_SERVICE_ACCOUNT]`

In this member name:

* `PROJECT_ID`: your Google Cloud project ID.
* `KUBERNETES_NAMESPACE`: the namespace of the Kubernetes service account.
* `KUBERNETES_SERVICE_ACCOUNT`: the name of the Kubernetes service account making the request.

The process of configuring Workload Identity includes using an IAM policy binding to bind the Kubernetes service account member name to an IAM service account that has the permissions your workloads need. Any Google Cloud API calls from workloads that use this Kubernetes service account are authenticated as the bound IAM service account.

## Configure CARTO deployment to use Workload Identity

In order to enable Workload Identity in your CARTO Self-Hosted installation, you'll have to follow these steps:

1. **Create an IAM service account for your application**, or use an existing IAM service account instead.

{% tabs %}
{% tab title="gcloud" %}

```bash
gcloud iam service-accounts create {IAM_SERVICE_ACCOUNT_NAME} \
    --project={PROJECT_ID}
```

* `IAM_SERVICE_ACCOUNT_NAME`: name of the new service account.
* `PROJECT_ID`: ID of the project where the GKE cluster is deployed.

Service Account needs `roles/iam.serviceAccountTokenCreator` role to sign URLs, you can grant it with this command:

```bash
gcloud iam service-accounts add-iam-policy-binding \
  {IAM_SERVICE_ACCOUNT_EMAIL} \
  --member=serviceAccount:{IAM_SERVICE_ACCOUNT_EMAIL} \
  --role=roles/iam.serviceAccountTokenCreator
```

* `IAM_SERVICE_ACCOUNT_NAME`: name of the new service account used in previous step
* `IAM_SERVICE_ACCOUNT_EMAIL`: email of the service account generated with the previous command.
  {% endtab %}
  {% endtabs %}

**2.** **Send email to CARTO Support Team** <support@carto.com> with the **Service Account email**

Reach out to our CARTO support team and provide them with the email associated with the Service Account you've created. This step ensures seamless integration of your Service Account with your CARTO Self-Hosted deployment. Email CARTO Support Team <support@carto.com> with the service account email.

{% hint style="danger" %}
**IMPORTANT**: The provided Service Account will not work unless the CARTO support team has been notified and they proceed with the grants mentioned above. You cannot change the Service Account without contacting support.
{% endhint %}

3. Configure the Kubernetes service account for Workload Identity:

{% tabs %}
{% tab title="Kots" %} <img src="/files/iX0yYSxrIcdJH0mbRf9w" alt="Kots" width="18">

Create the Kubernetes service account used for Workload Identity:

Use the following command to generate the service account in your cluster:

```
kubectl create serviceaccount {SERVICE_ACCOUNT_NAME} \
    --namespace={NAMESPACE}
```

* `SERVICE_ACCOUNT_NAME`: name of the service account that will be generated in your namespace. You'll have to provide that name when configuring CARTO platform.
* `NAMESPACE`: namespace where you're deploying CARTO Self-Hosted platform.

Once your service account is created in your kubernetes cluster, you'll have to annotate it with the email of the service account that you genereated in your GCP project:

```
kubectl annotate serviceaccount {SERVICE_ACCOUNT_NAME} \
    --namespace {NAMESPACE} \
    iam.gke.io/gcp-service-account={GCP_SERVICE_ACCOUNT_EMAIL}
```

* `SERVICE_ACCOUNT_NAME`: name of the service account that will be generated in your namespace.
* `NAMESPACE`: namespace where you're deploying CARTO Self-Hosted platform.
* `GCP_SERVICE_ACCOUNT_EMAIL`: email of the service account that you created in your GCP project.
  {% endtab %}

{% tab title="Helm" %} <img src="/files/5mQydBQdQ20MZUxbcOKQ" alt="Helm" width="18">

Add the following lines to your <mark style="color:orange;">customizations.yaml</mark> file:

```yaml
commonBackendServiceAccount:
  enableGCPWorkloadIdentity: true
  annotations:
    iam.gke.io/gcp-service-account: "{IAM_SERVICE_ACCOUNT_EMAIL}"
```

* `IAM_SERVICE_ACCOUNT_EMAIL`: email of the service account generated in the first step.

{% hint style="info" %}
The chart gives the possibility of disabling `commonBackendServiceAccount` account creation with `commonBackendServiceAccount.create: false` but you'll have to provide the name of your service account with `name: "{K8S_SERVICE_ACCOUNT_NAME}"`
{% endhint %}
{% endtab %}
{% endtabs %}

**4.** Allow the Kubernetes service account that is going to be created in your GKE cluster to impersonate the IAM service account by adding an IAM policy binding between the two service accounts. This binding allows the Kubernetes service account to act as the IAM service account.

{% tabs %}
{% tab title="gcloud" %}

```bash
gcloud iam service-accounts add-iam-policy-binding {IAM_SERVICE_ACCOUNT_EMAIL} \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:{PROJECT_ID}.svc.id.goog[{KUBERNETES_NAMESPACE}/{KUBERNETES_SERVICE_ACCOUNT}]"
```

* `IAM_SERVICE_ACCOUNT_EMAIL`: email of the service account generated in the first step.
* `PROJECT_ID`: ID of the project where the GKE cluster is deployed.
* `KUBERNETES_NAMESPACE`: namespace where CARTO application is deployed.
* `KUBERNETES_SERVICE_ACCOUNT`: name of the kubernetes service account used by CARTO application. Default value is `carto-common-backend`.

{% hint style="info" %}
You can find the `gcloud` command with the `KUBERNETES_NAMESPACE` and `KUBERNETES_SERVICE_ACCOUNT` values in the helm output notes once you execute the installation process.
{% endhint %}
{% endtab %}
{% endtabs %}

**5.** Add the workload identity service account name to your deployment:

{% tabs %}
{% tab title="Kots" %} <img src="/files/iX0yYSxrIcdJH0mbRf9w" alt="Kots" width="18">

In the Admin Console → Config → **Advanced Config** section:

1. Enable **Google Workload Identity** (toggle on)
2. Enter the **Kubernetes workload identity service account name** — use the name of the K8s service account you created in step 3
3. Click **Save config** → **Deploy**

<figure><img src="/files/UUUlkiKTo7Kol6r89k3I" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The **Kubernetes workload identity service account name** field appears only after **Google Workload Identity** is enabled.
{% endhint %}
{% endtab %}

{% tab title="Helm" %} <img src="/files/5mQydBQdQ20MZUxbcOKQ" alt="Helm" width="18">

This step is handled automatically through the `commonBackendServiceAccount` configuration in the <mark style="color:orange;">customizations.yaml</mark> file from step 3.
{% endtab %}
{% endtabs %}

## Create a BigQuery connection managed using Workload Identity

CARTO Self-Hosted running on a GKE cluster can take advantage of GKE Workload Identity feature to create a connection between the CARTO Self-Hosted platform and BigQuery without any user action.

### Configuration

1. Setup GKE Workload Identity for CARTO Self-Hosted following the [documentation](#configure-carto-deployment-to-use-workload-identity).
2. Grant your Workload Identity service account with BigQuery [required permissions](/carto-user-manual/connections/required-permissions.md) to your data warehouse project.
3. Enable the BigQuery workload identity connection in your deployment:

{% tabs %}
{% tab title="Kots" %} <img src="/files/iX0yYSxrIcdJH0mbRf9w" alt="Kots" width="18">

In the Admin Console → Config → **Advanced Config** section (with **Google Workload Identity** already enabled), fill in the following fields:

1. Enable **BigQuery workload identity** (toggle on)
2. **Workflows temporary location** — BigQuery dataset for storing temp tables (e.g., `my_gcp_project.my_dataset`)
3. **Google billing project** — GCP project to be charged with BigQuery costs
4. **CARTO connection owner id** — ID of the CARTO user who will own the connection (e.g., `auth0|3idsj230990sj4wsddd10`)

{% hint style="info" %}
The service account email used for the BigQuery connection is taken automatically from your Workload Identity configuration — you do not enter it separately here.
{% endhint %}

<figure><img src="/files/aW5VPqyW8jOrdugEGQ20" alt=""><figcaption></figcaption></figure>

The **CARTO connection owner id** can be obtained by running the following `curl` command:

```
curl -s 'https://accounts.app.carto.com/users/me' \
  -H 'Authorization: Bearer <your_carto_jwt_token>' \
  | jq '.user_id'
```

{% endtab %}

{% tab title="Helm" %} <img src="/files/5mQydBQdQ20MZUxbcOKQ" alt="Helm" width="18">

Add the following environment variables in your <mark style="color:orange;">customizations.yaml</mark> file:

```yaml
workspaceApi:
  extraEnvVars:
    - name: WORKSPACE_SYNC_DATA_ENABLED
      value: "true"
    - name: WORKSPACE_WORKLOAD_IDENTITY_WORKFLOWS_TEMP
      value: {WORKFLOWS_TEMP_LOCATION}
    - name: WORKSPACE_WORKLOAD_IDENTITY_BILLING_PROJECT
      value: {BILLING_PROJECT_ID}
    - name: WORKSPACE_WORKLOAD_IDENTITY_SERVICE_ACCOUNT_EMAIL
      value: {WORKLOAD_IDENTITY_SA_EMAIL}
    - name: WORKSPACE_WORKLOAD_IDENTITY_CONNECTION_OWNER_ID
      value: {CARTO_OWNER_ID}
workspaceSubscriber:
  extraEnvVars:
    - name: WORKSPACE_SYNC_DATA_ENABLED
      value: "true"
    - name: WORKSPACE_WORKLOAD_IDENTITY_WORKFLOWS_TEMP
      value: {WORKFLOWS_TEMP_LOCATION}
    - name: WORKSPACE_WORKLOAD_IDENTITY_BILLING_PROJECT
      value: {BILLING_PROJECT_ID}
    - name: WORKSPACE_WORKLOAD_IDENTITY_SERVICE_ACCOUNT_EMAIL
      value: {WORKLOAD_IDENTITY_SA_EMAIL}
    - name: WORKSPACE_WORKLOAD_IDENTITY_CONNECTION_OWNER_ID
      value: {CARTO_OWNER_ID}
```

* `WORKFLOWS_TEMP_LOCATION`: BigQuery dataset ID used for storing temporary tables (i.e. `my_gcp_project.my_dataset`).
* `BILLING_PROJECT_ID`: GCP project to be charged with the BigQuery costs.
* `WORKLOAD_IDENTITY_SA_EMAIL`: Service account email configured for Workload Identity.
* `CARTO_OWNER_ID`: ID of the CARTO user who will be the owner of the connection (i.e. `"auth0|3idsj230990sj4wsddd10"`). This can be obtained by running the following `curl` command:

  ```
  curl -s 'https://accounts.app.carto.com/users/me' \
    -H 'Authorization: Bearer <your_carto_jwt_token>' \
    | jq '.user_id'
  ```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Helm" %} <img src="/files/5mQydBQdQ20MZUxbcOKQ" alt="Helm" width="18">

4. Follow the previous command output and grant the service account the following role:

```bash
gcloud iam service-accounts add-iam-policy-binding \
  {WORKLOAD_IDENTITY_SA_EMAIL} \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:{PROJECT_ID}.svc.id.goog[{KUBERNETES_NAMESPACE}/carto-common-backend]" \
  --project {PROJECT_ID}
```

* `WORKLOAD_IDENTITY_SA_EMAIL`: Service account email configured for Workload Identity.
* `PROJECT_ID`: ID of the project where the GKE cluster is deployed.
* `KUBERNETES_NAMESPACE`: namespace where CARTO application is deployed.
  {% endtab %}
  {% endtabs %}

Once you've applied the changes performed in your <mark style="color:orange;">customizations.yaml</mark> file, your CARTO deployment will automatically create a new BigQuery connection using Workload Identity owned by the CARTO user specified in the deployment configuration!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.carto.com/carto-self-hosted/configuration/security/cloud-identities/use-workload-identity-in-gcp.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
