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

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

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

本页面介绍了组织级层可用的 IAM 角色,以及如何使用 Resource Manager API 创建和管理组织的 IAM 政策。如需详细了解 IAM,请参阅 IAM 文档。尤其应参阅授予、更改和撤消访问权限

权限和角色

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

您不能直接授予用户权限,而是向其授予角色(角色本身会具有一项或多项权限)。

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

使用预定义角色

下表列出了您可以授予的角色,以访问组织属性、角色的作用以及该角色内捆绑的权限。

职责 角色名称 说明 权限
roles/resourcemanager.organizationAdmin 组织管理员

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

  • orgpolicy.constraints.*
  • orgpolicy.policies.list
  • orgpolicy.policy.get
  • resourcemanager.folders.get
  • resourcemanager.folders.getIamPolicy
  • resourcemanager.folders.list
  • resourcemanager.folders.setIamPolicy
  • resourcemanager.organizations.*
  • resourcemanager.projects.get
  • resourcemanager.projects.getIamPolicy
  • resourcemanager.projects.list
  • resourcemanager.projects.setIamPolicy
roles/resourcemanager.organizationViewer Organization Viewer

提供查看组织的权限。

  • resourcemanager.organizations.get
roles/orgpolicy.policyAdmin Organization Policy Administrator

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

  • orgpolicy.*
roles/browser 浏览器

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

  • 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 权限允许用户授予所有其他权限,因此在分配时应谨慎处理。

查看组织的现有访问权限

通过获取组织级层 IAM 政策,您可以查看用户被授予的组织角色。您可以使用 Google Cloud Console、Google Cloud CLI 或 getIamPolicy() 方法查看组织的政策。

控制台

如需使用 Cloud Console 在组织级层查看授予的角色,请执行以下操作:

  1. 转到 Cloud Console 中的管理资源页面:

    打开“管理资源”页面

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

  3. 选中“组织”资源对应的复选框。

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

gcloud

使用 get-iam-policy 命令获取组织的 IAM 政策:

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 帐号电子邮件、Google 群组、服务帐号或 G Suite 网域授予角色。您可以使用 Cloud Console、gcloud CLI 或 setIamPolicy() 方法授予角色。

控制台

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

  1. 转到 Cloud Console 中的管理资源页面:

    打开“管理资源”页面

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

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

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

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

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

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

  8. 点击添加

gcloud

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

  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="
    }
    
  3. 使用文本编辑器打开 JSON 文件,并向定义组织管理员的绑定数组添加新条目。例如,要将 anotheradmin@gcp-test.com 设为 Organization Admin,您需要按如下方式更改上面显示的示例:

    {
        "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="
    }
    
  4. 通过运行以下命令来更新组织的政策:

    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() 方法,您可以通过向组织附加 IAM 政策来向用户授予角色。IAM 政策由一组语句组成,这些语句定义了谁拥有何种访问权限。

读取-修改-写入:更新资源(例如政策)的一种常见模式是读取其当前状态、在本地更新数据,然后发送修改后的数据以进行写入。如果两个或更多个独立进程同时尝试执行此序列,此模式可能会导致冲突。例如,假设某个项目有两位所有者,并且他们都尝试同时对政策进行更改。在某些情况下,其中一个项目所有者所做的更改可能会失败。IAM 可利用 IAM 政策中的 ETag 属性来解决此问题。此属性用于验证自上次请求以来政策是否发生了更改。当您使用 ETag 值向 IAM 发出请求时,IAM 会将请求中的 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 Admin 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)

...

限制用户对项目的公开范围

用户可以在 Cloud Console 和搜索查询中查看他们有权访问的所有项目,无论他们是否在用户当前选定的组织中。您可以使用组织政策服务来限制查询和 Cloud Console 中返回的一组项目。 这样一来,用户就只能查看自己网域中的项目。

组织政策限制条件 constraints/resourcemanager.accessBoundaries 是对组织资源强制执行的列表限制条件。限制条件接受组织 ID 列表,这些 ID 定义了在查询或 Cloud Console 中向用户显示资源的一组组织。

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

我们建议您先将 No organization 范围内的项目迁移到您的组织,然后再实施此限制条件。如需了解如何将项目迁移到组织,请参阅移动项目

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

测试权限

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

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

API

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

以下一些示例代码可测试组织的权限:

Request:

POST https://cloudresourcemanager.googleapis.com/v3/organization/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)

...