使用 IAM 对组织资源进行访问权限控制

Google Cloud 提供 Identity and Access Management (IAM),可让您授予对特定 Google Cloud 资源的更精细访问权限,并防止对其他资源进行不必要的访问。IAM 允许您采用 最小权限安全原则, 因此您只需授予对您的资源的必要访问权限即可。

IAM 允许您通过设置允许政策来控制谁(用户)哪些资源 具有什么访问权限(角色) 。您可以使用允许政策向用户授予特定 角色,给予用户某些权限。

本页面介绍在 组织资源上使用的 IAM 角色,以及如何使用 Cloud Resource Manager API 为 组织资源创建和管理允许政策。如需了解详情,请参阅 管理对项目、文件夹和组织的访问权限

权限和角色

为了控制对资源的访问权限, Google Cloud 要求发出 API 请求的账号具有适当的 IAM 角色。IAM 角色 包含允许用户对 Google Cloud 资源执行特定操作的权限。例如, resourcemanager.organizations.get权限允许用户获取有关其组织资源的详细信息。

您不直接授予用户权限,而是向其授予 角色(角色自带一个或多个权限)。

您可以针对同一项资源授予一个或多个角色。

使用预定义角色

下表列出了您可以授予的角色,以访问组织资源的属性、角色的功能说明以及该角色中捆绑的权限。

角色 权限

(roles/resourcemanager.organizationAdmin)

拥有管理 IAM 政策以及查看组织、文件夹和项目的组织政策的权限。

您可以授予此角色的最低级层资源:

  • 项目

essentialcontacts.*

  • essentialcontacts.contacts.create
  • essentialcontacts.contacts.delete
  • essentialcontacts.contacts.get
  • essentialcontacts.contacts.list
  • essentialcontacts.contacts.send
  • essentialcontacts.contacts.update

iam.policybindings.*

  • iam.policybindings.get
  • iam.policybindings.list

orgpolicy.constraints.list

orgpolicy.policies.list

orgpolicy.policy.get

resourcemanager.capabilities.*

  • resourcemanager.capabilities.get
  • resourcemanager.capabilities.update

resourcemanager.folders.createPolicyBinding

resourcemanager.folders.deletePolicyBinding

resourcemanager.folders.get

resourcemanager.folders.getIamPolicy

resourcemanager.folders.list

resourcemanager.folders.searchPolicyBindings

resourcemanager.folders.setIamPolicy

resourcemanager.folders.updatePolicyBinding

resourcemanager.organizations.*

  • resourcemanager.organizations.createPolicyBinding
  • resourcemanager.organizations.deletePolicyBinding
  • resourcemanager.organizations.get
  • resourcemanager.organizations.getIamPolicy
  • resourcemanager.organizations.searchPolicyBindings
  • resourcemanager.organizations.setIamPolicy
  • resourcemanager.organizations.updatePolicyBinding

resourcemanager.projects.createPolicyBinding

resourcemanager.projects.deletePolicyBinding

resourcemanager.projects.get

resourcemanager.projects.getIamPolicy

resourcemanager.projects.list

resourcemanager.projects.searchPolicyBindings

resourcemanager.projects.setIamPolicy

resourcemanager.projects.updatePolicyBinding

(roles/resourcemanager.organizationViewer)

提供查看组织的权限。

您可以授予此角色的最低级层资源:

  • 组织

resourcemanager.organizations.get

roles/orgpolicy.policyAdmin

提供通过设置组织政策来指定组织要对云端资源的配置实施哪些限制的权限。

您可以授予此角色的最低级层资源:

  • 组织

cloudasset.assets.analyzeOrgPolicy

cloudasset.assets.exportResource

cloudasset.assets.listResource

cloudasset.assets.searchAllResources

orgpolicy.*

  • orgpolicy.constraints.list
  • orgpolicy.customConstraints.create
  • orgpolicy.customConstraints.delete
  • orgpolicy.customConstraints.get
  • orgpolicy.customConstraints.list
  • orgpolicy.customConstraints.update
  • orgpolicy.policies.create
  • orgpolicy.policies.delete
  • orgpolicy.policies.list
  • orgpolicy.policies.update
  • orgpolicy.policy.get
  • orgpolicy.policy.set

policysimulator.orgPolicyViolations.list

policysimulator.orgPolicyViolationsPreviews.*

  • policysimulator.orgPolicyViolationsPreviews.create
  • policysimulator.orgPolicyViolationsPreviews.get
  • policysimulator.orgPolicyViolationsPreviews.list

