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

Identity and Access Management (IAM) 可让您授予对特定 Cloud de Confiance by S3NS 资源的精细访问权限,同时防止对其他资源进行不必要的访问。通过应用最小权限原则,您仅授予工作负载所需的权限。

IAM 通过允许政策控制谁(用户)对哪些资源具有什么访问权限(角色),这些政策会将特定角色绑定到用户。如需管理整个资源层次结构的访问权限,您可以使用 Cloud Resource Manager API 配置组织级 IAM 角色和允许政策。您还可以定义拒绝政策,以防止主账号使用特定权限。如需了解详情,请参阅管理对项目、文件夹和组织的访问权限。

权限和角色

为了控制对资源的访问权限, Cloud de Confiance by S3NS 要求发出 API 请求的账号具有适当的 IAM 角色。IAM 角色包含允许用户对Cloud de Confiance 资源执行特定操作的权限。例如,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.list 和 folders.get 权限,则还应包含 projects.list 和 projects.get。
  • 请注意,组织、文件夹和项目资源的 setIamPolicy 权限允许用户授予所有其他权限,因此应谨慎分配。

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

获取组织资源的允许政策后,您即可查看为用户授予的组织资源角色。您可以使用 Cloud de Confiance 控制台、Google Cloud CLI 或 getIamPolicy() 方法查看组织资源的允许政策。

控制台

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

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

    打开“管理资源”页面

  2. 在组织下拉菜单中,选择您的组织资源。

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

  4. 在信息面板中的权限下,点击展开某个角色,即可显示拥有该角色的所有成员。

gcloud

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

gcloud 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.s3ns-system.iam.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)

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

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

控制台

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

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

    打开“管理资源”页面

  2. 在组织下拉菜单中,选择您的组织资源。

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

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

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

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

  7. 在选择角色下拉菜单中,选择要授予团队成员的角色。

  8. 点击 Add(添加)。

gcloud

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

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

    gcloud 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 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.s3ns-system.iam.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.s3ns-system.iam.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKJUiQ="
}

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

读取-修改-写入:更新资源元数据(例如允许政策)的常见模式包括读取其当前状态、在本地更新数据,然后发送修改后的数据以进行写入。如果有两个或两个以上的独立过程同时尝试执行该序列,则此模式可能会导致冲突。例如,如果两位 Project Owner 尝试同时对允许政策进行有冲突的更改,则其中一位所有者的更改可能会失败。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)

限制用户的项目公开范围

用户可以在 Cloud de Confiance 控制台和搜索查询中看到他们有权访问的所有项目,无论这些项目是否位于用户所选的组织资源中。您可以使用 Organization Policy Service 限制在查询和 Cloud de Confiance 控制台中返回的项目集。这样,您就可以限制用户只能查看您网域中的项目。

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

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

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

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

授予条件式访问权限

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

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

{
  "bindings": [
    {
      "members": [
        "{dynamic print variables.examples.principal_group_api}"
      ],
      "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 权限。此方法接受资源网址和要测试的一组权限。它会返回用户可以访问的这些权限的子集。

如果您直接使用Cloud de Confiance 控制台管理权限,通常无需调用 testIamPermissions()。testIamPermissions() 适合与您的专有软件(如自定义图形界面)整合使用。例如, Cloud de Confiance 控制台会在内部使用 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)