# GKE Workload Identity

Google Cloud supports [mapping Kubernetes service accounts to Google Cloud IAM service accounts](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) using a feature called [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation).

### Objective

Bindplane requires access to Google Pub/Sub when operating in [High Availability](https://app.gitbook.com/s/gmiOMzBfoNFwmKJFHMcJ/production-checklist/bindplane/high-availability) using a multi-replica [Deployment](https://app.gitbook.com/s/gmiOMzBfoNFwmKJFHMcJ/deployment/kubernetes/server/installation).

Bindplane can authenticate to Pub/Sub using [OAuth Scopes](https://developers.google.com/identity/protocols/oauth2/scopes) or with [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation).\
This guide will focus on how to configure workload identity.

### Prerequisites

You must have access to a Google Kubernetes Engine cluster with workload identity enabled. GKE Autopilot has workload identity enabled by default.

### Configuration

Review the [Configure applications to use Workload Identity Federation for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#authenticating_to) instructions.

If you deploy Bindplane to a cluster without the Pub/Sub OAUTH scopes, you can expect to see the following error logs:

```json
{
  "level": "error",
  "timestamp": "2024-04-25T18:49:15.243Z",
  "message": "failed to build server during server startup",
  "error": "failed to init eventbus: create topic: check topic: rpc error: code = PermissionDenied desc = User not authorized to perform this action."
}
```

This is because the Kubernetes service account has not been mapped to IAM.

#### Kubernetes Service Account

The [Bindplane Helm Chart](https://github.com/observIQ/bindplane-op-helm) creates service accounts for you. The name of the service account is derived from the name of your Helm deployment.

You can find your service account with `kubectl -n <namespace> get sa`.

```bash
$ kubectl -n default get sa

NAME        SECRETS   AGE
bindplane   0         12m
default     0         19m
```

```bash
$ kubectl -n default get sa bindplane -o yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    meta.helm.sh/release-name: bindplane
    meta.helm.sh/release-namespace: default
  labels:
    app.kubernetes.io/instance: bindplane
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: bindplane
    app.kubernetes.io/stack: bindplane
  name: bindplane
  namespace: default
```

All pods deployed by the Helm chart will use this service account.

#### IAM Mapping

Step 4 in [Configure applications to use Workload Identity Federation for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#authenticating_to) instructs you to create an IAM policy binding that binds the Kubernetes service account to your project's IAM.

```bash
gcloud projects add-iam-policy-binding projects/PROJECT_ID \
    --role=roles/pubsub.admin \
    --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME \
    --condition=None
```

#### Restart Bindplane

If you previously deployed Bindplane, and the pods are crashing due to Pub/Sub permission errors, restart the pods by deleting them or using the `kubectl rollout restart` command.

Once the new pods are started, they will not return Pub/Sub errors if the workload identity\
mapping was successful.

### Resources

* [Bindplane Helm Chart](https://github.com/observIQ/bindplane-op-helm)
* [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation)
* [Workload Identity How To](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)


---

# Agent Instructions: 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:

```
GET https://docs.bindplane.com/how-to-guides/cloud-and-platform-integrations/kubernetes/gke-workload-identity.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
