使用 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:[email protected] role: roles/editor - members: - user:[email protected] role:roles/resourcemanager.organizationAdmin - members: - user:[email protected] 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:[email protected]"     ]     },     {         "role": "roles/resourcemanager.projectCreator",         "members": [             "user:[email protected]",             "user:[email protected]",             "serviceAccount:[email protected]"         ]     }     ]     "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 命令获取组织资源的许可政策,并将该政策输出到 JSON 文件:

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

{     "bindings": [     {         "members": [             "user:[email protected]"         ],         "role": "roles/editor"     },     {         "members": [             "user:[email protected]",         ],         "role": "roles/resourcemanager.organizationAdmin"     },     {         "members": [             "user:[email protected]"         ],         "role": "roles/resourcemanager.projectCreator"     },     ],     "etag": "BwU1aRxWk30=" } 
  1. 使用文本编辑器打开 JSON 文件,并向 bindings 数组添加一个新条目来定义 Organization Administrator 角色。例如,要将 [email protected] 设为 Organization Administrator,您需要按如下方式更改上一个示例:
{     "bindings": [     {         "members": [             "user:[email protected]"         ],         "role": "roles/editor"     },     {         "members": [             "user:[email protected]",             "user:[email protected]"         ],         "role": "roles/resourcemanager.organizationAdmin"     },     {         "members": [             "user:[email protected]"         ],         "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:[email protected]"         ]     },     {         "role": "roles/resourcemanager.projectCreator",         "members": [         "user:[email protected]",         "user:[email protected]",         "serviceAccount:[email protected]"         ]     }     ]     "etag": "BwUjHYKHHiQ="     } } 

回答:

{     "bindings": [     {         "role": "roles/resourcemanager.organizationAdmin",         "members": [             "user:[email protected]"         ]     },     {         "role": "roles/resourcemanager.projectCreator",         "members": [             "user:[email protected]",             "user:[email protected]",             "serviceAccount:[email protected]"         ]     }     ]     "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 角色(例如组织政策管理员 [roles/orgpolicy.policyAdmin])只能在组织资源上授予。由于存在政策继承,因此组织中的所有资源通常都会继承此角色。

如需更精细地控制角色授予的资源,您可以使用 IAM Conditions。将标记与条件搭配使用,可让您仅在资源具有指定的标记时授予对该资源的访问权限。例如,以下允许政策仅在具有 environment: dev 标记的资源上授予组织政策管理员角色,而不会在任何其他资源上授予该角色:

{   "bindings": [     {       "members": [         "group:[email protected]"       ],       "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)