凭证访问边界概览

本页面介绍了凭证访问边界,您可以使用它来缩小或限制短期有效的凭证可以使用的 Identity and Access Management (IAM) 权限范围。

您可以使用凭据访问边界生成 OAuth 2.0 访问令牌,这些令牌代表服务账号,但具有的权限少于服务账号。例如,如果您的某个客户需要访问您控制的 Cloud Storage 数据,您可以执行以下操作:

  1. 创建一个可访问您拥有的每个 Cloud Storage 存储桶的服务账号。
  2. 为此服务账号生成 OAuth 2.0 访问令牌。
  3. 应用凭据访问边界,以仅允许访问包含您的客户数据的存储桶。

凭据访问边界的工作原理

要缩小权限范围,您需要定义凭据访问边界(用来指定短期有效的凭据可以访问的资源),以及在各资源上可用权限的上限。然后,您可以创建一个短期有效的凭据,并用其交换遵循凭据访问边界的新凭据。

如果您需要针对每个会话为主账号提供一组不同的权限,则与创建多个不同的服务账号并为每个服务账号授予一组不同的角色相比,使用凭据访问边界更高效。

凭据访问边界的组成部分

凭据访问边界是包含一系列访问边界规则的对象。每条规则都包含以下信息:

  • 应用该规则的资源。
  • 在该资源上可用的权限上限。
  • 可选:进一步限制权限的条件。条件包括以下内容:
    • 计算结果为 truefalse 的条件表达式。如果计算结果为 true,则允许访问;否则拒绝访问。
    • 可选:标识条件的标题。
    • 可选:包含有关条件的更多信息的说明。

如果您将凭据访问边界应用于短期有效的凭据,则该凭据只能访问凭据访问边界中的资源,不能获得在其他资源上可用的权限。

凭证访问边界最多可以包含 10 条访问边界规则。您只能为每个短期有效的凭据应用一个凭据访问边界。

以 JSON 对象的形式表示时,凭据访问边界包含以下字段:

字段
accessBoundary

object

凭据访问边界的封装容器。

accessBoundary.accessBoundaryRules[]

object

应用于短期有效的凭据的访问边界规则的列表。

accessBoundary.accessBoundaryRules[].availablePermissions[]

string

用于定义对于资源可用的权限上限的列表。

每个值都是一个 IAM 预定义角色自定义角色的标识符,并且带有前缀 inRole:。例如:inRole:roles/storage.objectViewer。只能使用这些角色中的权限。

accessBoundary.accessBoundaryRules[].availableResource

string

应用规则的 Cloud Storage 存储桶的完整资源名称。请使用此格式://storage.googleapis.com/projects/_/buckets/bucket-name

accessBoundary.accessBoundaryRules[].availabilityCondition

object

可选。限制对特定 Cloud Storage 对象的权限可用性的条件。

如果要使权限可用于特定的对象(而不是 Cloud Storage 存储桶中的所有对象),请使用此字段。

accessBoundary.accessBoundaryRules[].availabilityCondition.expression

string

一个条件表达式,用于指定可以使用权限的 Cloud Storage 对象。

如需了解如何在条件表达式中引用特定的对象,请参阅 resource.name 属性api.getAttribute("storage.googleapis.com/objectListPrefix") 属性

accessBoundary.accessBoundaryRules[].availabilityCondition.title

string

可选。标识条件目的的短字符串。

accessBoundary.accessBoundaryRules[].availabilityCondition.description

string

可选。有关条件目的的详细信息。

如需查看 JSON 格式的示例,请参阅本页面上的凭据访问边界示例

凭据访问边界的示例

以下各个部分展示了常见使用场景的凭据访问边界示例。您在使用 OAuth 2.0 访问令牌换取作用域令牌时,可以使用凭据访问边界。

限制存储桶的权限

