# Connect the Google SecOps Integration with WIF Auth

This guide explains how to configure your Google SecOps instance for secure communication w/ Bindplane using **Workload Identity Federation (WIF).** Allowing for authentication without having to share long-lived service account keys.

[Read more about Workload Identity Federation](https://docs.cloud.google.com/iam/docs/workload-identity-federation)

{% hint style="warning" %}
WIF Authentication for the Google SecOps Integration is only supported in Bindplane Cloud.\
It is not supported for self-hosted Bindplane instances.
{% endhint %}

***

### Overview

At a high level, you will:

1. [Create a Service Account](#id-1.-create-a-service-account)
   1. [Configure Service Account Permissions](#id-1a.-configure-service-account-permissions)
2. [Create a Workload Identity Pool](#id-2.-create-a-workload-identity-pool)
3. [Create a Workload Identity Provider (OIDC)](#id-3.-create-a-workload-identity-provider-oidc)
4. [Allow Service Account Impersonation](#id-4.-allow-service-account-impersonation)
5. [Configure the Google SecOps Integration in Bindplane](#id-5.-configure-the-google-secops-integration-in-bindplane)

{% hint style="info" %}
It is highly recommended to use the **gcloud CLI** to perform these actions.
{% endhint %}

***

### Prerequisites

You will need:

* A Bindplane Cloud project with support for the Google SecOps Integration
  * This requires one of the following Bindplane plans:
    * Enterprise
    * Enterprise (Google Edition)
    * Google Edition
* Your Google SecOps instance must be enabled for the "Data Processing Preview"
  * Contact your Google SecOps Account Manager for more information or to get enabled
* The **Bindplane Project ID** of the project where you want to setup the Google SecOps Integration
  * Find this value on the Support page by clicking the blue question mark button on the bottom right of Bindplane
* The **GCP Project Number** of your Google SecOps instance.
  * Find this value in Google SecOps at Settings -> Profile -> Organization Details.
* Access to create and modify the following resources in the above GCP Project
  * Service Accounts
  * Workload Identity Pools
  * Workload Identity Providers

{% hint style="warning" %}
Perform all the below commands in the same terminal session in order to persist variables
{% endhint %}

***

### **0. Set Up Variables**

Replace the placeholder values below with your **Bindplane Project ID** and **GCP Project Number** and run the commands to set up variables to be used later.

```bash
BP_PROJECT_ID=<YOUR_BINDPLANE_PROJECT_ID>
GCP_PROJECT_NUMBER=<YOUR_GCP_PROJECT_NUMBER>
# Automatically populate the GCP_PROJECT_ID variable
GCP_PROJECT_ID=$(gcloud projects describe $GCP_PROJECT_NUMBER --format="value(projectId)")
```

***

### 1. Create a Service Account

This service account will be impersonated using Workload Identity Federation.

{% hint style="info" %}
Replace `<YOUR_SA_NAME>` below with a descriptive name for your new service account
{% endhint %}

```bash
SA_EMAIL=$(gcloud iam service-accounts create <YOUR_SA_NAME> \
  --project=$GCP_PROJECT_ID \
  --description="Service account for the Bindplane Google SecOps Integration" \
  --display-name="Bindplane Google SecOps Integration WIF" \
  --format="value(email)")
```

***

#### 1a. Configure Service Account Permissions

Per [Google's Documentation](https://docs.cloud.google.com/chronicle/docs/ingestion/data-processing-pipeline#prerequisites), the service account must be configured with the proper permissions in order to manage Google SecOps resources. This can be done using a custom role, or with the Chronicle API Admin role.

Below are commands for each approach.

#### Option 1 (Preferred) - Custom Role

* Create Custom Role

{% hint style="info" %}
Replace `<YOUR_ROLE_NAME>` in the command below with any descriptive name
{% endhint %}

```bash
CUSTOM_SECOPS_ROLE=$(gcloud iam roles create <YOUR_ROLE_NAME> \
  --project=$GCP_PROJECT_ID \
  --title="Custom Bindplane SecOps Integration Role" \
  --permissions="\
chronicle.logProcessingPipelines.associateStreams,\
chronicle.logProcessingPipelines.create,\
chronicle.logProcessingPipelines.delete,\
chronicle.logProcessingPipelines.dissociateStreams,\
chronicle.logProcessingPipelines.fetchAssociatedPipeline,\
chronicle.logProcessingPipelines.fetchSampleLogsByStreams,\
chronicle.logProcessingPipelines.get,\
chronicle.logProcessingPipelines.list,\
chronicle.logProcessingPipelines.testPipeline,\
chronicle.logProcessingPipelines.update,\
chronicle.logTypes.get,\
chronicle.logTypes.list,\
chronicle.feeds.get,\
chronicle.feeds.list,\
chronicle.logs.list" \
  --stage="GA" \
  --format="value(name)")
```

* Bind Custom Role to Service Account

```bash
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="${CUSTOM_SECOPS_ROLE}"
```

#### Option 2 - Chronicle Admin Role

```bash
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/chronicle.admin"
```

***

### 2. Create a Workload Identity Pool

The Workload Identity Pool represents a trust boundary for external identities (Auth0).

[Read more about WIF Pools](https://docs.cloud.google.com/iam/docs/workload-identity-federation#pools)

{% hint style="info" %}
Replace `<YOUR_POOL_ID>` with a descriptive name for your pool that fits the constraints set by Google.

[Read more](https://docs.cloud.google.com/iam/docs/reference/rest/v1/projects.locations.workloadIdentityPools/create#query-parameters)
{% endhint %}

```bash
WIF_POOL_ID=<YOUR_POOL_ID>
gcloud iam workload-identity-pools create $WIF_POOL_ID \
  --project=$GCP_PROJECT_ID \
  --location="global" \
  --display-name="Bindplane SecOps WIF Pool"
```

***

### 3. Create a Workload Identity Provider (OIDC)

The provider validates tokens issued by Bindplane’s Auth0 tenant.

The attribute mapping and condition ensure that only tokens issued for your specific Bindplane project are allowed to impersonate the service account.

Read more about [WIF Providers](https://docs.cloud.google.com/iam/docs/workload-identity-federation#providers), [Attribute Mappings](https://docs.cloud.google.com/iam/docs/workload-identity-federation#mapping), and [Attribute Conditions](https://docs.cloud.google.com/iam/docs/workload-identity-federation#conditions)

{% hint style="info" %}
Replace `<YOUR_PROVIDER_ID>` with a descriptive name for your pool that fits the constraints set by Google.

[Read more](https://docs.cloud.google.com/iam/docs/reference/rest/v1/projects.locations.workloadIdentityPools.providers/create#query-parameters)
{% endhint %}

```bash
WIF_PROVIDER_ID=<YOUR_PROVIDER_ID>
gcloud iam workload-identity-pools providers create-oidc $WIF_PROVIDER_ID \
  --project=$GCP_PROJECT_ID \
  --location="global" \
  --workload-identity-pool=$WIF_POOL_ID \
  --issuer-uri="https://auth0.app.bindplane.com" \
  --allowed-audiences="https://auth0.app.bindplane.com/secops-wif" \
  --attribute-mapping="google.subject=assertion.sub,attribute.project_id=assertion['https://auth0.app.bindplane.com/project_id']" \
  --attribute-condition="attribute.project_id=='${BP_PROJECT_ID}'"
```

***

### 4. Allow Service Account Impersonation

Grant the Workload Identity Pool permission to impersonate the service account.

[Read more about Service Account Impersonation](https://docs.cloud.google.com/iam/docs/workload-identity-federation#impersonation)

```bash
gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \
  --project=$GCP_PROJECT_ID \
  --role="roles/iam.serviceAccountTokenCreator" \
  --member="principalSet://iam.googleapis.com/projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${WIF_POOL_ID}/attribute.project_id/${BP_PROJECT_ID}"
```

***

### 5. Configure the Google SecOps Integration in Bindplane

Set up the Bindplane Google SecOps Integration to use WIF Authentication

Run the following command to output the values needed to input into Bindplane

```bash
echo "\nGCP Project Number: $GCP_PROJECT_NUMBER\nService Account Email: $SA_EMAIL\nWIF Pool ID: $WIF_POOL_ID\nWIF Provider ID: $WIF_PROVIDER_ID"
```

{% hint style="info" %}
Ensure you are logged into the same Bindplane project as the Project ID you set in [Step 0](#id-0.-set-up-variables)
{% endhint %}

1. Navigate to the **Project Settings** page in Bindplane using the menu in the top right
2. Scroll down to find the **Integrations** section
3. Press **Connect** or **Edit** to configure the integration
4. Fill out the Region, Customer ID, and Project Number parameters per the instructions in the dialog
5. Choose **Workload Identity Federation (WIF)** from the **Authentication Method** dropdown
6. Fill out the **Service Account Email, WIF Pool ID,** and **WIF Provider ID** with the values in the output from the above command
7. Press **Connect** or **Save** to complete the configuration and connect with Google SecOps.
   1. A successful connection means you have correctly completed the setup!
   2. In the case of a credentials based error, a descriptive error message will be shown at the bottom of the Google SecOps Integration editor
   3. Open the Developer Tools (F12) -> Console to view a raw technical error for further troubleshooting or support

<figure><img src="https://4134819172-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA6BP9V0wfJj4LZdQH6OJ%2Fuploads%2F0YG8E3nWlyJqrUuoz0Jd%2FwifConfig.png?alt=media&#x26;token=84c3bae1-2a6f-456b-ac3d-2d4e8b5d4f3d" alt=""><figcaption></figcaption></figure>

### Troubleshooting

If you're having issues setting up WIF Auth, first validate the following:

* You created all the GCP resources (service account, WIF pool, etc) in the GCP project associated with your Google SecOps Tenant
* Your Google SecOps Tenant is enabled for the "Data Processing Pipelines Preview"
  * Contact your Google SecOps Account Manager for more information or to get enabled
* You are setting up the Google SecOps Integration in the correct Bindplane Project. Your Bindplane Project ID should be the one used to create the WIF Provider in [Step 3](#id-3.-create-a-workload-identity-provider-oidc).
  * Find this value on the Support page by clicking the blue question mark button on the bottom right of Bindplane

Below are some commands to validate your resources have been created correctly.

#### Set Up Variables

For streamlined commands, set up the variables that will be referenced. Replace the placeholders below with the values you've generated from the above process.

```bash
GCP_PROJECT_NUMBER=<YOUR_GCP_PROJECT_NUMBER>
SA_EMAIL=<YOUR_SERVICE_ACCOUNT_EMAIL_ADDRESS>
WIF_POOL_ID=<YOUR_WIF_POOL_ID>
WIF_PROVIDER_ID=<YOUR_WIF_PROVIDER_ID>
# Automatically populate the GCP_PROJECT_ID variable
GCP_PROJECT_ID=$(gcloud projects describe $GCP_PROJECT_NUMBER --format="value(projectId)")
```

#### Verify Service Account Exists

```bash
gcloud iam service-accounts describe $SA_EMAIL \
  --project=$GCP_PROJECT_ID
```

Expected response

```
description: My Description
displayName: "My Display Name"
email: My Email
etag: MXXbWjE3jA=
name: projects/<GCP_PROJECT_ID>/serviceAccounts/<SA_EMAIL>
oauth2ClientId: 'myOAuth2ID'
projectId: <GCP_PROJECT_ID>
uniqueId: 'myID'
```

#### Validate Service Account Permissions

```bash
gcloud projects get-iam-policy $GCP_PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:${SA_EMAIL}" \
  --format="table(bindings.role)"
```

Expected response

```
ROLE
projects/<GCP_PROJECT_ID>/roles/<CUSTOM_SECOPS_ROLE>
```

Or if you used the "Chronicle API Admin" role approach

```
ROLE
roles/chronicle.admin
```

#### Validate Custom Role Permissions

If you have used a custom role approach for your service account permissions, run the following command to validate the proper permissions are set. Replace the placeholder for `<CUSTOM_SECOPS_ROLE>` with the value from the previous command.

```bash
gcloud iam roles describe <CUSTOM_SECOPS_ROLE> \
  --project=$GCP_PROJECT_ID
```

Expected response

* Validate the list of `includedPermissions` matches accordingly

```
etag: BwZJnSrKkMw=
includedPermissions:
- chronicle.feeds.get
- chronicle.feeds.list
- chronicle.logProcessingPipelines.associateStreams
- chronicle.logProcessingPipelines.create
- chronicle.logProcessingPipelines.delete
- chronicle.logProcessingPipelines.dissociateStreams
- chronicle.logProcessingPipelines.fetchAssociatedPipeline
- chronicle.logProcessingPipelines.fetchSampleLogsByStreams
- chronicle.logProcessingPipelines.get
- chronicle.logProcessingPipelines.list
- chronicle.logProcessingPipelines.testPipeline
- chronicle.logProcessingPipelines.update
- chronicle.logTypes.get
- chronicle.logTypes.list
- chronicle.logs.list
name: projects/<GCP_PROJECT_ID>/roles/<CUSTOM_SECOPS_ROLE>
stage: GA
title: My Custom SecOps Role Name
```

#### Validate WIF Pool

```bash
gcloud iam workload-identity-pools describe $WIF_POOL_ID \
  --location=global \
  --project=$GCP_PROJECT_ID
```

Expected response

* Ensure your pool is listed and is active

```
displayName: My SecOps WIF Pool Name
name: projects/<GCP_PROJECT_NUMBER>/locations/global/workloadIdentityPools/<WIF_POOL_IDL>
state: ACTIVE
```

#### Validate WIF Provider

```bash
gcloud iam workload-identity-pools providers describe $WIF_PROVIDER_ID \
  --location=global \
  --workload-identity-pool=$WIF_POOL_ID \
  --project=$GCP_PROJECT_ID
```

Expected response

* Ensure your provider is active, and configured correctly

```
attributeCondition: attribute.project_id=='<BP_PROJECT_ID>'
attributeMapping:
  attribute.project_id: assertion['https://auth0.app.bindplane.com/project_id']
  google.subject: assertion.sub
displayName: My Provider Name
name: projects/<GCP_PROJECT_NUMBER>/locations/global/workloadIdentityPools/<WIF_POOL_ID>/providers/<WIF_PROVIDER_ID>
oidc:
  allowedAudiences:
  - https://auth0.app.bindplane.com/secops-wif
  issuerUri: https://auth0.app.bindplane.com
state: ACTIVE
```

#### Validate Service Account Impersonation

```bash
gcloud iam service-accounts get-iam-policy \
  $SA_EMAIL \
  --project=$GCP_PROJECT_ID
```

Expected response

```
bindings:
- members:
  - principalSet://iam.googleapis.com/projects/<GCP_PROJECT_NUMBER>/locations/global/workloadIdentityPools/<WIF_POOL_ID>/attribute.project_id/<BP_PROJECT_ID>
  role: roles/iam.serviceAccountTokenCreator
etag: BwZK8vsdu6U=
version: 1
```
