# Cloud Storage (GCS) Source

## Overview

Panther supports configuring Google Cloud Storage (GCS) as a Data Transport to pull log data directly from GCS buckets, write rules, and run queries on this processed data. Panther uses [Pub/Sub](https://cloud.google.com/storage/docs/pubsub-notifications) to be notified of new data in your bucket that is ready to be consumed.

Panther can authenticate against your source using Google Cloud [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) or a [service account](https://cloud.google.com/iam/docs/service-account-overview).

Data can be sent compressed (or uncompressed). Learn more about compression specifications in [Ingesting compressed data in Panther](https://docs.panther.com/data-onboarding/data-transports/..#ingesting-compressed-data-in-panther).

## How to set up a GCS log source in Panther

### Step 1: Begin creating the GCS source in Panther

1. In the left-hand navigation bar of your Panther Console, click **Configure** > **Log Sources**.
2. In the upper-right corner, click **Create New**.
3. Click the **Google Cloud Storage** tile.
4. On the **Basic Info** page, fill in the fields:
   * **Name**: Enter a descriptive name for the GCS log source.
   * **Prefixes & Schemas**: Define combinations of prefixes, schemas, and exclusion filters, according the structure of your data storage in GCS.
     * To attach one or more schemas to all data in the bucket, leave the **GCS Prefix** field blank. This will create a wildcard (\*) prefix.
5. Click **Setup**.
6. On the **Log Format** page, select the [stream type](https://docs.panther.com/custom-log-types/reference#stream-type) of the incoming logs:
   * **Auto**
   * **Lines**
   * **JSON**
   * **JSON Array**
7. Click **Continue**.

### **Step 2: Create** required Google Cloud Platform (GCP) infrastructure

Before creating GCP infrastructure, you'll need to decide:

* The authentication method: You can use [Google Cloud Workload Identity Federation with AWS](https://cloud.google.com/iam/docs/workload-identity-federation) or a [service account](https://cloud.google.com/iam/docs/service-account-overview)—see the top-level tabs below.
* The creation method: You can use Terraform to create the infrastructure, or create it manually in the GCP console—see the sub-tabs within each top-level tab below.

{% tabs %}
{% tab title="Service account authentication" %}
If you'd like Panther to authenticate using a [Google Cloud service account](https://cloud.google.com/iam/docs/service-account-overview), follow the instructions in one of the tabs below.

{% tabs %}
{% tab title="Terraform" %}
To create GCP infrastructure using Terraform (authenticating with a service account):

1. On the **Infrastructure & Credentials** page, click the **Service Account** tab.\
   ![Under an "Infrastructure & Credentials" header, a tab labeled "Service Account" is circled.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-86cf52ca25fab148f209f35c7689bf9fce571efe%2FScreenshot%202025-02-24%20at%202.37.30%E2%80%AFPM.png?alt=media)
2. Click **Terraform Template** to download the Terraform template.
   * You can also find the Terraform template at [this GitHub link](https://github.com/panther-labs/panther-auxiliary/tree/main/terraform/panther_gcs_transport_type_infra).
3. Fill out the fields in the `panther.tfvars` file with your configuration.
   * Set `authentication_method` to `"service_account"`.
4. Initialize a working directory containing Terraform configuration files and run `terraform init`.
5. Copy the corresponding **Terraform Command** provided and run it in your CLI.
6. Generate a JSON key file by copying the **gcloud Command** provided, replacing the value for your service account email address, and running it in your CLI.
   * You can find the service account email in the output of the **Terraform Command**.
     {% endtab %}

{% tab title="Manual creation in GCP console" %}
To create the GCP infrastructure components manually in the GCP console (authenticating with a service account):

1. In your Google Cloud console, determine which bucket Panther will pull logs from.
   * If you have not created a bucket yet, please see [Google's documentation on creating a bucket](https://cloud.google.com/storage/docs/creating-buckets).
2. [Create a topic](https://cloud.google.com/pubsub/docs/admin#creating_a_topic) for the notifications.
   * You can create a topic using the `gcloud` CLI tool with the following command format: `gcloud pubsub topics create $TOPIC_ID`
3. [Configure the bucket to send notifications](https://cloud.google.com/storage/docs/reporting-changes) for new files to the topic you created.
   * You can create a notification using the `gcloud` CLI tool with the following command format: `gsutil notification create -t $TOPIC_NAME -e OBJECT_FINALIZE -f json gs://$BUCKET_NAME`
   * **Note:** Panther only requires the `OBJECT_FINALIZE` type.
4. [Create a subscription](https://cloud.google.com/pubsub/docs/admin#pubsub_create_pull_subscription-gcloud) to be used with the topic you created.
   * You can create a subscription using the `gcloud` CLI tool with the following command format: `gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic $TOPIC_ID --topic-project $PROJECT_ID`

{% hint style="warning" %}
This subscription should not be used by any other service or source.
{% endhint %}

5. [Enable the IAM API](https://console.cloud.google.com/apis/library/iam.googleapis.com).
6. [Create a new Google Cloud service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts). To create the account using the `gcloud` CLI tool, use the following command format:

   ```
   gcloud iam service-accounts create SA-NAME \
       --description="DESCRIPTION" \
       --display-name="DISPLAY_NAME"
   ```

   * Make sure to take note of the account email address, as Panther will use this to access the infrastructure created for this GCS integration.
7. Assign the required IAM roles to the account.
   * The following permissions are required for the project where the Pub/Sub subscription and topic lives:

     <table data-header-hidden><thead><tr><th width="327.374982940047" align="center">Permission required</th><th width="294.15662026309724" align="center">Role</th><th width="208" align="center">Condition</th></tr></thead><tbody><tr><td align="center"><strong>Permissions required</strong></td><td align="center"><strong>Role</strong></td><td align="center"><strong>Scope</strong></td></tr><tr><td align="center"><p><code>storage.objects.get</code></p><p><code>storage.objects.list</code></p></td><td align="center"><code>roles/storage.objectViewer</code></td><td align="center"><em>bucket-name</em></td></tr><tr><td align="center"><code>pubsub.subscriptions.consume</code></td><td align="center"><code>roles/pubsub.subscriber</code></td><td align="center"><em>subscription-name</em></td></tr><tr><td align="center"><code>pubsub.subscriptions.get</code></td><td align="center"><code>roles/pubsub.viewer</code></td><td align="center"><em>subscription-name</em></td></tr><tr><td align="center"><code>monitoring.timeSeries.list</code></td><td align="center"><code>roles/monitoring.viewer</code></td><td align="center">project</td></tr></tbody></table>

     * **Note:** You can set conditions or IAM policies on permissions for specific resources. This can be done either in the IAM page of the service account (as seen in the example screenshot below) or in the specific resource's page.\
       ![On the IAM page of the service account, under the header "Grant this service account access to project," there are fields for Rule and Condition.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-a76ce6b753aefd1a1a5b99869bb6773442a905cf%2Fgcp-grant-access.png?alt=media)
     * **Note:** You can create the permissions using the `gcloud` CLI tool:
       * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" --role="roles/storage.objectViewer"`
       * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" --role="roles/pubsub.subscriber"`
       * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" --role="roles/pubsub.viewer"`
       * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" --role="roles/monitoring.viewer"`
8. [Generate a JSON key file](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) for the service account, which will be used in Panther to authenticate to the GCP infrastructure.
   * To create a JSON key file using the gcloud CLI tool, run the following command format:\
     `gcloud iam service-accounts keys create $KEYFILE_PATH --iam-account=$SERVICE_ACCOUNT_EMAIL`
   * Alternatively, you can run the above command in GCP's terminal instead of locally.
     1. Click the 3 dots icon menu in the top right, then click **Download**.
        * ![](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-6940cc677e233faedec16959c99926def5e052be%2Fimage.png?alt=media)
     2. Click the folder icon for Browse.
     3. Navigate to the key file and select it, then click **Download**.
        {% endtab %}
        {% endtabs %}
        {% endtab %}

{% tab title="Workload Identity Federation authentication" %}
If you'd like Panther to authenticate using [Google Cloud Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation), follow the instructions in one of the tabs below.

{% tabs %}
{% tab title="Terraform" %}
To create the GCP infrastructure components using Terraform (authenticating with Workload Identity Federation):

1. On the **Infrastructure & Credentials page**, click the **Workload Identity Federation** tab.\
   ![Under an "Infrastructure & Credentials" header, a tab labeled "Workload Identity Federation" is circled.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-7e7ca651c6e60e46eebec337cf723e11dc602ae7%2FScreenshot%202025-02-24%20at%202.39.43%E2%80%AFPM.png?alt=media)
2. Click **Terraform Template** to download the Terraform template.
   * You can also find the Terraform template at [this GitHub link](https://github.com/panther-labs/panther-auxiliary/tree/main/terraform/panther_gcs_transport_type_infra).
3. Fill out the fields in the `panther.tfvars` file with your configuration.
   * Set `authentication_method` to `"workload_identity_federation"`.
   * Provide values for `panther_workload_identity_pool_id`, `panther_workload_identity_pool_provider_id`**,** and `panther_aws_account_id`.
4. Initialize a working directory containing Terraform configuration files and run `terraform init`.
5. Copy the corresponding **Terraform Command** provided and run it in your CLI.
6. Generate a credential configuration file for the pool by copying the **gcloud Command** provided, replacing the value for the project number, pool ID, and provider ID, and running it in your CLI.
   * You can find the project number, the pool ID and the provider ID in the output of the **Terraform Command**.
     {% endtab %}

{% tab title="Manual creation in GCP console" %}
To create the GCP infrastructure components manually in the GCP console (authenticating with Workload Identity Federation):

1. In your Google Cloud console, determine which bucket Panther will pull logs from.
   * If you have not created a bucket yet, please see [Google's documentation on creating a bucket](https://cloud.google.com/storage/docs/creating-buckets).

{% hint style="warning" %}
[Uniform bucket-level access](https://cloud.google.com/storage/docs/uniform-bucket-level-access) must be enabled on the target bucket in order to grant Workload Identity Federation entities access to cloud storage resources.
{% endhint %}

2. [Create a topic](https://cloud.google.com/pubsub/docs/admin#creating_a_topic) for the notifications.
   * You can create a topic using the `gcloud` CLI tool with the following command format: `gcloud pubsub topics create $TOPIC_ID`
3. [Configure the bucket to send notifications](https://cloud.google.com/storage/docs/reporting-changes) for new files to the topic you created.
   * You can create a notification using the `gcloud` CLI tool with the following command format: `gsutil notification create -t $TOPIC_NAME -e OBJECT_FINALIZE -f json gs://$BUCKET_NAME`
   * **Note:** Panther only requires the `OBJECT_FINALIZE` type.
4. [Create a subscription](https://cloud.google.com/pubsub/docs/admin#pubsub_create_pull_subscription-gcloud) to be used with the topic you created.
   * You can create a subscription using the `gcloud` CLI tool with the following command format: `gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic $TOPIC_ID --topic-project $PROJECT_ID`

{% hint style="warning" %}
This subscription should not be used by any other service or source.
{% endhint %}

5. [Enable the IAM API](https://console.cloud.google.com/apis/library/iam.googleapis.com).
6. Configure Workload Identity Federation with AWS by following the [Configure Workload Identity Federation with AWS or Azure](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds) documentation.
   1. As you are [defining an attribute mapping(s) and condition](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds#mappings-and-conditions), take note of the following examples:
      * Example [attribute mappings](https://cloud.google.com/iam/docs/workload-identity-federation#mapping):

        <table><thead><tr><th width="195.8271484375">Google</th><th width="523.1220703125">AWS</th></tr></thead><tbody><tr><td><code>google.subject</code></td><td><code>assertion.arn.extract('arn:aws:sts::{account_id}:')+":"+assertion.arn.extract('assumed-role/{role_and_session}').extract('/{session}')</code></td></tr><tr><td><code>attribute.account</code></td><td><code>assertion.account</code></td></tr></tbody></table>
      * Example [attribute condition](https://cloud.google.com/iam/docs/workload-identity-federation#conditions):\
        `attribute.account=="<PANTHER_AWS_ACCOUNT_ID>"`

{% hint style="warning" %}
The value of the `google.subject` attribute [cannot exceed 127 characters](https://cloud.google.com/iam/docs/workload-identity-federation#mapping). You may use [Common Expression Language (CEL) expressions](https://cloud.google.com/iam/docs/workload-identity-federation#mapping) to transform or combine attributes from the token issued by AWS. The expression suggested in the table above takes this limit into account, and is an attempt at transforming the ARN into a value that uniquely identifies Panther entities. For more information on the AWS attributes, see "Example 2 - Called by user created with AssumeRole" on [this AWS documentation page](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html).
{% endhint %}

b. When you are [adding a provider to your identity pool](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds#aws), select **AWS**.

7. Assign the required IAM roles to the account.
   * The following permissions are required for the project where the Pub/Sub subscription and topic lives:

<table data-header-hidden><thead><tr><th width="327.374982940047" align="center">Permission required</th><th width="294.15662026309724" align="center">Role</th><th width="208" align="center">Condition</th></tr></thead><tbody><tr><td align="center"><strong>Permissions required</strong></td><td align="center"><strong>Role</strong></td><td align="center"><strong>Scope</strong></td></tr><tr><td align="center"><p><code>storage.objects.get</code></p><p><code>storage.objects.list</code></p></td><td align="center"><code>roles/storage.objectViewer</code></td><td align="center"><em>bucket-name</em></td></tr><tr><td align="center"><code>pubsub.subscriptions.consume</code></td><td align="center"><code>roles/pubsub.subscriber</code></td><td align="center"><em>subscription-name</em></td></tr><tr><td align="center"><code>pubsub.subscriptions.get</code></td><td align="center"><code>roles/pubsub.viewer</code></td><td align="center"><em>subscription-name</em></td></tr><tr><td align="center"><code>monitoring.timeSeries.list</code></td><td align="center"><code>roles/monitoring.viewer</code></td><td align="center">project</td></tr></tbody></table>

* **Note:** You can set conditions or IAM policies on permissions for specific resources. This can be done either in the IAM section in GCP (as seen in the example screenshot below) or in the specific resource's page.\
  ![In the Google Cloud console, the "IAM" navigation bar item is circled. In a slide-out panel, sections titled "Add principals" and "Assign roles" are circled.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-fde2bbdd808d22e67b3f2409a908d7a63596593b%2FScreenshot%202025-03-05%20at%2015.20.04.png?alt=media)
* **Note:** You can create the permissions using the `gcloud` CLI tool, where the `$PRINCIPAL_ID` may be something like:\
  `principalSet://iam.googleapis.com/projects/<THE_ACTUAL_GOOGLE_PROJECT_NUMBER>/locations/global/workloadIdentityPools/<THE_ACTUAL_POOL_ID>/attribute.account/<THE_ACTUAL_PANTHER_AWS_ACCOUNT_ID>`
  * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="$PRINCIPAL_ID" --role="roles/storage.objectViewer"`
  * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="$PRINCIPAL_ID" --role="roles/pubsub.subscriber"`
  * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="$PRINCIPAL_ID" --role="roles/pubsub.viewer"`
  * `gcloud projects add-iam-policy-binding $PROJECT_ID --member="$PRINCIPAL_ID" --role="roles/monitoring.viewer"`

8. [Download the credential configuration file](https://cloud.google.com/iam/docs/workload-download-cred-and-grant-access), which will be used in Panther to authenticate to the GCP infrastructure.
   * To generate a credential configuration file using the gcloud CLI tool, use the following command format:\
     `gcloud iam workload-identity-pools create-cred-config projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID --aws --output-file=config.json`
     {% endtab %}
     {% endtabs %}
     {% endtab %}
     {% endtabs %}

### Step 3: Provide credential file and configuration values to Panther

{% tabs %}
{% tab title="Service account authentication" %}
If you are using a [Google Cloud service account](https://cloud.google.com/iam/docs/service-account-overview) to authenticate:

1. Under **Provide pulling configuration & JSON Keyfile**, upload your JSON key file.
2. Enter your **GCS Bucket Nam**e and **Pub/Sub Subscription ID,** found in the **Subscriptions** section of your Google Cloud account.\
   ![](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-cbe16c67c5686419222831aa3ef4085a2c53b47f%2FScreenshot%202025-03-05%20at%2015.32.51.png?alt=media)
3. Click **Setup**. You will be directed to a success screen:

   <figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-e55cedf82c6a6adc66ec5c14ebdcb164c3b1dcca%2FScreenshot%202023-08-03%20at%204.33.30%20PM.png?alt=media" alt="The success screen reads, &#x22;Everything looks good! Panther will now automatically pull &#x26; process logs from your account&#x22;" width="281"><figcaption></figcaption></figure>

   * You can optionally enable one or more [Detection Packs](https://docs.panther.com/detections/panther-managed/packs).
   * If you have not done so already, click **Attach or Infer Schemas** to attach one or more schemas to the source.
   * The **Trigger an alert when no events are processed** setting defaults to **YES**. We recommend leaving this enabled, as you will be alerted if data stops flowing from the log source after a certain period of time. The timeframe is configurable, with a default of 24 hours.

     <figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-c48119abd559990173004bde99ff4907fdd2ded2%2FScreenshot%202023-08-03%20at%204.26.54%20PM.png?alt=media" alt="The &#x22;Trigger an alert when no events are processed&#x22; toggle is set to YES. The &#x22;How long should Panther wait before it sends you an alert that no events have been processed&#x22; setting is set to 1 Day" width="320"><figcaption></figcaption></figure>

{% endtab %}

{% tab title="Workload Identity Federation authentication" %}
If you are using [Google Cloud Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) to authenticate:

1. On the **Infrastructure & Credentials page**, if you have not already, click the **Workload Identity Federation** tab.\
   ![Under an "Infrastructure & Credentials" header, a tab labeled "Workload Identity Federation" is circled.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-7e7ca651c6e60e46eebec337cf723e11dc602ae7%2FScreenshot%202025-02-24%20at%202.39.43%E2%80%AFPM.png?alt=media)
2. Under **Provide pulling configuration & credential configuration file**, upload your credential configuration file.
3. Enter your **Project ID**, **GCS Bucket Name**, and **Pub/Sub Subscription ID** found in the **Subscriptions** section of your Google Cloud account.\
   ![In a tab titled "Workload Identity Federation," there are various buttons and form fields, including "GCS Bucket Name," "Pub/Sub Subscription ID," and "Project ID."](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-7389ace81b5b86f828da0995718f5fff17470707%2FScreenshot%202025-03-05%20at%2015.32.59.png?alt=media)
4. Click **Setup**. You will be directed to a success screen:

   <figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-e55cedf82c6a6adc66ec5c14ebdcb164c3b1dcca%2FScreenshot%202023-08-03%20at%204.33.30%20PM.png?alt=media" alt="The success screen reads, &#x22;Everything looks good! Panther will now automatically pull &#x26; process logs from your account&#x22;" width="281"><figcaption></figcaption></figure>

   * You can optionally enable one or more [Detection Packs](https://docs.panther.com/detections/panther-managed/packs).
   * If you have not done so already, click **Attach or Infer Schemas** to attach one or more schemas to the source.
   * The **Trigger an alert when no events are processed** setting defaults to **YES**. We recommend leaving this enabled, as you will be alerted if data stops flowing from the log source after a certain period of time. The timeframe is configurable, with a default of 24 hours.

     <figure><img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-c48119abd559990173004bde99ff4907fdd2ded2%2FScreenshot%202023-08-03%20at%204.26.54%20PM.png?alt=media" alt="The &#x22;Trigger an alert when no events are processed&#x22; toggle is set to YES. The &#x22;How long should Panther wait before it sends you an alert that no events have been processed&#x22; setting is set to 1 Day" width="320"><figcaption></figcaption></figure>

{% endtab %}
{% endtabs %}

## Viewing ingested logs

After your log source is configured, you can search ingested data using [Search](https://docs.panther.com/search/search-tool) or [Data Explorer](https://docs.panther.com/search/data-explorer).
