本文主要介绍通过标签(Tag)功能对API网关资源进行标记,利用资源上的Tag来批量描述资源,从而实现对特定类型的资源进行分组查询和管理。

每个标签(Tag)是由两个部分组成,Key和Value。同时,标记资源的时候需要指定资源类型,不同类型资源之间的标签是隔离的,不同region之间的标签也是隔离的。目前API网关支持对以下几种资源打标签:分组,API,插件,应用。这四种资源对应的参数ResourceType取值分别为:apiGroup,api,plugin,app。

1. 标签使用场景

  1. 对大量资源进行分组管理,方便批量的查询和处理资源。
  2. 结合阿里云的RAM系统的权限管理能力,提供主子账户的资源隔离的功能。本文3.1节将对此用法进行详细说明。

2. 使用Tag的限制:

  • 一个资源上面已有的Tag不能超过20个
  • 一个资源上Tag的Key不能相同,如果添加一个已有key的Tag,会使用该Tag新的Value覆盖旧的Value
  • Key长度<=64 个 Unicode 字符,Value长度<=128 个 Unicode 字符
  • Key和Value区分大小写
  • 键(key)不支持以aliyun、acs: 开头; 不允许包含http:// 和 https:// ;不允许为空字符串
  • 值(value)不允许包含http:// 和 https:// 。允许为空字符串

3. 权限控制

3.1 主子账户的资源隔离

简单介绍下RAM,阿里云账号本身是主账号,可以创建多个子账号,这些子账号可以被授权管理主账号的资源,授权操作参见相关文档:阿里云RAM

主账号可以使用Tag对资源进行分类,对子账号授权时按照文档权限策略基本元素将资源的标签指定为授权语句的限制条件(Condition)部分,进而对所属资源进行子账号的隔离。例如,公司有多个部门,我们为每个部门创建一个管理员(子账号),然后授权每个子账号只能操作带有自己部门标签的资源。授权示例如下:

示例1:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "apigateway:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "apigateway:tag/depart": "dep1"
        }
      }
    }
  ]
}

被授权的子用户,就只能操作带有depart:dep1标签的资源,即可管理部门1的所有资源。在这个子账号查询资源列表的时候,必须带有Tag.1.Key=depart、Tag.1.Value=dep1的过滤条件鉴权才会通过,才允许查询。

示例2:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "apigateway:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "apigateway:tag/depart": ["dep2", "dep3"]
        }
      }
    }
  ]
}

被授权的子用户,能操作带有depart:dep2或者depart:dep3 标签的资源,即可管理部门2和部门3的所有资源。

示例3:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "apigateway:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "apigateway:tag/depart": "dep2", 
         "apigateway:tag/Enviroment": "test"
        }
      }
    }
  ]
}

被授权的子用户,只能操作同时被depart:dep2 和 Enviroment:test 标签标记的资源,即可管理部门2的测试环境资源。

分组,插件,应用三种资源支持子账号按照标签授权访问,API的授权完全从属于所属分组的授权规则,不支持通过API上已标记的标签进行授权。

3.2 标签相关操作的鉴权说明

对于使用标签(Tag)授权的资源,对不同类型的API有不同的限制表现,具体的限制如下:

创建类接口

对于创建类接口,鉴权时会判断接口中使用的所有资源是不是有权限,同时,也会通过标签参数判断是否有即将创建出来的资源的权限。因此,对于带有标签授权的子账号,创建API分组、应用、插件这类资源的时候,请求参数中也必须带有相关Tag参数,否则子用户没有权限创建。示例如下:

子账号被授予如下的权限时,则该子账号只能创建带有标签 `depart:dept1` 的分组。

{
    "Effect": "Allow",
    "Action": "apigateway:*",
     "Resource": "acs:apigateway:*:*:apigroup/*",
     "Condition": {
           "StringEquals": {
                "apigateway:tag/depart": "dep1"
            }
      }
}

操作类接口

对于操作类接口(如DeleteApp),是针对某一个资源的操作,子账号是否有权限完全依赖这个资源是否带有指定的标签。 如果应用上带有授权语句中所有规定的标签,则允许子账号操作。

查询类接口

对于查询类操作,由于所有的鉴权行为都是前置行为(即判断结果只区分是否通过,而不会判断一个集合中有哪些通过),所以不会对结果集合进行“有权限过滤”。使用了标签鉴权的子账号,必须在查询中带有指定有权限的标签进行查询,才能查到有权限的应用。当查询条件指定资源id 的情况下,账号是否有权限依赖这个资源是否带有指定的标签。

3.3 用户通过OpenAPI 访问资源的特殊说明

通过子账号AK根据标签条件查询资源列表时,需要配置启用标签鉴权,即设置参数 EnableTagAuth 为true。启用后才支持标签鉴权。这类接口列表如下:

  • DescribeApiGroups
  • DescribeAppAttributes

3.4 子账号访问控制台分组和API列表不展示的情况

部分用户过去使用类似下面语法的授权,老版控制台可以在列表查询中默认看到该分组。新版控制台将不再支持子账号资源列表查询对这种语法的支持。

{
     "Effect": "Allow",
     "Action": "apigateway:*",
     "Resource": "acs:apigateway:*:*:apigroup/f0b34d4c55504a34897f7390a24ce253"
}

子账号需要作出下面的调整才可以看到列表查询的结果。除列表查询以外其他接口不受影响,也不需要调整任何授权配置。

  1. 在原来的授权语句基础上增加下面的授权子句,分组列表和API列表查询可以展示所有资源
    {
         "Effect": "Allow",
         "Action": ["apigateway:DescribeApiGroups", "apigateway:DescribeApisForConsole"],
         "Resource": "acs:apigateway:*:*:apigroup/*"
    }
  2. 通过主账号在控制台给对应的资源加标签 depart:dep1,并在RAM控制台给需要授权的子账号对应的自定义权限权规则中增加下面的授权子句,则子账号在控制台可以通过设置标签条件查询资源列表
{
    "Effect": "Allow",
    "Action": "apigateway:*",
     "Resource": "acs:apigateway:*:*:apigroup/*",
     "Condition": {
           "StringEquals": {
                "apigateway:tag/depart": "dep1"
            }
      }
}