以下示例展示了一个简单的凭据访问边界。它应用于 Cloud Storage 存储桶 example-bucket,并且将权限上限设置为 Storage Object Viewer 角色 (roles/storage.objectViewer) 中包含的权限:

{
  "accessBoundary": {
    "accessBoundaryRules": [
      {
        "availablePermissions": [
          "inRole:roles/storage.objectViewer"
        ],
        "availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket"
      }
    ]
  }
}

限制多个存储分区的权限

以下示例展示了一个凭据访问边界,其中包含多个存储桶的规则:

  • Cloud Storage 存储桶 example-bucket-1:对于此存储桶,只有 Storage Object Viewer 角色 (roles/storage.objectViewer) 中的权限可用。
  • Cloud Storage 存储桶 example-bucket-2:对于此存储桶,只有 Storage Object Creator 角色 (roles/storage.objectCreator) 中的权限可用。
{
  "accessBoundary": {
    "accessBoundaryRules": [
      {
        "availablePermissions": [
          "inRole:roles/storage.objectViewer"
        ],
        "availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket-1"
      },
      {
        "availablePermissions": [
          "inRole:roles/storage.objectCreator"
        ],
        "availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket-2"
      }
    ]
  }
}

限制特定对象的权限

您还可以使用 IAM Conditions 指定主账号可以访问哪些 Cloud Storage 对象。例如,您可以添加一个条件,该条件使权限可用于名称以 customer-a 开头的对象:

{
  "accessBoundary": {
    "accessBoundaryRules": [
      {
        "availablePermissions": [
          "inRole:roles/storage.objectViewer"
        ],
        "availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket",
        "availabilityCondition": {
          "expression" : "resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a')"
        }
      }
    ]
  }
}

列出对象时限制权限

当您列出 Cloud Storage 存储桶中的对象时,会针对存储桶资源(而不是对象资源)调用方法。因此,如果系统为列出请求计算了条件,并且该条件引用了资源名称,则资源名称将标识存储桶,而不是该存储桶中的对象。例如,当您列出 example-bucket 中的对象时,资源名称为 projects/_/buckets/example-bucket

当您列出对象时,此命名惯例可能会导致意外行为。例如,假设您需要一个凭据访问边界,用于允许查看 example-bucket 中前缀为 customer-a/invoices/ 的对象。您可以尝试在凭据访问边界中使用以下条件:

不完整:仅检查资源名称的条件

resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a/invoices/')

此条件适用于读取对象,但不适用于列出对象:

  • 当主账号尝试读取 example-bucket 中前缀为 customer-a/invoices/ 的对象时,该条件的计算结果为 true
  • 当主账号尝试列出具有该前缀的对象时,该条件的计算结果为 falseresource.name 的值为 projects/_/buckets/example-bucket(没有以 projects/_/buckets/example-bucket/objects/customer-a/invoices/ 开头)。

为了防止此问题,除了使用 resource.name.startsWith() 之外,您的条件还可以检查名为 storage.googleapis.com/objectListPrefixAPI 特性。此特性包含用于过滤对象列表的 prefix 参数的值。因此,您可以编写一个引用 prefix 参数的值的条件。

以下示例展示了如何在条件中使用 API 特性。它允许读取和列出 example-bucket 中前缀为 customer-a/invoices/ 的对象:

完整:检查资源名称和前缀的条件

resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a/invoices/')  ||
    api.getAttribute('storage.googleapis.com/objectListPrefix', '')
                     .startsWith('customer-a/invoices/')

现在,您可以在凭据访问边界中使用此条件:

{
  "accessBoundary": {
    "accessBoundaryRules": [
      {
        "availablePermissions": [
          "inRole:roles/storage.objectViewer"
        ],
        "availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket",
        "availabilityCondition": {
          "expression":
            "resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a/invoices/') || api.getAttribute('storage.googleapis.com/objectListPrefix', '').startsWith('customer-a/invoices/')"
        }
      }
    ]
  }
}

后续步骤