Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/integrations/data-ingestion/clickpipes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Azureeventhubssvg from '@site/static/images/integrations/logos/azure_even
import Warpstreamsvg from '@site/static/images/integrations/logos/warpstream.svg';
import S3svg from '@site/static/images/integrations/logos/amazon_s3_logo.svg';
import Amazonkinesis from '@site/static/images/integrations/logos/amazon_kinesis_logo.svg';
import GoogleCloudPubSub from '@site/static/images/integrations/logos/google_pubsub.svg';
import Gcssvg from '@site/static/images/integrations/logos/gcs.svg';
import DOsvg from '@site/static/images/integrations/logos/digitalocean.svg';
import ABSsvg from '@site/static/images/integrations/logos/azureblobstorage.svg';
Expand Down Expand Up @@ -54,6 +55,7 @@ ClickPipes can be deployed and managed manually using the ClickPipes UI, as well
| DigitalOcean Spaces | <DOsvg class="image" alt="Digital Ocean logo" style={{width: '3rem', height: 'auto'}}/> | Object Storage | Stable | Configure ClickPipes to ingest large volumes of data from object storage.
| Azure Blob Storage | <ABSsvg class="image" alt="Azure Blob Storage logo" style={{width: '3rem', height: 'auto'}}/> | Object Storage | Stable | Configure ClickPipes to ingest large volumes of data from object storage.
| [Amazon Kinesis](/integrations/clickpipes/kinesis) | <Amazonkinesis class="image" alt="Amazon Kenesis logo" style={{width: '3rem', height: 'auto'}}/> |Streaming| Stable | Configure ClickPipes and start ingesting streaming data from Amazon Kinesis into ClickHouse cloud. |
| [GCP Pub/Sub](/integrations/clickpipes/pubsub) | <GoogleCloudPubSub class="image" alt="Google Cloud Pub/Sub logo" style={{width: '3rem', height: 'auto'}}/> |Streaming| Public Beta | Configure ClickPipes and start ingesting streaming data from Google Cloud Pub/Sub into ClickHouse Cloud. |
| [Postgres](/integrations/clickpipes/postgres) | <Postgressvg class="image" alt="Postgres logo" style={{width: '3rem', height: 'auto'}}/> |DBMS| Stable | Configure ClickPipes and start ingesting data from Postgres into ClickHouse Cloud. |
| [MySQL](/integrations/clickpipes/mysql) | <Mysqlsvg class="image" alt="MySQL logo" style={{width: '3rem', height: '3rem'}}/> |DBMS| Public Beta | Configure ClickPipes and start ingesting data from MySQL into ClickHouse Cloud. |
| [MongoDB](/integrations/clickpipes/mongodb) | <Mongodbsvg class="image" alt="MongoDB logo" style={{width: '3rem', height: '3rem'}}/> |DBMS| Private Preview | Configure ClickPipes and start ingesting data from MongoDB into ClickHouse Cloud. |
Expand Down
229 changes: 229 additions & 0 deletions docs/integrations/data-ingestion/clickpipes/pubsub/01_overview.md

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions docs/integrations/data-ingestion/clickpipes/pubsub/02_auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
slug: /integrations/clickpipes/pubsub/auth
sidebar_label: 'Pub/Sub IAM permissions'
title: 'Pub/Sub IAM permissions'
description: 'This article describes the GCP IAM permissions ClickPipes requires to authenticate with Google Cloud Pub/Sub and consume data from your topics.'
doc_type: 'guide'
keywords: ['Google Cloud Pub/Sub', 'GCP IAM', 'service account']
integration:
- support_level: 'core'
- category: 'clickpipes'
---

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.

## Prerequisites {#prerequisite}

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

## Authentication model {#authentication-model}

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#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.

## Required permissions {#required-permissions}

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.

### Topic access (discovery and validation) {#topic-access}

| 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 |

