Azure 容器注册表中基于非 Microsoft Entra 令牌的存储库权限

本文介绍了如何创建令牌和范围映射,以便在容器注册表中管理对存储库的访问权限。 通过创建令牌,注册表所有者可以为用户或服务提供范围限定于存储库且有时间限制的访问权限,用来拉取或推送映像或执行其他操作。 令牌提供的权限比其他注册表身份验证选项更精细,后者指定的权限范围是整个注册表。

注释

非Microsoft Entra 令牌和范围映射可用于管理存储库权限,而无需使用 Microsoft Entra。 要使用 Microsoft Entra 标识的 Microsoft Entra 角色分配来管理存储库权限,请参阅针对存储库权限的 Microsoft Entra 基于属性的访问控制 (ABAC)。

适合创建令牌的常见场景包括:

  • 允许具有单独令牌的 IoT 设备从存储库中拉取映像。
  • 向外部组织提供对存储库路径的权限。
  • 针对组织中的不同用户组限制对存储库的访问权限。 例如,为面向特定存储库构建映像的开发人员提供写入和读取访问权限,为从这些存储库进行部署的团队提供读取访问权限。

此功能可在所有服务层级中使用。 若要了解注册表服务层和限制,请参阅 Azure 容器注册表服务层

局限性

  • 当前无法将存储库范围的权限分配给 Microsoft Entra 标识,例如服务主体或托管标识。

概念

若要配置存储库范围内的权限,请创建具有关联的“范围映射”的“令牌” 。

  • 用户使用令牌与生成的密码对注册表进行身份验证。 你可以为令牌密码设置到期日期,或者随时禁用令牌。

    使用令牌进行身份验证后,用户或服务可以执行范围限定于一个或多个存储库的一个或多个操作。

    行动 DESCRIPTION 示例:
    content/delete 从存储库中删除数据 删除存储库或清单
    content/read 从存储库中读取数据 拉取项目
    content/write 将数据写入存储库 与 content/read 一起使用以推送项目
    metadata/read 从存储库中读取元数据 列出标记或清单
    metadata/write 将元数据写入存储库 启用或禁用读取、写入或删除操作

注释

存储库范围的权限不支持列出注册表中所有存储库的目录的功能。

  • 范围映射会对你应用于令牌的存储库权限进行分组,并且可以重新应用于其他令牌。 每个令牌都与单个范围映射相关联。 通过范围映射,你可以执行以下操作:

    • 配置对一组存储库具有相同权限的多个令牌。
    • 在范围映射中添加或删除存储库操作时更新令牌权限,或者在应用另一个范围映射时这样做。

    Azure 容器注册表还提供了几个系统定义的范围映射,你可以在创建令牌时应用这些映射。 系统定义的范围映射的权限适用于注册表中的所有存储库。 单个操作对应于每个范围映射的存储库的限制。

下图显示了令牌与范围映射之间的关系。

注册令牌与范围图

先决条件

  • Azure CLI - 本文中的 Azure CLI 命令示例需要 Azure CLI 2.17.0 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。
  • Docker - 若要对注册表进行身份验证以拉取或推送映像,你需要安装一个本地 Docker。 Docker 提供有关 macOS、 Windows 和 Linux systems.systems 的安装说明。
  • 容器注册表 - 如果没有,请在 Azure 订阅中创建容器注册表。 例如,使用 Azure 门户或 Azure CLI。

创建令牌 - CLI

创建令牌并指定存储库

可使用 az acr token create 命令创建令牌。 创建令牌时,可以指定一个或多个存储库,并在每个存储库上指定关联的操作。 存储库不需要已在注册表中。 若要通过指定现有范围映射来创建令牌,请参阅下一部分。

下面的示例在注册表 myregistry 中创建一个令牌,该令牌对 存储库具有以下权限:samples/hello-world 和 content/write。 默认情况下,该命令会将默认令牌状态设置为 enabled,但你随时可以将状态更新为 disabled。

az acr token create --name MyToken --registry myregistry \
  --repository samples/hello-world \
  content/write content/read \
  --output json

