Pub/Sub sits between services, so a single over-broad grant on a topic or subscription lets one identity inject events into, or read events from, systems it was never meant to touch. Securing it is a set of customer-side choices: which roles go on which topics and subscriptions, how push endpoints prove a request really came from Pub/Sub, which identity writes to BigQuery or Cloud Storage for export subscriptions, where messages are stored, and how keys and perimeters wrap it all. This guide covers those controls for platform engineers, application security engineers and cloud reviewers who run event-driven systems on Google Cloud. For the wider platform baseline, read the Google Cloud Security Guide first.
This is an independent guide from NHI Mgmt Group, based on Google Cloud's public documentation as of November 2026. It is not sponsored or reviewed by Google. Product features change, so confirm settings against Google Cloud's current documentation.
Key takeaways
- Grant on the topic and the subscription, not the project. Publisher on one topic and Subscriber on one subscription is the normal shape for a service; project-wide Editor lets it read and write every stream.
- Authenticate every push subscription. Configure a push auth service account so Pub/Sub sends a signed OIDC token, and have the endpoint verify the signature, audience, email and issuer.
- Cross-project access is two grants. A subscription in project A on a topic in project B needs rights in project A and on topic B, which gives you a clean point of control for each data flow.
- Message operations need their own monitoring. Admin Activity logs record topic, subscription and IAM changes; publish and pull are tracked through Cloud Monitoring metrics and application logging.
- Use dedicated identities for export. BigQuery and Cloud Storage subscriptions can write as a user-managed service account, which keeps write access to the destination tied to that one subscription.
How identity and access work in Pub/Sub
Pub/Sub uses Google Cloud IAM. Every publisher, subscriber and administrator is a Google principal: a user, group, service account or federated workload identity. Policies can be set on the project (through the IAM page) and on individual topics, subscriptions, snapshots and schemas (through the Pub/Sub IAM API or the resource's Permissions tab). Resource-level grants are the way to express "this service may publish to this topic only".
| Role | Role ID | What it allows | Lowest grant level |
|---|---|---|---|
| Pub/Sub Publisher | roles/pubsub.publisher | Publish to a topic (pubsub.topics.publish only) | Topic |
| Pub/Sub Subscriber | roles/pubsub.subscriber | Consume from a subscription, seek to snapshots, attach subscriptions to a topic | Snapshot, subscription, topic |
| Pub/Sub Viewer | roles/pubsub.viewer | View topics, subscriptions, schemas and snapshots | Schema, snapshot, subscription, topic |
| Pub/Sub Editor | roles/pubsub.editor | Create and modify topics and subscriptions, publish and consume; excludes setting IAM policy | Schema, snapshot, subscription, topic |
| Pub/Sub Admin | roles/pubsub.admin | Full control including IAM policy on Pub/Sub resources | Schema, snapshot, subscription, topic |
| Cloud Pub/Sub Service Agent | roles/pubsub.serviceAgent | Lets the Pub/Sub service agent manage resources | Service agent only; never grant to people |
Two details shape day-to-day design. First, Subscriber on a topic carries pubsub.topics.attachSubscription, which lets the holder create a new subscription on that topic and so receive its messages. Grant Subscriber on the subscription for consumers, and on the topic only to the team that provisions subscriptions. Second, testIamPermissions is meant for permission-aware user interfaces; Google warns it may fail open, so never use it as an authorisation check in your own code.
Cross-project access
Event flows often cross project boundaries: a shared events project publishes, and consumer projects subscribe. To create subscription S in project A attached to topic T in project B, the creator needs permission to create subscriptions in project A and to attach to topic T. Google notes that the subscribing identity can then appear in project B's audit logs, which gives the topic owner visibility of who attached. Use this pattern deliberately:
- Topic owner controls attachment: grant Subscriber on the topic to the consuming project's provisioning service account, not to all of its users.
- Consumer controls reading: inside project A, grant Subscriber on subscription S only to the workload that processes it.
- Publish across projects narrowly: grant Publisher on topic T to the named service account in the producing project, never to a whole domain.
- Keep sharing inside the organisation: enforce the
iam.allowedPolicyMemberDomainsorganisation policy so topics cannot be shared withallUsers,allAuthenticatedUsersor outside identities. See the Google Cloud Organization Policy Guide.
Admin roles and privileged access
The privileged operations in Pub/Sub are changing IAM on a topic or subscription, changing a subscription's push endpoint or auth identity, detaching subscriptions, seeking (which replays or skips messages), and deleting topics. Each can redirect or drop events.
- Hold Admin in a small group:
roles/pubsub.adminis the role that can set IAM policy on topics and subscriptions. Keep it off application service accounts and grant it just in time where possible. - Use Editor for provisioning pipelines only: infrastructure-as-code service accounts need Editor to create topics and subscriptions; runtime services do not.
- Govern push endpoint changes:
ModifyPushConfigandUpdateSubscriptioncan point a subscription at a new URL. Treat them as change-controlled operations and alert on them. - Govern actAs on push and export identities: anyone who creates or updates a subscription with a push auth or export service account needs
iam.serviceAccounts.actAson it (for example throughroles/iam.serviceAccountUser). Grant that on the specific service account, not the project. - Protect seek and snapshots: Seek can replay retained messages to a subscriber; restrict snapshot and seek rights to operators who need replay for recovery.
Integrations, API tokens and service accounts
Pub/Sub is mostly used by non-human identities: services publishing events, workers pulling them, the Pub/Sub service agent signing push tokens and writing exports. Each needs a distinct identity with one job. For the wider pattern, see the Google Cloud IAM and Service Accounts Guide.
Push authentication with OIDC tokens
For a push subscription, configure a push auth service account. Pub/Sub then signs an OpenID Connect JWT for that account and sends it in the Authorization: Bearer header of each request. The signer is the Pub/Sub service agent, [email protected], which Google documents as needing roles/iam.serviceAccountTokenCreator (or iam.serviceAccounts.getOpenIdToken) on the push auth service account or an ancestor. Grant it on the specific service account rather than the project where you can. Steps for a secure push endpoint:
- Create a dedicated push auth service account per subscription or per receiving service.
- Set an explicit audience with
--push-auth-token-audience(for example the endpoint URL), so a token minted for one endpoint is rejected by another. - At the endpoint, verify the JWT signature against Google's keys, check that
audmatches your audience, thatemailis the expected service account withemail_verifiedtrue, and thatissishttps://accounts.google.com. Tokens can be up to an hour old, so accept that window and no more. - Where the endpoint is on Google Cloud, let the platform do the check: grant the push auth account
roles/run.invokeron the target Cloud Run service,roles/cloudfunctions.invokerfor HTTP-triggered functions, or the IAP-secured Web App User role for an App Engine app behind IAP (using the IAP client ID as the audience). - Keep the endpoint on HTTPS and acknowledge only after processing; any response other than 102, 200, 201, 202 or 204 is a negative acknowledgement and the message is redelivered.
A shared secret in a query string is an application-level extra, not a replacement for JWT validation. See the Cloud Run and Cloud Functions Security Guide for invoker IAM and ingress settings on the receiving side.
Identity map
| Integration | Identity | Grant | Hardened setting |
|---|---|---|---|
| Publishing service | The service's own service account | Publisher on the topic | One service account per service; no project-level Pub/Sub roles |
| Pull consumer | Worker service account | Subscriber on the subscription | Grant on the subscription, not the topic |
| Push delivery | Push auth service account, signed by the Pub/Sub service agent | Invoker on the target; Token Creator for the service agent | Explicit audience; endpoint verifies all claims |
| BigQuery subscription | Pub/Sub service agent by default, or a user-managed service account | roles/bigquery.dataEditor on the table | Use a user-managed service account with table-level Data Editor |
| External publisher (on-premises, other cloud) | Federated principal | Publisher on the topic | Workload Identity Federation instead of service account keys. See the Cloud Workload Identity Guide. |
The export identity matters. Google cautions that granting BigQuery Data Editor to the default Pub/Sub service agent lets anyone who can create subscriptions in the project write to that table. With a user-managed service account, the Pub/Sub service agent needs iam.serviceAccounts.getAccessToken on it and the creator needs actAs, so write access to each destination stays tied to an identity you chose. See BigQuery Security Guide for the destination side.
Logging and detection
Pub/Sub writes Admin Activity audit logs for configuration and IAM changes, and Data Access logs (once turned on) for reads such as Get and List calls and Seek. As of November 2026 Google's audit logging page describes message operations (publish, pull, acknowledge and StreamingPull) as observed through Cloud Monitoring metrics and the application's own logs rather than audit log entries, so plan both sources. Route audit logs to a central sink; see the Google Cloud Audit Logs and Log Sinks Guide.
| Event | Method | Log type | Alert on |
|---|---|---|---|
| IAM change on a topic or subscription | google.iam.v1.IAMPolicy.SetIamPolicy | Admin Activity | New members outside the organisation, any public member, Publisher or Subscriber added to an unexpected identity |
| New subscription | google.pubsub.v1.Subscriber.CreateSubscription | Admin Activity | Subscriptions on sensitive topics created by unexpected principals or from other projects |
| Push endpoint change | ModifyPushConfig, UpdateSubscription | Admin Activity | Endpoint URL or push auth account changes outside change windows |
| Detach subscription | google.pubsub.v1.Publisher.DetachSubscription | Admin Activity | Unplanned detachment of consumers |
| Topic changes | UpdateTopic, DeleteTopic | Admin Activity | Removed CMEK or changed message storage policy |
| Replay | google.pubsub.v1.Subscriber.Seek | Data Access | Seeks outside planned recovery work |
For message-level visibility, monitor publish and delivery request counts per topic and subscription, unacknowledged message age, and dead-letter topic volume. A sudden publish rate from a new principal or a spike in dead-lettered messages is worth an alert. Map detections to MITRE ATT&CK T1078.004 Cloud Accounts for misuse of a service account identity.
Metrics that show it is working
- Share of Pub/Sub grants made at topic or subscription level rather than project level.
- Push subscriptions without a push auth service account (target: zero).
- Export subscriptions writing as the default service agent rather than a user-managed account (target: zero).
- Topics carrying regulated data that have CMEK and a message storage policy set (target: all).
- Members from outside the organisation on any topic or subscription (target: zero, or documented partner exceptions).
Hardening baseline
Apply in this order, testing each step on a non-production topic first. Before each IAM change, save the current policy with gcloud pubsub topics get-iam-policy or gcloud pubsub subscriptions get-iam-policy so you can restore it.
- Inventory: list topics, subscriptions (with type: pull, push, BigQuery, Cloud Storage), push endpoints, auth identities and IAM bindings across projects.
- Move grants down: replace project-level Editor and Publisher grants with Publisher on named topics and Subscriber on named subscriptions.
- Authenticate push: add a push auth service account and audience to every push subscription, then turn on token verification at each endpoint.
- Move exports to dedicated identities: switch BigQuery and Cloud Storage subscriptions to user-managed service accounts with destination-level grants.
- Set storage location: for data residency, set
--message-storage-policy-allowed-regionson topics and turn onenforceInTransitso requests in disallowed regions are rejected. Organisation policy changes apply to new topics, so for existing topics run--recompute-message-storage-policyafter changing the Resource Location Restriction policy. - Apply CMEK where required: create or update topics with
--topic-encryption-key, grantingroles/cloudkms.cryptoKeyEncrypterDecrypterto the Pub/Sub service agent. Google recommends global keys because Pub/Sub resources are global. Disabling the key stops publishing and delivery for that topic, which is also a documented emergency lever. See the Cloud KMS and Cloud HSM Guide. - Add a perimeter: include
pubsub.googleapis.comin the VPC Service Controls perimeter around event-processing projects, and check Google's supported products page for the documented behaviour of push and export subscriptions inside a perimeter before enforcing. Run the perimeter in dry-run mode first. See the VPC Service Controls Guide. - Handle failures safely: configure dead-letter topics with their own restricted IAM, because failed messages often carry the most sensitive payloads.
- Log and alert: route Admin Activity logs to a sink and alert on the events above; add Monitoring alerts for message metrics.
Decision guidance
| Decision | Option A | Option B | Choose A when |
|---|---|---|---|
| Delivery | Pull | Push | Consumers run in your own network and you prefer outbound-only connections; choose push for serverless receivers with IAM-checked invocation |
| Topic layout | Central events project | Topics in each producer project | Many consumers across teams need governed attachment; choose B for small estates with few flows |
| Encryption | Google-owned keys | CMEK | No regulatory key-control requirement; choose CMEK where policy requires customer key control or a kill switch |
| Export identity | Default service agent | User-managed service account | Short-lived test projects only; choose B everywhere else |
Framework mapping
| Control area | Pub/Sub setting | NIST SP 800-53 Rev 5 |
|---|---|---|
| Least privilege | Topic and subscription-level roles | AC-6, AC-3 |
| Authenticated service calls | Push OIDC tokens with audience checks | IA-9 |
| Machine credentials | Federation instead of keys; dedicated export identities | IA-5, AC-2 |
| Encryption and residency | CMEK, message storage policy | SC-28, SC-12 |
| Boundary protection | VPC Service Controls | SC-7 |
| Audit | Admin Activity logs and message metrics | AU-2, AU-6 |
Common misconfigurations
- Project-level Editor for application services: every service can then read every subscription and publish to every topic. Use Publisher and Subscriber on named resources.
- Push endpoints that accept unsigned requests: an endpoint that processes any POST it receives will accept forged events. Configure push auth and verify the token, including the audience.
- Audience left unchecked: verifying only the signature accepts any Google-signed token. Check
aud,emailandissevery time. - Subscriber granted on the topic to consumers: this lets them attach new subscriptions. Grant on the subscription instead.
- Exports writing as the default service agent: anyone who can create a subscription can write to the destination table. Use a user-managed service account.
- Token Creator granted to the service agent at project level for convenience: scope it to the push auth service accounts where your setup allows.
Practitioner checklist
- Replace project-level Pub/Sub grants with Publisher on topics and Subscriber on subscriptions.
- Enforce domain restricted sharing so no topic or subscription can be shared publicly or outside the organisation.
- Give every push subscription a dedicated push auth service account and explicit audience, and verify all token claims at the endpoint.
- Run BigQuery and Cloud Storage subscriptions as user-managed service accounts with destination-level grants.
- Restrict Admin, actAs on push and export identities, and Seek to small named groups.
- Set message storage policies with enforceInTransit for residency, and CMEK where key control is required.
- Protect dead-letter topics with their own IAM.
- Alert on SetIamPolicy, CreateSubscription from other projects, ModifyPushConfig and DetachSubscription, and monitor message metrics.
Standards and references
- Google Cloud: Access control with IAM for Pub/Sub
- Google Cloud: Authenticate push subscriptions
- Google Cloud: Pub/Sub audit logging
- Google Cloud: Configure message encryption
- Google Cloud: Configure message storage policies
- Google Cloud: Create BigQuery subscriptions
- Google Cloud: Push subscriptions
- NIST: SP 800-53 Rev 5 Security and Privacy Controls
Related NHI Mgmt Group resources: Google Cloud Security Guide · Google Cloud IAM and Service Accounts Guide · Cloud Run and Cloud Functions Security Guide · VPC Service Controls Guide