函数身份

为了安全起见,Google Cloud 中实体之间的大多数交互都要求每个实体都有一个可验证的身份,并由某种 Secret(如密码或密钥)保护。正如其他实体需要身份才能访问 Cloud Run functions 一样,函数本身通常需要访问 Google Cloud 中的其他资源才能完成其工作。每个函数都与一个服务账号关联,该服务账号充当函数访问其他资源时的身份。函数用作身份的服务账号也称为“运行时服务账号”

对于生产用途,Google 建议您为每个函数分配用户管理的服务账号来为其提供一个专属身份。通过用户管理的服务账号,您可以使用 Identity and Access Management 授予一组最低权限来控制访问权限。

运行时服务账号

除非您在部署函数时指定其他运行时服务账号,否则 Cloud Run functions 会使用默认服务账号作为其执行函数的身份:

  • Cloud Run functions 使用默认计算服务账号 PROJECT_NUMBER-compute@developer.gserviceaccount.com

    请注意,项目编号与项目 ID 和项目名称不同。您可以在 Google Cloud 控制台的“信息中心”页面上找到项目编号。

根据您的组织政策配置,默认服务账号可能会自动获得项目的 Editor 角色。我们强烈建议您通过强制执行 iam.automaticIamGrantsForDefaultServiceAccounts 组织政策限制条件来停用自动角色授予功能。如果您的组织是在 2024 年 5 月 3 日之后创建的,则默认情况下会强制执行此限制条件。

如果您停用自动角色授予功能,则必须决定向默认服务账号授予哪些角色,然后自行授予这些角色

如果默认服务账号已具有 Editor 角色,我们建议您将 Editor 角色替换为权限较少的角色。如需安全地修改服务账号的角色,请使用 Policy Simulator 查看更改的影响,然后授予和撤消相应的角色

为确保您的函数在生产环境中的安全,请执行以下操作:

更改默认运行时服务账号的权限

控制台

  1. 进入 Google Cloud 控制台中的 IAM 页面:

    转到 Google Cloud 控制台

  2. 从表中选择 App Engine 默认服务账号或默认计算服务账号

  3. 点击对应行右侧的铅笔图标,以显示修改权限标签页。

  4. 通过角色下拉列表添加或移除角色,以提供最小访问权限。

  5. 点击保存

gcloud

移除 Editor 角色,然后使用 gcloud projects add-iam-policy-binding 命令添加新角色:

# Remove the Editor role
gcloud projects remove-iam-policy-binding PROJECT_ID \
--member="SERVICE_ACCOUNT_EMAIL" \
--role="roles/editor"

# Add the desired role
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="SERVICE_ACCOUNT_EMAIL" \
--role="ROLE"

其中 PROJECT_ID 是您使用的项目的 ID,SERVICE_ACCOUNT_EMAIL 是默认运行时服务账号的电子邮件地址(如前面的运行时服务账号所示),ROLE 是分配给默认运行时服务账号的新角色。

为函数使用单独的服务账号

为了让您能够更灵活地控制函数的访问权限,您可以为它们各提供一个用户管理的服务账号。

  1. 创建您的服务账号。记下其名称。
  2. 根据函数完成其工作所需的资源,向其授予相应角色
  3. 如果服务账号和函数位于不同项目中,则来自服务账号所在的项目:

    1. 配置服务账号以跨项目工作。
    2. 向 Cloud Run Service Agent (service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com) 授予 Service Account Token Creator 角色 (roles/iam.serviceAccountTokenCreator),其中 PROJECT 是指函数所在的项目。Cloud Run Service Agent 用于管理您的服务账号的跨项目访问权限。

    3. 向不同项目中的服务账号的 Cloud Run functions Service Agent (service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com) 授予 iam.serviceaccounts.actAs 权限。

  4. 向服务账号授予资源的访问权限。执行此操作的方法取决于资源类型。

  5. 将服务账号与您的函数相关联。您可以在部署时执行此操作,也可以通过更新先前部署的函数来执行。

在部署时添加用户管理的服务账号

控制台

  1. 转到 Google Cloud 控制台:

    转到 Google Cloud 控制台

  2. 根据需要指定和配置函数。

  3. 点击运行时、构建...以显示更多设置。

  4. 选择运行时标签页。

  5. 点击服务账号下拉列表,然后选择所需的服务账号。

  6. 点击下一步部署

gcloud

使用 gcloud functions deploy 部署函数时,添加 --service-account 标志。例如:

gcloud functions deploy FUNCTION_NAME --service-account SERVICE_ACCOUNT_EMAIL

其中,FUNCTION_NAME 是您的函数名称,SERVICE_ACCOUNT_EMAIL 是服务账号电子邮件地址。

更新现有函数的服务账号

您可以更新现有函数的运行时服务账号。

控制台

  1. 转到 Google Cloud 控制台:

    转到 Google Cloud 控制台

  2. 点击所需函数的名称转到其详情页面。

  3. 点击详情页面顶部的修改铅笔图标以修改该函数。

  4. 点击运行时、构建...以显示更多设置。

  5. 选择运行时标签页。

  6. 点击服务账号下拉列表,然后选择所需的服务账号。

  7. 点击下一步部署

gcloud

使用 gcloud functions deploy 部署函数时,添加 --service-account 标志:

gcloud functions deploy FUNCTION_NAME --service-account SERVICE_ACCOUNT_EMAIL

其中,FUNCTION_NAME 是您的函数名称,SERVICE_ACCOUNT_EMAIL 是服务账号。

重新部署的函数现在使用新的运行时服务账号。

使用元数据服务器获取令牌

虽然在 Google Cloud 中用于管理访问权限的 IAM 定义的服务账号是首选方法,但某些服务可能需要其他模式,例如 API 密钥、OAuth 2.0 客户端或服务账号密钥。访问外部资源可能还需要使用其他方法。

如果您的目标服务要求您提供 OpenID Connect ID 令牌或 OAuth 2.0 访问令牌,您可以使用计算元数据服务器提取这些令牌,而不是设置完整的 OAuth 客户端。

身份令牌

您可以使用计算元数据服务器提取具有特定目标设备的 ID 令牌,如下所示:

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE" \
  -H "Metadata-Flavor: Google"

其中,AUDIENCE 是请求的目标(例如,所调用服务的网址(如 https://service.domain.com)),或受 IAP 保护的资源的 OAuth 客户端 ID(例如 1234567890.apps.googleusercontent.com)。

访问令牌

OAuth 2.0 访问令牌使用范围来定义访问权限。默认情况下,在 Google Cloud 访问令牌中,范围是 cloud-platform。如需访问其他 Google 或 Google Cloud API,您需要提取具有适当范围的访问令牌。

您可以使用计算元数据服务器来提取访问令牌

如果需要具有特定范围的访问令牌,您可以按如下方式生成一个:

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token?scopes=SCOPES" \
  -H "Metadata-Flavor: Google"

其中,SCOPES 是所请求 OAuth 范围的列表(以英文逗号分隔),例如 https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/spreadsheets

如需查找所需的范围,请参阅完整的 Google OAuth 范围列表。

后续步骤

了解如何授予对函数的访问权限或对开发者和其他函数进行身份验证,以便他们能够调用函数。