输出会显示有关令牌的详细信息。 默认情况下,系统会生成两个不会过期的密码,但你可以根据需要设置过期日期。 建议将密码保存在安全的位置,以便以后将其用于身份验证。 无法再次检索这些密码,但可以生成新密码。

{
  "creationDate": "2023-01-18T00:15:34.066221+00:00",
  "credentials": {
    "certificates": [],
    "passwords": [
      {
        "creationTime": "2023-01-18T00:15:52.837651+00:00",
        "expiry": null,
        "name": "password1",
        "value": "uH54BxxxxK7KOxxxxRbr26dAs8JXxxxx"
      },
      {
        "creationTime": "2023-01-18T00:15:52.837651+00:00",
        "expiry": null,
        "name": "password2",
        "value": "kPX6Or/xxxxLXpqowxxxxkA0idwLtmxxxx"
      }
    ],
    "username": "MyToken"
  },
  "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/myresourcegroup/providers/Microsoft.ContainerRegistry/registries/myregistry/tokens/MyToken",
  "name": "MyToken",
  "objectId": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "myresourcegroup",
  "scopeMapId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/myresourcegroup/providers/Microsoft.ContainerRegistry/registries/myregistry/scopeMaps/MyToken-scope-map",
  "status": "enabled",
  "type": "Microsoft.ContainerRegistry/registries/tokens"
}

注释

若要重新生成令牌密码和有效期,请参阅本文后面的重新生成令牌密码。

输出包含该命令创建的范围映射的详细信息。 可以使用范围映射(在此处名为 MyToken-scope-map)将相同的存储库操作应用于其他令牌。 或者,稍后更新范围映射以更改关联的令牌的权限。

创建令牌并指定范围映射

创建令牌的另一种方法是指定现有的范围映射。 如果还没有范围映射,请先指定存储库和关联的操作来创建一个。 然后,在创建令牌时指定该范围映射。

若要创建范围映射,请使用 az acr scope-map create 命令。 以下命令创建的范围映射对前面使用的 samples/hello-world 存储库具有相同权限。

az acr scope-map create --name MyScopeMap --registry myregistry \
  --repository samples/hello-world \
  content/write content/read \
  --description "Sample scope map"

运行 az acr token create 来创建令牌,同时指定 MyScopeMap 范围映射。 与前面的示例一样,该命令会将默认令牌状态设置为 enabled。

az acr token create --name MyToken \
  --registry myregistry \
  --scope-map MyScopeMap

输出会显示有关令牌的详细信息。 默认情况下,会生成两个密码。 建议将密码保存在安全的位置,以便以后将其用于身份验证。 无法再次检索这些密码,但可以生成新密码。

注释

若要重新生成令牌密码和有效期,请参阅本文后面的重新生成令牌密码。

如何使用范围映射来为多个存储库定义和分配权限

范围映射允许使用通配符来为共享公共前缀的多个存储库定义和授予类似的权限。 也可以在同一范围映射中使用具有特定权限的存储库和具有通配符的存储库。 这为在单个范围映射中管理多个存储库集的权限提供了灵活性。

创建范围映射并将其分配给令牌时,可以创建存储库权限。 或者,可以创建令牌并将其直接分配给存储库。

以下示例使用通配符创建范围映射,然后将其分配给令牌。

az acr scope-map create --name MyScopeMapWildcard --registry myregistry \
  --repository samples/* \
  content/write content/read \
  --description "Sample scope map with wildcards"
az acr token create --name MyTokenWildcard \
  --registry myregistry \
  --scope-map MyScopeMapWildcard

以下示例使用通配符创建一个令牌。

 az acr token create --name MyTokenWildcard --registry myregistry \
  --repository samples/* \
  content/write content/read \

通配符权限是可累加的,这意味着当访问特定存储库时,生成的权限将包括与通配符前缀匹配的所有范围映射规则的权限。

在此示例中,范围映射为三种不同类型的存储库定义了权限:

资料库 许可
sample/* content/read
sample/teamA/* content/write
sample/teamA/projectB content/delete

为令牌分配了一个范围映射,以授予用于访问存储库 [content/read, content/write, content/delete] 的 sample/teamA/projectB 权限。 但是,当使用相同的令牌访问 sample/teamA/projectC 存储库时,它只具有 [content/read, content/write] 权限。

重要

在范围映射中使用通配符的存储库应始终以 /* 后缀结尾才有效,并且存储库名称中只有一个通配符。 下面是无效通配符的一些示例:

  • 存储库名称中间有一个通配符的 sample/*/teamA。
  • 包含不以“/*”结尾的通配符的 sample/teamA*。
  • 存储库名称中包含多个通配符的 sample/teamA/*/projectB/*。

根级别通配符

也可以在根级别应用通配符。 这意味着,分配给定义为 * 的存储库的任何权限都将在注册表范围内应用。

该示例演示如何创建具有根级别通配符的令牌,该通配符将为令牌提供对注册表中所有存储库的 [content/read, content/write] 权限。 这提供了一种简单的方式来向注册表中的所有存储库授予权限,而无需单独指定每个存储库。

 az acr token create --name MyTokenWildcard --registry myregistry \
  --repository * \
  content/write content/read \

重要

如果通配符规则包含尚不存在的存储库,则此通配符规则的权限仍将应用于该存储库名称。 例如,分配给范围映射的令牌,它用于授予对 [content/write, metadata/write] 存储库的 sample/* 权限。 此外,假设存储库 sample/teamC/teamCimage 尚不存在。 该令牌有权将映像推送到存储库 sample/teamC/teamCimage,这会在成功推送的同时创建存储库。

创建令牌 - 门户

你可以使用 Azure 门户来创建令牌和范围映射。 与 az acr token create CLI 命令一样,你可以应用现有的作范围映射,也可以在创建令牌时通过指定一个或多个存储库和关联的操作创建范围映射。 存储库不需要已在注册表中。

下面的示例创建了一个令牌和一个范围映射,后者具有对 samples/hello-world 存储库的以下权限:content/write 和 content/read。

  1. 在门户中,导航到容器注册表。

  2. 在“存储库权限”下,选择“令牌”“+添加”。

    在门户中创建令牌的屏幕截图。

  3. 输入令牌名称。

  4. 在“范围映射”下,选择“新建” 。

  5. 配置范围映射:

    1. 为范围映射输入名称和说明。

    2. 在“存储库”下,输入 ,并在“权限”下,选择 samples/hello-world 和 。 然后选择“+添加”。

      在门户中创建范围映射的屏幕截图。

    3. 添加存储库和权限后,选择“添加”,以添加范围映射。

  6. 接受默认令牌状态(“启用”),然后选择“创建” 。

验证并创建令牌后,令牌详细信息将显示在“令牌”屏幕中。

添加令牌密码

若要使用在门户中创建的令牌,必须生成密码。 你可以生成一个或两个密码,并为每个密码设置到期日期。 为令牌创建的新密码会立即可用。 为令牌重新生成新密码将需要 60 秒才能完成复制并成为可用状态。

  1. 在门户中,导航到容器注册表。

  2. 在“存储库权限”下,选择“令牌”,然后选择一个令牌。

  3. 在“令牌详细信息”中,选择“password1”或“password2”,然后选择“生成”图标 。

  4. 在“密码”屏幕上,根据需要为密码设置过期日期,并选择“生成”。 建议设置到期日期。

  5. 生成密码后,将其复制到一个安全的位置并保存。 关闭屏幕后无法检索生成的密码,但可以生成新的密码。

    在门户中创建令牌密码的屏幕截图。

使用令牌进行身份验证

当用户或服务使用令牌对目标注册表进行身份验证时,它会提供令牌名称作为用户名,以及生成的其中一个密码。

身份验证方法取决于已配置的操作或与令牌关联的操作。

行动 如何进行身份验证
content/delete Azure CLI 中的 az acr repository delete

示例:az acr repository delete --name myregistry --repository myrepo --username MyToken --password xxxxxxxxxx
content/read docker login

Azure CLI 中的 az acr login

示例:az acr login --name myregistry --username MyToken --password xxxxxxxxxx
content/write docker login

Azure CLI 中的 az acr login
metadata/read az acr repository show

az acr repository show-tags

Azure CLI 中的 az acr manifest list-metadata
metadata/write az acr repository untag

Azure CLI 中的 az acr repository update

示例:使用令牌

以下示例使用之前在本文中创建的令牌对存储库执行常见操作:推送和拉取映像、删除映像以及列出存储库标记。 该令牌最初设置有针对 content/write 存储库的推送权限(content/read 和 samples/hello-world 操作)。

请求和标记测试映像

对于以下示例,请从 Azure 容器注册表拉取公共 hello-world 映像和 nginx 映像,并为注册表和存储库标记它们。

docker pull mcr.microsoft.com/hello-world
docker pull mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
docker tag mcr.microsoft.com/hello-world myregistry.azurecr.cn/samples/hello-world:v1
docker tag mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine myregistry.azurecr.cn/samples/nginx:v1

使用令牌进行身份验证

运行 docker login 或 az acr login 以通过注册表进行身份验证,以便推送或拉取映像。 提供令牌名称作为用户名,并提供其密码之一。 令牌必须具有 Enabled 状态。

下面的示例针对 bash shell 进行了格式设置,并使用环境变量提供值。

TOKEN_NAME=MyToken
TOKEN_PWD=<token password>

echo $TOKEN_PWD | docker login --username $TOKEN_NAME --password-stdin myregistry.azurecr.cn

输出应显示身份验证成功:

Login Succeeded

将映像推送到注册表

成功登录后,尝试将标记的映像推送到注册表。 由于该令牌有权将映像推送到 samples/hello-world 存储库,因此以下推送成功:

docker push myregistry.azurecr.cn/samples/hello-world:v1

该令牌无权访问 samples/nginx 存储库,因此,以下推送尝试将失败,并显示类似于 requested access to the resource is denied 的错误:

docker push myregistry.azurecr.cn/samples/nginx:v1

更新令牌权限

若要更新令牌的权限,请更新相关联的范围映射中的权限。 更新的范围映射会立即应用于所有关联的令牌。

例如,使用对 MyToken-scope-map 存储库的 content/write 和 content/read 操作更新 samples/ngnx,并删除对 content/write 存储库的 samples/hello-world 操作。

若要使用 Azure CLI,请运行 az acr scope map update 来更新范围映射:

az acr scope-map update \
  --name MyScopeMap \
  --registry myregistry \
  --add-repository samples/nginx content/write content/read \
  --remove-repository samples/hello-world content/write 

在 Azure 门户中:

  1. 导航到你的容器注册表。

  2. 在“存储库权限”下,选择“范围映射”,然后选择要更新的范围映射。

  3. 在“存储库”下,输入 ,并在“权限”下,选择 samples/nginx 和 。 然后选择“+添加”。

  4. 在“存储库”下,选择 ,并在“权限”下,取消选择 samples/hello-world 。 然后,选择“保存”。

范围映射更新后,以下推送成功:

docker push myregistry.azurecr.cn/samples/nginx:v1

由于范围映射仅具有对 content/read 存储库的 samples/hello-world 权限,因此,对 samples/hello-world 存储库的推送尝试现在会失败:

docker push myregistry.azurecr.cn/samples/hello-world:v1

从这两个存储库中提取映像将成功,因为范围映射提供对两个存储库的 content/read 权限:

docker pull myregistry.azurecr.cn/samples/nginx:v1
docker pull myregistry.azurecr.cn/samples/hello-world:v1

删除映像

通过将 content/delete 操作添加到 nginx 存储库可以更新范围映射。 此操作允许删除存储库中的映像或删除整个存储库。

为简洁起见,我们只显示用于更新范围映射的 az acr scope map update 命令:

az acr scope-map update \
  --name MyScopeMap \
  --registry myregistry \
  --add-repository samples/nginx content/delete

若要使用门户更新范围映射,请参阅上一部分。

可使用以下 az acr repository delete 命令删除 samples/nginx 存储库。 若要删除映像或存储库,请将令牌的名称和密码传递给命令。 以下示例使用本文前面创建的环境变量:

az acr repository delete \
  --name myregistry --repository samples/nginx \
  --username $TOKEN_NAME --password $TOKEN_PWD

显示存储库标记

通过将 metadata/read 操作添加到 hello-world 存储库可以更新范围映射。 此操作允许读取存储库中的清单和标记数据。

为简洁起见,我们只显示用于更新范围映射的 az acr scope map update 命令:

az acr scope-map update \
  --name MyScopeMap \
  --registry myregistry \
  --add-repository samples/hello-world metadata/read 

若要使用门户更新范围映射,请参阅上一部分。

若要读取 samples/hello-world 存储库中的元数据,请运行 az acr manifest list-metadata 或 az acr repository show-tags 命令。

若要读取元数据,请将令牌的名称和密码传递给任一命令。 以下示例使用本文前面创建的环境变量:

az acr repository show-tags \
  --name myregistry --repository samples/hello-world \
  --username $TOKEN_NAME --password $TOKEN_PWD

示例输出:

[
  "v1"
]

管理令牌和范围映射

列出范围映射

使用 az acr scope-map list 命令或门户中的“范围映射”屏幕,列出在注册表中配置的所有范围映射。 例如:

az acr scope-map list \
  --registry myregistry --output table

输出包括三个系统定义的范围映射和你生成的其他范围映射。 可以使用上述任一范围映射来配置令牌。

NAME                 TYPE           CREATION DATE         DESCRIPTION
-------------------  -------------  --------------------  ------------------------------------------------------------
_repositories_admin  SystemDefined  2023-01-20T09:44:24Z  Can perform all read, write and delete operations on the ...
_repositories_pull   SystemDefined  2023-01-20T09:44:24Z  Can pull any repository of the registry
_repositories_push   SystemDefined  2023-01-20T09:44:24Z  Can push to any repository of the registry
MyScopeMap           UserDefined    2022-11-15T21:17:34Z  Sample scope map

显示令牌详细信息

若要查看某个令牌的详细信息(例如其状态和密码到期日期),请运行 az acr token show 命令,或在门户中的“令牌”屏幕中选择该令牌。 例如:

az acr scope-map show \
  --name MyScopeMap --registry myregistry

使用门户中的 az acr token list 命令或“令牌”屏幕列出注册表中配置的所有令牌。 例如:

az acr token list --registry myregistry --output table

重新生成令牌密码

如果未生成令牌密码,或者要生成新密码,请运行 az acr token credential generate 命令。 为令牌重新生成新密码将需要 60 秒才能完成复制并成为可用状态。

下面的示例为 MyToken 令牌的 password1 生成新值,有效期为 30 天。 它将密码存储在环境变量 TOKEN_PWD 中。 此示例的格式是针对 bash shell 设置的。

TOKEN_PWD=$(az acr token credential generate \
  --name MyToken --registry myregistry --expiration-in-days 30 \
  --password1 --query 'passwords[0].value' --output tsv)

要使用 Azure 门户生成令牌密码,请参阅本文前面的创建令牌 - 门户中的步骤。

使用新的范围映射更新令牌

如果要使用不同的范围映射来更新令牌,请运行 az acr token update 并指定新的范围映射。 例如:

az acr token update --name MyToken --registry myregistry \
  --scope-map MyNewScopeMap

在门户中的“令牌”屏幕上,选择相应令牌,然后在“范围映射”下,选择一个不同的范围映射。

小窍门

使用新的范围映射更新令牌后,建议生成新的令牌密码。 请使用 az acr token credential 生成 命令或在 Azure 门户中重新生成令牌密码。

禁用或删除令牌

建议临时对用户或服务禁用令牌凭据。

使用 Azure CLI 运行 az acr token update 命令,将 status 设置为 disabled:

az acr token update --name MyToken --registry myregistry \
  --status disabled

在门户中的“令牌”屏幕中选择令牌,然后在“状态”下选择“禁用”。

若要删除令牌以使利用其凭据的任何人的访问权限永久失效,请运行 az acr token delete 命令。

az acr token delete --name MyToken --registry myregistry

在门户中的“令牌”屏幕中选择令牌,然后选择“禁用”。

后续步骤

  • 若要管理范围映射和令牌,请使用 az acr scope map 和 az acr token 命令组中的其他命令。
  • 请参阅身份验证概述,了解通过 Azure 容器注册表进行身份验证的其他选项,其中包括使用 Microsoft Entra 标识、服务主体或管理员帐户。