> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Pub/Sub IAM permissions

> This article describes the GCP IAM permissions ClickPipes requires to authenticate with Google Cloud Pub/Sub and consume data from your topics.

<Note>
  You can sign up for the Private Preview waitlist [here](https://clickhouse.com/cloud/clickpipes#pubsub-private-preview).
</Note>

This article describes the GCP IAM permissions ClickPipes requires to authenticate with Google Cloud Pub/Sub and consume data from your topics, and how to set up a service account that grants exactly those permissions.

<h2 id="prerequisite">
  Prerequisites
</h2>

To follow this guide, you will need:

* An active ClickHouse Cloud service
* A GCP project containing the Pub/Sub topic you want to ingest from
* IAM permissions in that project to create service accounts and grant roles

<h2 id="authentication-model">
  Authentication model
</h2>

ClickPipes for Pub/Sub authenticates with GCP using a [service account JSON key](https://cloud.google.com/iam/docs/keys-create-delete). When you create a pipe, you upload the key file; ClickPipes encrypts it at rest and uses it at runtime to:

* list and read topics in your project,
* create and delete the [managed subscription](/integrations/clickpipes/pubsub/overview#managed-subscriptions) ClickPipes uses to consume messages,
* consume messages from that subscription, and
* (optionally) read native Pub/Sub schemas from the schema registry.

There is no workload identity or inline credential paste option — the service account JSON key is the only supported authentication method today.

<h2 id="required-permissions">
  Required permissions
</h2>

ClickPipes requires the following IAM permissions on the GCP project that owns the topic. They cover the full pipe lifecycle: discovery (topic listing, validation, sampling), subscription management, steady-state ingestion, and cleanup.

<h3 id="topic-access">
  Topic access (discovery and validation)
</h3>

| Permission                         | Purpose                                                           |
| ---------------------------------- | ----------------------------------------------------------------- |
| `pubsub.topics.list`               | List available topics in the project during discovery             |
| `pubsub.topics.get`                | Validate topic existence and retrieve schema settings             |
| `pubsub.topics.attachSubscription` | Required on the **topic** when creating a subscription against it |

<h3 id="subscription-lifecycle">
  Subscription lifecycle (discovery and ingestion)
</h3>

| Permission                     | Purpose                                                                                         |
| ------------------------------ | ----------------------------------------------------------------------------------------------- |
| `pubsub.subscriptions.create`  | Create the managed subscription (`clickpipes-{pipeID}`) and ephemeral discovery subscriptions   |
| `pubsub.subscriptions.get`     | Health checks (every 60s), follower polling, subscription validation                            |
| `pubsub.subscriptions.delete`  | Clean up ephemeral discovery subscriptions and delete the managed subscription on pipe deletion |
| `pubsub.subscriptions.consume` | `Receive()`, `Ack()`, `Nack()`, and seek-to-timestamp operations                                |

<h3 id="schema-access">
  Schema access (optional — only for native Avro/Protobuf topics)
</h3>

| Permission           | Purpose                                                             |
| -------------------- | ------------------------------------------------------------------- |
| `pubsub.schemas.get` | Retrieve native schema definitions from the Pub/Sub schema registry |

<h2 id="predefined-roles">
  Predefined roles
</h2>

| Role                                                                                                 | Sufficient? | Notes                                                                                                                  |
| ---------------------------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------- |
| [`roles/pubsub.editor`](https://cloud.google.com/iam/docs/understanding-roles#pubsub.editor)         | Yes         | Covers all required permissions. Broadest option.                                                                      |
| [`roles/pubsub.subscriber`](https://cloud.google.com/iam/docs/understanding-roles#pubsub.subscriber) | **No**      | Missing `topics.list`, `topics.attachSubscription`, `subscriptions.create`, `subscriptions.delete`, and `schemas.get`. |
| [`roles/pubsub.viewer`](https://cloud.google.com/iam/docs/understanding-roles#pubsub.viewer)         | **No**      | Read-only — no subscription management or consumption.                                                                 |
| Custom role *(recommended)*                                                                          | Yes         | Use the seven core permissions above (plus optional `schemas.get`) for least-privilege access.                         |

<h2 id="setup">
  Setup
</h2>

<h3 id="create-custom-role">
  Create a custom role (recommended)
</h3>

For least-privilege access, create a custom role with exactly the permissions ClickPipes needs.

You can do this with the `gcloud` CLI:

```bash theme={null}
gcloud iam roles create clickpipes.pubsub.ingestion \
  --project=YOUR_PROJECT_ID \
  --title="ClickPipes Pub/Sub Ingestion" \
  --description="Permissions required by ClickHouse ClickPipes to ingest from Pub/Sub" \
  --permissions=pubsub.topics.list,pubsub.topics.get,pubsub.topics.attachSubscription,pubsub.subscriptions.create,pubsub.subscriptions.get,pubsub.subscriptions.delete,pubsub.subscriptions.consume \
  --stage=GA
```

Or, in the GCP Console, go to **IAM & Admin → Roles → Create role** and add the permissions listed in [Required permissions](#required-permissions).

<Info>
  **Optional permissions**

  Append `pubsub.schemas.get` to the `--permissions` list if you ingest from topics that use native Pub/Sub Avro or Protobuf schemas. Leave it out otherwise to keep the role minimal.
</Info>

If you prefer to skip the custom role, you can grant `roles/pubsub.editor` instead.

<h3 id="create-service-account">
  Create a service account
</h3>

Create a dedicated service account for the ClickPipe:

```bash theme={null}
gcloud iam service-accounts create clickpipes-pubsub \
  --project=YOUR_PROJECT_ID \
  --display-name="ClickPipes Pub/Sub Ingestion"
```

<h3 id="grant-role">
  Grant the role to the service account
</h3>

Bind the role you created (or `roles/pubsub.editor`) to the service account at the project level:

```bash theme={null}
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:clickpipes-pubsub@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
  --role="projects/YOUR_PROJECT_ID/roles/clickpipes.pubsub.ingestion"
```

<h3 id="create-key">
  Create and download a service account key
</h3>

Create a JSON key for the service account and download it locally:

```bash theme={null}
gcloud iam service-accounts keys create clickpipes-pubsub-key.json \
  --iam-account=clickpipes-pubsub@YOUR_PROJECT_ID.iam.gserviceaccount.com
```

You will upload this `clickpipes-pubsub-key.json` file in the ClickPipes UI when creating the pipe.

<Info>
  **Treat the key as a secret**

  Service account keys grant access to your GCP project. Store the file securely, do not commit it to source control, and rotate it periodically. ClickPipes encrypts the key at rest after upload.
</Info>

<h2 id="notes">
  Notes
</h2>

* `pubsub.topics.attachSubscription` is required on the **topic resource**, not the subscription. This is commonly missed when granting only subscription-level permissions.
* If your topic does not use a native Pub/Sub schema (Avro or Protobuf), the `pubsub.schemas.get` permission is not needed.
* Managed subscriptions are named `clickpipes-{pipeID}` with a 60s ack deadline, 7-day message retention, and message ordering enabled.
* Ephemeral discovery subscriptions are named `clickpipes-discovery-{uuid}` with a 10s ack deadline, 10-minute retention, and a 24-hour auto-expiry TTL.
* ClickPipes treats `PermissionDenied` and `Unauthenticated` errors as non-retryable — if a permission is missing, the pipe fails fast rather than retrying indefinitely.
