> ## Documentation Index
> Fetch the complete documentation index at: https://www.truefoundry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authenticate To GCP Using IAM Serviceaccount

> Step-by-step guide for authenticate to gcp using iam serviceaccount, explaining configuration, best practices, and real-world usage on…

In Google Kubernetes Engine (GKE), applications leverage Workload Identity to securely connect with Google Cloud Platform (GCP) services through IAM service accounts. This seamless integration enables fine-grained access control and eliminates the need for managing credentials within the application code, enhancing both security and operational efficiency in the GKE environment.

## Step 1 (A) - Pre-requisites

1. Export important variables

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     export PROJECT_ID=""
     export CLUSTER_NAME=""
     export GKE_REGION=""
     ```
   </CodeGroup>

2. Authenticate using `gcloud`

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     gcloud auth login
     ```
   </CodeGroup>

3. Set your project ID

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     gcloud config set project $PROJECT_ID
     ```
   </CodeGroup>

## Step 1 (B) - Enabling workload identity for your cluster

Workload identity needs to be enabled for your GKE cluster so that pods can leverage this to authenticate to GCP services without credentials.

1. If workload identity is not enabled for your GKE cluster, run the below command to enable it

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     gcloud container clusters update $CLUSTER_NAME \
         --region=$GKE_REGION \
         --workload-pool=$PROJECT_ID.svc.id.goog
     ```
   </CodeGroup>

2. The above step will enable workload identity only in the new node pool. To enable the workload identity in the existing node pool

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     gcloud container node-pools create <NODEPOOL_NAME> \
         --cluster=$CLUSTER_NAME \
         --region=$GKE_REGION \
         --workload-metadata=GKE_METADATA
     ```
   </CodeGroup>

## Step 2 - Create a kubernetes workspace

1. Export the namespace and the `serviceaccount `. TrueFoundry's workspace is analogous to Kubernetes namespace.

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     export APP_NS=""
     export APP_SA=""
     ```
   </CodeGroup>

2. Go to Workspaces tab from the left panel of the portal and create the workspace with same name as of your namespace \$APP\_NS

   1. Click on `+ New Workspace` to create a new workspace. If you already have a workspace created click on the **Edit** section from the right side of the workspace card.
   2. Select the cluster where you want to create the serviceaccount and enter the name of the workspace (namespace).
      <Frame caption="">
        <img src="https://mintcdn.com/truefoundry/FrY4JbiyZud2He3p/images/1f453b52-ecc2450-creating-workspace.png?fit=max&auto=format&n=FrY4JbiyZud2He3p&q=85&s=7f12d8a2ffdd4a555c6d87287178e201" width="1362" height="1026" data-path="images/1f453b52-ecc2450-creating-workspace.png" />
      </Frame>

## Step 3 - Create IAM serviceaccount in GCP

In this section we will create an IAM `serviceaccount` which has access to buckets. We will try to use this to access the bucket files in GCP

1. Export these variables and enter the name of the google serviceaccount you want to give in the variable `GSA_NAME`. We are assigning this serviceaccount Storage admin permission. You can assign the permissions that you want for accessing your GCP application.

   <CodeGroup>
     ```shell Shell lines theme={"dark"}
     # google serviceaccount
     export GSA_NAME=""
     export ROLE_NAME="roles/storage.admin"
     ```
   </CodeGroup>

2. Create the IAM serviceaccount and assign the role using the below command. We are also assigning `roles/iam.workloadIdentityUser` role to the IAM serviceaccount on itself so that it can be accessed from inside GKE.

   <CodeGroup>
     ```powershell Shell lines theme={"dark"}
     # creating the IAM serviceaccount
     gcloud iam service-accounts create $GSA_NAME \
         --project=$PROJECT_ID

     # assigning the role
     gcloud projects add-iam-policy-binding $PROJECT_ID \
         --member "serviceAccount:$GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
         --role "$ROLE_NAME"

     # assign the roles/iam.workloadIdentityUser
     gcloud iam service-accounts add-iam-policy-binding $GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
         --role roles/iam.workloadIdentityUser \
         --member "serviceAccount:$PROJECT_ID.svc.id.goog[$APP_NS/$APP_SA]"
     ```
   </CodeGroup>

<Warning>
  ### The policy contains bindings with conditions

  When you are trying to run the command `gcloud projects add-iam-policy-binding` you might get the below output

  <CodeGroup>
    ```shell Shell lines theme={"dark"}
    Created service account [test-iam-sa].
     [1] EXPRESSION=resource.name.startsWith("projects/_/buckets/xxxxxxxx"), TITLE=xxxxxxx Admin
     [2] None
     [3] Specify a new condition
    The policy contains bindings with conditions, so specifying a condition is required when adding a binding. Please specify a condition.:
    ```
  </CodeGroup>

  You can enter a condition if you want to restrict the GCP IAM serviceaccount to a certain bucket or you can use option 2 and continue.
</Warning>

## Step 4 - Create Kubernetes Serviceaccount in your workspace

1. Go to Workspaces tab from the left panel of the portal and click on the pencil icon to edit your workspace.

2. Click on `Show Advanced fields` on bottom of the screen and enable `Service accounts` field.

3. Click on `+ Add Service Accounts` to add a Serviceaccount

   1. Enter the name of your Kubernetes Serviceaccount which is in the variable \$APP\_SA
   2. Enter the IAM Serviceaccount name which will be `$GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com`

      <CodeGroup>
        ```shell Shell lines theme={"dark"}
        # run this command to get your IAM serviceaccount name
        echo $GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com
        ```
      </CodeGroup>

4. Click on update to continue\\
   <Frame caption="">
     <img src="https://mintcdn.com/truefoundry/4MAaF__cLD4iud16/images/56b2f0ec-9e7dcf6-gke-k8a-serviceaccount.png?fit=max&auto=format&n=4MAaF__cLD4iud16&q=85&s=2621611db452f0cf9e9c6800fe65e62b" width="1524" height="764" data-path="images/56b2f0ec-9e7dcf6-gke-k8a-serviceaccount.png" />
   </Frame>

## Test the `serviceaccount`

1. Create the below pod

   <CodeGroup>
     ```powershell Shell lines theme={"dark"}
     kubectl apply -f -<<EOF
     apiVersion: v1
     kind: Pod
     metadata:
       name: workload-identity-test
       namespace: $APP_NS
     spec:
       containers:
       - image: google/cloud-sdk:slim
         name: workload-identity-test
         command: ["sleep","infinity"]
       serviceAccountName: $APP_SA
       nodeSelector:
         iam.gke.io/gke-metadata-server-enabled: "true"
     EOF
     ```
   </CodeGroup>

2. Check if you are able to list buckets without passing creds

   <CodeGroup>
     ```bash Shell lines theme={"dark"}
     kubectl exec -it workload-identity-test -n $APP_NS -- gcloud storage ls
     ```
   </CodeGroup>
