# Analytics Hub Publisher

> Design and publish BigQuery data products through Analytics Hub, including exchanges, listings, subscriber governance, and the decision of whether to share at all. Use when the user mentions Analytics Hub, a data exchange, a listing, sharing datasets across projects or with a partner or vendor, linked datasets, or asks how to give another team read access without copying data.

- Skill: `rk-chavali/analytics-hub-publisher` (Agent Skill)
- Install (CLI): `npx skillmds@latest add rk-chavali/analytics-hub-publisher`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rk-chavali/analytics-hub-publisher/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: rk-chavali (https://skillmd.com/u/rk-chavali)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/rk-chavali/analytics-hub-publisher

---


# Analytics Hub publisher

## Decide the sharing mechanism first

Analytics Hub is not always the answer. Work down this table before designing an
exchange.

| Situation | Use | Why not Analytics Hub |
| --- | --- | --- |
| One team, same org, one dataset | dataset IAM grant | an exchange is overhead for one grant |
| Row or column restrictions per consumer | authorized view, or row-level security | listings share the whole dataset |
| Many consumers, stable product, cross-project | Analytics Hub | this is what it is for |
| External partner, different org | Analytics Hub | no data copy, no egress, revocable |
| Consumer needs to write | not sharing, a pipeline | linked datasets are read-only |
| One-off extract | authorized view or an export | a listing implies a commitment |

Say plainly that a listing is a product commitment. Publishing one means you have
promised a schema, a freshness, and a deprecation path to people you may never
meet. If the user is not ready for that, recommend an authorized view instead.

## Structure

- **Exchange**: a container, scoped by audience. `internal-analytics`,
  `partner-suppliers`, `public-reference`. Do not put internal and partner
  listings in the same exchange.
- **Listing**: one per data product, backed by one dataset.
- **Linked dataset**: what the subscriber creates in their own project. It is
  read-only, queried on the subscriber's own slots, and reflects the source live.

Billing follows the query, so subscribers pay for their own scans. Storage stays
with you. Say this explicitly when someone asks who pays.

## Prepare the source dataset before listing it

A listing exposes the whole dataset, so the dataset must contain only what you
intend to publish. Build a dedicated publication dataset rather than listing a
working dataset.

1. Create `pub_<domain>` containing only the published surfaces.
2. Populate it with authorized views over the marts, so you keep control of the
   column list.
3. Description and column descriptions on everything. This is the documentation
   the subscriber sees, and it is the only documentation they get.
4. Partition filters required, so a subscriber cannot accidentally scan history.
5. A schema contract on file for each table. See `bq-schema-contract`.

## Terraform

```hcl
resource "google_bigquery_analytics_hub_data_exchange" "internal" {
  project          = var.project_id
  location         = var.location
  data_exchange_id = "internal_analytics"
  display_name     = "Internal analytics"
  description      = "Governed data products published by the data platform team."
  primary_contact  = "data-platform@example.com"
}

resource "google_bigquery_analytics_hub_listing" "orders" {
  project          = var.project_id
  location         = var.location
  data_exchange_id = google_bigquery_analytics_hub_data_exchange.internal.data_exchange_id
  listing_id       = "retail_orders_v1"
  display_name     = "Retail orders, v1"
  description      = "One row per order. Grain: order_id. Refreshed daily by 07:00 UTC."
  primary_contact  = "data-platform@example.com"
  documentation    = "https://internal.example.com/docs/data/retail-orders"

  bigquery_dataset {
    dataset = google_bigquery_dataset.pub_retail.id
  }

  restricted_export_config {
    enabled               = true
    restrict_query_result = true
  }
}

resource "google_bigquery_analytics_hub_listing_iam_member" "finance" {
  project          = var.project_id
  location         = var.location
  data_exchange_id = google_bigquery_analytics_hub_data_exchange.internal.data_exchange_id
  listing_id       = google_bigquery_analytics_hub_listing.orders.listing_id
  role             = "roles/analyticshub.subscriber"
  member           = "group:finance-analytics@example.com"
}
```

Version in the listing id, not just the display name. `retail_orders_v1` and
`retail_orders_v2` can coexist while consumers migrate, which is the whole point
of versioning a published product.

## Inspect before you publish

Read `references/execution-model.md`. A listing exposes an entire dataset, so
check what is actually in it before designing one. `list_table_ids` and
`get_dataset_info` tell you whether the working dataset has tables nobody
intended to publish, which is the usual reason a publication dataset is needed.

Creating the exchange, the listing, and the IAM bindings are writes. Emit the
Terraform and the gcloud commands.

## Governance

- Grant `roles/analyticshub.subscriber` to groups, never to individuals.
- `restricted_export_config` on anything that leaves the org, so results cannot
  be exported wholesale.
- Review subscribers quarterly. List them and ask each owner if they still need
  it:

```bash
gcloud bigquery analytics-hub listings list \
  --data-exchange=internal_analytics --location=us

gcloud bigquery analytics-hub listings get-iam-policy LISTING_ID \
  --data-exchange=internal_analytics --location=us
```

- Deprecating a listing: announce, keep the old version live for one full
  consumer cycle, then delete. Deleting a listing breaks every linked dataset
  immediately and without warning to the subscriber, so never do it quietly.

## Output format

When designing a share, return: the mechanism chosen and why, the exchange and
listing names, the publication dataset contents, the Terraform, the subscriber
groups, and the deprecation policy in one sentence.