recommender.orgPolicyInsights.*

  • recommender.orgPolicyInsights.get
  • recommender.orgPolicyInsights.list
  • recommender.orgPolicyInsights.update

recommender.orgPolicyRecommendations.*

  • recommender.orgPolicyRecommendations.get
  • recommender.orgPolicyRecommendations.list
  • recommender.orgPolicyRecommendations.update

(roles/browser)

拥有浏览项目层次结构(包括文件夹、组织和允许政策)所需的读取权限。此角色不具备查看项目内资源的权限。

您可以授予此角色的最低级层资源:

  • 项目

resourcemanager.folders.get

resourcemanager.folders.list

resourcemanager.organizations.get

resourcemanager.projects.get

resourcemanager.projects.getIamPolicy

resourcemanager.projects.list

创建自定义角色

除了本主题中介绍的预定义角色以外,您还可以创建 自定义角色,以便根据个人需求量身定制一组 权限。创建用于 Resource Manager 的自定义角色时,请注意以下几点:
  • 列出和获取权限(如 resourcemanager.projects.get/list、 )应始终成对授予。
  • 当您的自定义角色包含 folders.listfolders.get 权限时,它还应包含 projects.listprojects.get.
  • 请注意,组织、文件夹和 项目资源的 setIamPolicy 权限允许用户授予所有其他权限,因此应谨慎分配。

查看组织资源的现有访问权限

您可以通过 获取组织资源的允许政策来查看用户对组织资源被授予了哪些角色。您可以使用 Google Cloud 控制台、Google Cloud CLI、 或 getIamPolicy() 方法查看 组织资源的允许政策。

控制台

如需使用 Google Cloud 控制台查看在组织资源级别授予的角色,请执行以下操作:

  1. 前往控制台中的管理资源页面: Google Cloud

    打开“管理资源” 页面

  2. 组织 下拉列表中,选择您的组织资源。

  3. 选中组织资源的复选框。

  4. 在右侧信息面板权限下方点击一下,以展开 某一角色并显示拥有该角色的所有成员。

gcloud

使用 get-iam-policy 命令获取组织资源的允许政策:

gcloud alpha organizations get-iam-policy [ORGANIZATION_ID] --format json >
[FILENAME.JSON]

该命令会输出允许政策,该政策类似于以下内容:

bindings:
- members:
- user:testuser1@gcp-test.com
role: roles/editor
- members:
- user:admin@gcp-test.com
role:roles/resourcemanager.organizationAdmin
- members:
- user:testuser2@gcp-test.com
role: roles/resourcemanager.projectCreator
etag": "BwU1aRxWk30="

API

以下代码段返回组织 资源 https://cloudresourcemanager.googleapis.com/v3/organizations/12345的允许政策。

请求:

POST
https://cloudresourcemanager.googleapis.com/v3/organizations/12345:getIamPolicy

响应:

