Cloud Function v2被Pub/Sub触发时遭遇403认证错误求助
Cloud Function v2 触发Pub/Sub事件时出现403未认证错误
问题描述
我创建了一个由Pub/Sub主题的messagePublished事件触发的Cloud Function v2,但每次触发都会返回403错误,错误日志如下:
{ "httpRequest": { "latency": "0s", "protocol": "HTTP/1.1", "remoteIp": "xx.xxx.xx.xx", "requestMethod": "POST", "requestSize": "3912", "requestUrl": "https://handler-function-cloud-custodian-xxxxxx-uc.a.run.app/?__GCP_CloudEventsMode=CUSTOM_PUBSUB_projects%2Fchase-test-custodian%2Ftopics%2Fevent-topic-cloud-custodian", "serverIp": "xxx.xxx.xx.xx", "status": 403, "userAgent": "APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)" }, "insertId": "xxxxx", "labels": { "goog-managed-by": "cloudfunctions" }, "logName": "projects/chase-test-custodian/logs/run.googleapis.com%2Frequests", "receiveTimestamp": "2023-01-30T17:45:14.427320714Z", "resource": { "labels": {}, "type": "cloud_run_revision" }, "severity": "WARNING", "spanId": "xxxxxx", "textPayload": "The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client", "timestamp": "2023-01-30T17:45:14.422306Z", "trace": "projects/chase-test-custodian/traces/xxxxxx" }
我尝试给该云函数添加了带有「Cloud Functions Invoker」角色的「allUsers」主体,但问题依旧。订阅通过Terraform创建,相关配置如下:
resource "google_pubsub_topic" "event_topic" { name = "event-topic-cloud-custodian" } resource "google_pubsub_subscription" "event_subscription" { name = "event-subscription-cloud-custodian" topic = google_pubsub_topic.event_topic.name push_config { push_endpoint = google_cloudfunctions2_function.handler.service_config.uri # 若指定了自定义服务账号,需确保其具备对应权限 # service_account_email = "custom-sa@${var.project_id}.iam.gserviceaccount.com" } } resource "google_cloudfunctions2_function" "handler" { name = "handler-function-cloud-custodian" location = "us-central1" description = "Cloud Function triggered by Pub/Sub" build_config { runtime = "python310" entry_point = "handler" source { storage_source { bucket = "your-function-bucket" object = "function-source.zip" } } } service_config { available_memory = "256Mi" timeout_seconds = 60 } event_trigger { event_type = "google.cloud.pubsub.topic.v1.messagePublished" topic = "projects/${var.project_id}/topics/${google_pubsub_topic.event_topic.name}" } }
解决方案
Cloud Function v2基于Cloud Run托管,权限体系遵循Cloud Run规则,而非传统Cloud Function v1。问题核心是Pub/Sub的推送服务账号没有权限调用对应的Cloud Run服务,而非云函数本身的权限问题。
步骤1:确定Pub/Sub使用的服务账号
- 若未在Terraform的
push_config中指定service_account_email,则使用Pub/Sub默认服务账号:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com - 若指定了自定义服务账号,则使用该账号
步骤2:授予Cloud Run Invoker角色
给上述服务账号授予roles/run.invoker角色,绑定到Cloud Function对应的Cloud Run服务上:
# 替换为你的项目ID和Cloud Run服务名 PROJECT_ID="chase-test-custodian" PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)') PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" CLOUD_RUN_SERVICE="handler-function-cloud-custodian-xxxxxx-uc" gcloud run services add-iam-policy-binding $CLOUD_RUN_SERVICE \ --member="serviceAccount:$PUBSUB_SERVICE_ACCOUNT" \ --role="roles/run.invoker" \ --region="us-central1"
步骤3:Terraform配置优化(可选)
若要通过Terraform自动化配置权限,可以添加以下资源:
data "google_project" "current" {} resource "google_cloud_run_service_iam_binding" "pubsub_invoker" { service = google_cloudfunctions2_function.handler.service_config.service location = google_cloudfunctions2_function.handler.location role = "roles/run.invoker" members = [ "serviceAccount:service-${data.google_project.current.number}@gcp-sa-pubsub.iam.gserviceaccount.com", ] }
关键说明
- 不要混淆
Cloud Functions Invoker和Cloud Run Invoker角色:Cloud Function v2底层是Cloud Run,因此需要授予roles/run.invoker而非roles/cloudfunctions.invoker - 给
allUsers添加权限虽然能临时解决问题,但存在安全风险,不建议在生产环境使用
内容的提问来源于stack exchange,提问作者Cdhippen
相关产品推荐
相关产品推荐

