Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

What Pub/Sub permissions do I need to create a subscription?

I have a Python 3.9 Cloud Function that is using the Cloud SDK to create Pub/Sub subscriptions. I'm having trouble determining what permissions I need to create a Pub/Sub subscription. The documentation shows the roles/pubsub.editor should be sufficient for creating subscriptions and attaching them to topics. However, when giving my service account being used by the Cloud Function the pubsub.editor role at the project level, I get this error when trying to create a subscription:

 

 

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "status": {
      "code": 7,
      "message": "User not authorized to perform this action."
    },
    "authenticationInfo": {
      "principalEmail": "person-api@<redacted>.iam.gserviceaccount.com",
      "serviceAccountDelegationInfo": [
        {
          "firstPartyPrincipal": {
            "principalEmail": "service-<redacted>@gcf-admin-robot.iam.gserviceaccount.com"
          }
        }
      ],
      "principalSubject": "serviceAccount:person-api@<redacted>.iam.gserviceaccount.com"
    },
    "requestMetadata": {
      "callerIp": "<redacted>",
      "callerSuppliedUserAgent": "grpc-python/1.50.0 grpc-c/28.0.0 (linux; chttp2),gzip(gfe)",
      "requestAttributes": {
        "time": "2022-10-31T22:24:28.743102902Z",
        "auth": {}
      },
      "destinationAttributes": {}
    },
    "serviceName": "pubsub.googleapis.com",
    "methodName": "google.pubsub.v1.Subscriber.CreateSubscription",
    "authorizationInfo": [
      {
        "resource": "projects/<redacted>",
        "permission": "pubsub.subscriptions.create",
        "granted": true,
        "resourceAttributes": {}
      }
    ],
    "resourceName": "projects/<redacted>/subscriptions/person-api-webhook-5a5e7a18-cd48-44e5-b241-d84b97484fda",
    "request": {
      "retainAckedMessages": true,
      "topic": "projects/<redacted>/topics/person-api-webhook-events",
      "ackDeadlineSeconds": 10,
      "name": "projects/<redacted>/subscriptions/person-api-webhook-5a5e7a18-cd48-44e5-b241-d84b97484fda",
      "@type": "type.googleapis.com/google.pubsub.v1.Subscription",
      "messageRetentionDuration": "604800s",
      "pushConfig": {
        "pushEndpoint": "<redacted>"
      }
    }
  },
  "insertId": "<redacted>",
  "resource": {
    "type": "pubsub_subscription",
    "labels": {
      "subscription_id": "projects/<redacted>/subscriptions/person-api-webhook-5a5e7a18-cd48-44e5-b241-d84b97484fda",
      "project_id": "<redacted>"
    }
  },
  "timestamp": "2022-10-31T22:24:28.735840698Z",
  "severity": "ERROR",
  "logName": "projects/<redacted>/logs/cloudaudit.googleapis.com%2Factivity",
  "receiveTimestamp": "2022-10-31T22:24:29.203119649Z"
}

 

 

I also tried giving the service account the pubsub.admin role and continued to get the same error. It wasn't until I assigned the service account the project editor role (don't worry, just for troubleshooting purposes) that I was able to successfully create a subscription from my cloud function.

Now for the extra weird part: I'm able to create a subscription from the command line while impersonating the service account when the service account only has the pubsub.editor role at the project level: gcloud pubsub subscriptions create my-subscription --impersonate-service-account=person-api@<redacted>.iam.gserviceaccount.com --topic=person-api-webhook-events

Additionally, if I login to the GCP console with a user that only has the pubsub.editor role, I'm also able to create a subscription. It seems like this issue is scoped to creating subscriptions from Cloud Functions.

Here is my python code in case it might be relevant to the issue. I hope it gives enough information to replicate the issue. google-cloud-pubsub version is 2.11.1

 

 

from google.cloud import pubsub_v1
from google.cloud.pubsub_v1.types import Subscription, PushConfig, ExpirationPolicy, RetryPolicy, Duration, DeleteSubscriptionRequest
project_id = "<redacted>"
subscriber = pubsub_v1.SubscriberClient()
subscription_name = subscriber.subscription_path(project_id, "person-api-webhook-5a5e7a18-cd48-44e5-b241-d84b97484fda")
oidc_token = PushConfig.OidcToken(audience="https://<redacted>.cloudfunctions.net/webhook_proxy", service_account_email="person-api-webhook-subscriber@<redacted>.iam.gserviceaccount.com")
topic_id = "projects/<redacted>/topics/person-api-webhook-events"
subscription_request = Subscription(
    name=subscription_name,
    topic=topic_id,
    push_config=PushConfig(push_endpoint="https://<redacted>.cloudfunctions.net/webhook_proxy/5a5e7a18-cd48-44e5-b241-d84b97484fda", oidc_token=oidc_token),
    message_retention_duration=Duration(seconds=604800),
    retain_acked_messages=True,
    expiration_policy=ExpirationPolicy(ttl=Duration(seconds=2678400)),
    ack_deadline_seconds=10,
    filter=None,
    enable_exactly_once_delivery=False,
    enable_message_ordering=False,
    dead_letter_policy=None,
    retry_policy=RetryPolicy(
        minimum_backoff=Duration(seconds=10),
        maximum_backoff=Duration(seconds=600)
    )
)
with subscriber:
    subscriber.create_subscription(request=subscription_request)

 

 

 

Solved Solved
2 9 11.3K
1 ACCEPTED SOLUTION

Just to close the loop on this, the issue was that the service account we were using to create the pubsub subscription did not have the `iam.serviceAccounts.actAs` permission. This is documented here: 

View solution in original post

9 REPLIES 9