使用不同 GCP 项目 ID 的 Cloud Function 访问资源

Cloud Function 拥有其自身的身份,该身份需要具备访问所需资源的权限。当 Cloud Function 所在的 GCP 项目与需要访问的资源(例如,存储在另一个项目中的 Secret)所在的 GCP 项目不同时,需要正确配置权限。切勿尝试为同一个 Cloud Function 指定多个身份,这通常会导致问题,并且不是推荐的做法。

授权 Cloud Function 服务账号访问资源

解决跨项目资源访问问题的关键在于,授予 Cloud Function 的服务账号访问所需资源的权限。Cloud Function 运行时会使用一个服务账号来代表其身份。你需要找到这个服务账号,并授予它访问目标项目资源的权限。

步骤如下:

  1. 找到 Cloud Function 的服务账号: 在 Cloud Function 的配置页面,你可以找到该 Function 使用的服务账号。通常,它的格式类似于 PROJECT_ID@appspot.gserviceaccount.com 或 PROJECT_NUMBER-compute@developer.gserviceaccount.com。

  2. 授予权限: 在目标项目(例如,存储 Secrets 的项目)中,将适当的权限授予 Cloud Function 的服务账号。这可以通过 IAM & Admin 页面完成。

    • 例如,如果 Cloud Function 需要访问 Secret Manager 中的 Secret,你需要在 Secret Manager 中授予该服务账号 Secret Manager Secret Accessor 角色。

示例:

假设 Cloud Function 位于 com-project-common 项目中,其服务账号为 com-project-common@appspot.gserviceaccount.com。并且你需要访问位于 com-project-data 项目中的一个 Secret。

  1. 在 com-project-data 项目的 Secret Manager 中,找到你要访问的 Secret。
  2. 点击 Secret 的 "Permissions" 标签。
  3. 添加 com-project-common@appspot.gserviceaccount.com 并授予其 Secret Manager Secret Accessor 角色。

代码示例 (Python):

from google.cloud import secretmanager

def hello_world(request):
    """Responds to any HTTP request.
    Args:
        request (flask.Request): HTTP request object.
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using
        `make_response `.
    """
    project_id = "com-project-data" # Project containing the secret
    secret_id = "my-secret"
    version_id = "latest"

    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
    response = client.access_secret_version(request={"name": name})

    secret_value = response.payload.data.decode("UTF-8")

    return f"The secret value is: {secret_value}"

注意事项:

  • 确保 Cloud Function 的服务账号拥有访问所需资源的最小权限。避免授予过于宽泛的角色,例如 roles/owner。
  • 使用环境变量或 Secret Manager 来存储敏感信息,例如数据库密码。不要将这些信息硬编码到代码中。
  • 定期审查和更新 Cloud Function 的权限,以确保其安全。

避免使用服务账号密钥文件

虽然可以通过使用服务账号密钥文件来模拟不同的身份,但这是一种非常糟糕的做法,应该避免。使用密钥文件会带来以下风险:

  • 安全风险: 密钥文件如果被泄露,可能会被恶意用户利用。
  • 管理复杂性: 管理多个密钥文件会变得非常复杂,容易出错。
  • 不符合最佳实践: 使用密钥文件不是 Cloud Functions 的推荐做法。

总结

通过正确配置 Cloud Function 的服务账号权限,可以安全地访问不同 GCP 项目中的资源。避免使用服务账号密钥文件,并遵循最佳实践,可以确保 Cloud Function 的安全性和可维护性。授予 Cloud Function 服务账号访问所需资源的权限,是解决跨项目资源访问问题的推荐方法。