{
    "bindings": [
    {
        "role": "roles/resourcemanager.organizationAdmin",
        "members": [
        "user:email1@gmail.com"
    ]
    },
    {
        "role": "roles/resourcemanager.projectCreator",
        "members": [
            "user:email2@gmail.com",
            "user:email3@gmail.com",
            "serviceAccount:my-other-app@appspot.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKHHiQ="
}

Python

借助方法 getIamPolicy() ,您可以获取之前设置的允许政策。

crm = discovery.build(
    'cloudresourcemanager', 'v3', http=creds.authorize(httplib2.Http()))
policy = crm.organizations().getIamPolicy(
    resource=flags.organizationId, body={}).execute()
print json.dumps(policy, indent=2)

授予对组织资源的访问权限

组织管理员可以向团队成员授予 IAM 角色 ,以便他们可以访问组织的资源和 API。您可以向用户账号电子邮件地址、Google 群组、服务帐号或 G Suite 域名授予角色。您可以使用 Google Cloud 控制台、gcloud CLI 或 该 setIamPolicy() 方法来授予角色。

控制台

如需使用 Google Cloud 控制台在组织资源级别设置访问权限控制,请执行以下操作:

  1. 前往控制台中的管理资源页面: Google Cloud

    打开“管理资源” 页面

  2. 组织 下拉列表中,选择您的组织资源。

  3. 选中组织资源的复选框。如果您没有 文件夹资源,则组织资源将不可见。如需 继续操作,请参阅有关通过 IAM 页面授予角色的说明。

  4. 如果右侧的信息面板窗格处于隐藏状态,请点击右上角的显示信息面板

  5. 信息面板窗格的权限标签页中,点击添加成员

  6. 新成员 字段中,输入要添加的团队成员。 您可以指定用户账号电子邮件地址、Google 群组、服务 账号或 G Suite 域名。

  7. 选择角色 下拉列表中,选择您要向团队成员 授予的角色。

  8. 点击添加

gcloud

如需使用 gcloud 命令设置组织资源的允许政策,请执行以下操作:

  1. 使用 get-iam-policy 命令获取组织资源的 IAM 政策,并将该政策输出到 JSON 文件:

    gcloud alpha organizations get-iam-policy [ORGANIZATION_ID]
    --format json > [FILENAME.JSON]
    
  2. JSON 文件的内容将如下所示:

{
    "bindings": [
    {
        "members": [
            "user:testuser1@gcp-test.com"
        ],
        "role": "roles/editor"
    },
    {
        "members": [
            "user:admin@gcp-test.com",
        ],
        "role": "roles/resourcemanager.organizationAdmin"
    },
    {
        "members": [
            "user:testuser2@gcp-test.com"
        ],
        "role": "roles/resourcemanager.projectCreator"
    },
    ],
    "etag": "BwU1aRxWk30="
}
  1. 使用文本编辑器打开 JSON 文件,并向 bindings 数组添加一个新条目来定义 Organization Administrator 角色。例如,如需将 anotheradmin@gcp-test.com设为 Organization Administrator,您可以按如下方式更改 之前的示例:
{
    "bindings": [
    {
        "members": [
            "user:testuser1@gcp-test.com"
        ],
        "role": "roles/editor"
    },
    {
        "members": [
            "user:admin@gcp-test.com",
            "user:anotheradmin@gcp-test.com"
        ],
        "role": "roles/resourcemanager.organizationAdmin"
    },
    {
        "members": [
            "user:testuser20@gcp-test.com"
        ],
        "role": "roles/resourcemanager.projectCreator"
    },
    ],
    "etag": "BwU1aRxWk30="
}
  1. 运行以下 命令,更新组织资源的允许政策:
gcloud alpha organizations set-iam-policy [ORGANIZATION_ID] policy.json

API

请求:

POST https://cloudresourcemanager.googleapis.com/v3/organizations/12345:setIamPolicy
{
    "policy": {
    "version": "0",
    "bindings": [
    {
        "role": "roles/resourcemanager.organizationAdmin",
        "members": [
            "user:email1@gmail.com"
        ]
    },
    {
        "role": "roles/resourcemanager.projectCreator",
        "members": [
        "user:email2@gmail.com",
        "user:email3@gmail.com",
        "serviceAccount:my-other-app@appspot.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKHHiQ="
    }
}

响应:

{
    "bindings": [
    {
        "role": "roles/resourcemanager.organizationAdmin",
        "members": [
            "user:email1@gmail.com"
        ]
    },
    {
        "role": "roles/resourcemanager.projectCreator",
        "members": [
            "user:email2@gmail.com",
            "user:email3@gmail.com",
            "serviceAccount:my-other-app@appspot.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKJUiQ="
}

借助 setIamPolicy() 方法,您可以通过将 允许政策附加到组织资源来向用户授予角色。允许政策是定义的一组绑定。

Read-Modify-Write:通常,我们按照以下模式更新资源的元数据( 如允许政策):先读取其当前状态,接着在本地更新数据, 然后发送修改后的数据以进行写入。如果两个或多个独立进程尝试同时执行此 序列,则可能会导致 冲突。例如,假设一个项目有两个所有者 并且他们都在尝试同时对允许 政策进行冲突的更改。在某些情况下,其中一个项目所有者所做的更改可能会 失败。IAM 可利用允许政策的 ETag 属性来解决此问题。此属性用于验证允许政策自上次请求以来是否已发生更改。当您使用 ETag 值发出请求时,系统会将请求中的 ETag 值与 政策关联的现有 ETag 值进行比较。只有当 ETag 值匹配时,系统才会写入允许政策 。

更新允许政策时,请先使用 getIamPolicy() 获取允许政策,更新允许政策,然后使用 setIamPolicy() 写入更新后的允许政策。只有当 GetPolicyResponse中的相应允许政策包含 ETag 值时,才在设置允许 政策时使用 ETag 值。

Python

借助 setIamPolicy() 方法,您可以将允许政策附加到资源。setIamPolicy 方法会接受SetIamPolicyRequest,其中包含要 设置的允许政策以及要附加允许政策的资源。它会返回生成的允许政策。使用 setIamPolicy() 更新允许政策时,建议遵循 读取-修改-写入模式 。

以下是一些用于设置组织 资源的允许政策的示例代码:

crm = discovery.build(
    'cloudresourcemanager', 'v3', http=creds.authorize(httplib2.Http()))
policy = crm.organizations().getIamPolicy(
    resource=flags.organizationId, body={}).execute()

admin_binding = next(
    (binding
        for binding in policy['bindings']
        if binding['role'] == 'roles/resourcemanager.organizationAdmin'),
        None)

# Add an empty Organization Administrator binding if not present.
if not admin_binding:
    admin_binding = {
        'role': 'roles/resourcemanager.organizationAdmin',
        'members': []
    }
policy['bindings'].append(admin_binding)

# Add the new Admin (if necessary).
new_admin = 'user:' + flags.adminEmail
if new_admin not in admin_binding['members']:
    admin_binding['members'].append(new_admin)
policy = crm.organizations().setIamPolicy(
    resource=flags.organizationId,
    body={
        'resource': flags.organizationId,
        'policy': policy
    }).execute()

print json.dumps(policy, indent=2)

限制用户可以看到的项目

用户可以在 Google Cloud 控制台和 搜索查询中查看他们有权访问的所有项目,无论他们是否在用户选定的 组织资源中。您可以使用组织政策服务来限制在查询和 Google Cloud 控制台中返回的 项目集。这 可用于限制用户只能查看您自己网域中的项目。

组织政策限制条件 constraints/resourcemanager.accessBoundaries是对组织资源强制执行的 列表限制条件 。限制条件接受 组织资源 ID 列表,这些 ID 定义使查询或 控制台中的用户可以看到其资源的组织资源集。 Google Cloud

如果用户对项目的父级组织 资源没有 resourcemanager.organizations.get权限,则项目会显示在No organization下。这可能会让您觉得不属于组织资源的项目根本没有与组织资源关联。如果您使用resourcemanager.accessBoundaries限制条件来禁止 组织资源,则属于该组织资源的项目不会 出现在查询或 Google Cloud 控制台中。如果强制执行此限制条件,则任何尚未 迁移到组织资源的项目都不可见。

我们建议您先将No organization下的项目迁移到您的 组织资源,然后再强制执行此限制条件。如需了解如何将项目迁移至组织资源,请参阅 移动项目

如需了解如何设置组织政策,请参阅 使用限制条件

授予条件式访问权限

某些 IAM 角色(例如 Organization Policy Administrator (roles/orgpolicy.policyAdmin))只能在组织资源上授予。 由于政策继承,此 角色通常由组织中的所有资源继承。

如需更好地控制在哪些资源上授予角色,您可以使用 IAM 条件。将标记与 条件结合使用,可让您仅在资源具有指定的 标记时授予对资源的访问权限。例如,以下允许 政策仅对具有 environment: dev 标记的资源授予 Organization Policy Administrator 角色,而不对任何其他资源授予该角色:

{
  "bindings": [
    {
      "members": [
        "group:my-group@example.com"
      ],
      "role": "roles/orgpolicy.policyAdmin",
      "condition": {
          "title": "Dev_environment_only",
          "description": "Only granted in the development environment",
          "expression":
            "resource.matchTag('123456789012/env', 'dev')"
      }
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 3
}

测试权限

您可以使用 testIamPermissions() 方法测试用户对组织 资源的 IAM 权限。此方法会将您想要测试的资源网址和权限集作为输入参数,并返回用户可拥有的其中部分权限。

如果您直接使用 Google Cloud 控制台来管理权限,通常无需调用 testIamPermission()testIamPermissions() 适合与您的专有软件(如自定义 图形用户界面)集成。例如, Google Cloud 控制台在内部使用 testIamPermissions()来确定 已登录的用户可以使用哪个界面。

API

您可以使用 testIamPermissions() 方法来检查调用者对指定资源所拥有的指定权限。该方法会将资源名称和一组权限作为 参数传递,并返回调用者拥有的部分权限。

以下是一些用于测试组织资源的权限的示例代码:

Request:

POST https://cloudresourcemanager.googleapis.com/v3/organizations/12345:testIamPermissions

{
    "permissions":  [
        "resourcemanager.organizations.get",
        "resourcemanager.organizations.setIamPolicy"
    ]
}

Response:

{
    "permissions": [
        "resourcemanager.organizations.get"
    ]
}

Python

crm = discovery.build(
    'cloudresourcemanager', 'v3', http=creds.authorize(httplib2.Http()))

response = crm.organizations().testIamPermissions(
    resource=flags.organizationId,
    body={
        'resource': flags.organizationId,
        'permissions': [
            'resourcemanager.organizations.setIamPolicy',
            'resourcemanager.projects.patch'
        ]
    }).execute()

print json.dumps(response, indent=2)