### Subscription lifecycle (discovery and ingestion) {#subscription-lifecycle}

| 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 |

### Schema access (optional — only for native Avro/Protobuf topics) {#schema-access}

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

## Predefined roles {#predefined-roles}

| 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. |

## Setup {#setup}

<VerticalStepper headerLevel="h3"/>

### Create a custom role (recommended) {#create-custom-role}

For least-privilege access, create a custom role with exactly the permissions ClickPipes needs.
Comment thread
tpanetti marked this conversation as resolved.

You can do this with the `gcloud` CLI:

```bash
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).

:::note 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.
:::

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

### Create a service account {#create-service-account}

Create a dedicated service account for the ClickPipe:

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

### Grant the role to the service account {#grant-role}

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

```bash
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"
```

### Create and download a service account key {#create-key}

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

```bash
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.

:::note 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.
:::

## Notes {#notes}

- `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.
20 changes: 20 additions & 0 deletions docs/integrations/data-ingestion/clickpipes/pubsub/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---


description: 'Landing page with table of contents for the GCP Pub/Sub ClickPipes section'
slug: /integrations/clickpipes/pubsub-index
sidebar_position: 1
title: 'GCP Pub/Sub ClickPipes'
doc_type: 'landing-page'
keywords: ['GCP Pub/Sub ClickPipes', 'Google Cloud Pub/Sub']
integration:
- support_level: 'core'
- category: 'clickpipes'
---

<!--AUTOGENERATED_START-->
| Page | Description |
|-----|-----|
| [Integrating Google Pub/Sub with ClickHouse Cloud](/integrations/clickpipes/pubsub) | Seamlessly connect your Google Cloud Pub/Sub topics to ClickHouse Cloud. |
| [Pub/Sub IAM permissions](/integrations/clickpipes/pubsub/auth) | This article describes the GCP IAM permissions ClickPipes requires to authenticate with Google Cloud Pub/Sub and consume data from your topics. |
<!--AUTOGENERATED_END-->
1 change: 1 addition & 0 deletions scripts/autogenerate-table-of-contents.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ COMMANDS=(
'--single-toc --dir="docs/getting-started/example-datasets" --md="docs/getting-started/index.md" --ignore images'
'--single-toc --dir="docs/integrations/data-ingestion/clickpipes/kafka" --md="docs/integrations/data-ingestion/clickpipes/kafka/index.md" --ignore images'
'--single-toc --dir="docs/integrations/data-ingestion/clickpipes/kinesis" --md="docs/integrations/data-ingestion/clickpipes/kinesis/index.md" --ignore images'
'--single-toc --dir="docs/integrations/data-ingestion/clickpipes/pubsub" --md="docs/integrations/data-ingestion/clickpipes/pubsub/index.md" --ignore images'
'--single-toc --dir="docs/integrations/data-ingestion/etl-tools/dbt" --md="docs/integrations/data-ingestion/etl-tools/dbt/index.md" --ignore images'
'--single-toc --dir="docs/use-cases/AI_ML/MCP" --md="docs/use-cases/AI_ML/MCP/index.md" --ignore images'
'--single-toc --dir="docs/use-cases/AI_ML/MCP/ai_agent_libraries" --md="docs/use-cases/AI_ML/MCP/ai_agent_libraries/index.md"'
Expand Down
16 changes: 16 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,22 @@ const sidebars = {
},
],
},
{
type: 'category',
label: 'ClickPipes for GCP Pub/Sub',
collapsed: true,
collapsible: true,
link: {
type: 'doc',
id: 'integrations/data-ingestion/clickpipes/pubsub/index',
},
items: [
{
type: 'autogenerated',
dirName: 'integrations/data-ingestion/clickpipes/pubsub',
},
],
},
{
type: 'category',
label: 'ClickPipes for MySQL',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion static/images/integrations/logos/amazon_kinesis_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions static/images/integrations/logos/google_pubsub.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading