Update container registry auth service to support read permissions for nested repositories
Context
We are rolling out a new version of the Container Registry in GitLab.com that includes a metadata database (&5523 (closed)). Among others, this database will allow for efficient storage usage calculations.
This issue is part of a work plan to expose the deduplicated size of grouped image repositories in the GitLab UI and API (&7228 (closed)).
The Container Registry has a new API, including Get repository details operation. When used in conjunction with the size=self_with_descendands
query parameter, the response will include the deduplicated size of the target repository and all repositories within. For example:
curl --header "Authorization: Bearer <token>" "https://registry.gitlab.com/gitlab/v1/repositories/gitlab-org/build/cng?size=self_with_descendants"
The request above will return the deduplicated size of all repositories within gitlab-org/build/cng
. In this case, cng
is a project, giving us the container registry usage at the project level. If we used gitlab-org/build
for the query, that would give us the group level usage (deduplicated size of all image repositories across all projects under the build
group). Finally, using gitlab-org
would give us the top-level namespace usage (deduplicated size of all image repositories across all groups and projects under that namespace).
Problem
This new API operation is the first where we're targeting a series of repositories that only have one thing in common: their ancestor.
This means that we have to update the authentication service, so that it's possible to emit tokens that grant permission on a given repository and all repositories within.
More precisely, as documented here, when using size=self_with_descendants
, An auth token with pull permissions for name <path>/* is required
. This part of the token will grant read access to all descendant repositories. The token also needs to have a pull
access record for the base repository. So, to be able to make the sample request above, we need a token with the following format:
{
"access": [
{
"actions": [
"pull"
],
"name": "gitlab-org/build/cng",
"type": "repository"
},
{
"actions": [
"pull"
],
"name": "gitlab-org/build/cng/*",
"type": "repository"
}
],
// ...
}
This is not possible right now.
Proposal
Implement support for nested repository permissions. This must be restricted to pull
permissions.
Additionally, to start with, we should restrict this to the project level. This means that when a user requests pull
permissions for foo/bar/car/*
, we should make sure that:
-
foo/bar/car
is a projectOR
foo/bar
is a project (and in that case,car
is a sub-repository)*
; - The requesting user has registry read access for the target project.
Later on, we'll have to expand this logic to account for group and top-level namespace permissions.
*
This requires some thought due to the max depth of groups/projects (what's the max depth here?) and sub container repositories (up to 3 levels deep).