Skip to content

Protected containers: Integrate protection rules in auth service

What does this MR do and why?

  • Push protection for new container images in the container registry authentication mechanism
  • Reusing the new model scopes to quickly match container registry protection rules
  • Code necessary for the implementation of the feature protected containers, see &9825

🛠 with at Siemens

DB Queries

The changes in this MR include the execution of two additional db queries when an image is pushed to the container registry:

  1. When calculating the maximum access level of the user for a specific project, see !136873 (diffs)
SELECT MAX("project_authorizations"."access_level") AS "maximum_access_level", "project_authorizations"."project_id" AS "project_authorizations_project_id"
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 1 AND "project_authorizations"."project_id" = 7
GROUP BY "project_authorizations"."project_id"
  1. When checking for existing container protection rules, see !136873 (diffs)
SELECT 1 AS one
FROM "container_registry_protection_rules"
WHERE "container_registry_protection_rules"."project_id" = 7
AND "container_registry_protection_rules"."push_protected_up_to_access_level" >= 50
AND ('flightjs/flight' ILIKE REPLACE(REPLACE(REPLACE(repository_path_pattern,
                        '%', '\%'),
                '_', '\_'),
        '*', '%')
)
LIMIT 1 

Note: The values in the queries are executed when following the local validation guide, see below.

Click to see the whole log output
  ProjectAuthorization Maximum (0.3ms)  SELECT MAX("project_authorizations"."access_level") AS "maximum_access_level", "project_authorizations"."project_id" AS "project_authorizations_project_id" FROM "project_authorizations" WHERE "project_authorizations"."user_id" = 1 AND "project_authorizations"."project_id" = 7 GROUP BY "project_authorizations"."project_id" /*application:web,correlation_id:01HJ8925X8BKSS4NV9A19NNK05,endpoint_id:JwtController#auth,db_config_name:main,line:/app/models/user.rb:2056:in `block in max_member_access_for_project_ids'*/
  ↳ app/models/user.rb:2056:in `block in max_member_access_for_project_ids'
  ContainerRegistry::Protection::Rule Exists? (0.1ms)  SELECT 1 AS one FROM "container_registry_protection_rules" WHERE "container_registry_protection_rules"."project_id" = 7 AND "container_registry_protection_rules"."push_protected_up_to_access_level" >= 50 AND ('flightjs/flight' ILIKE REPLACE(REPLACE(REPLACE(repository_path_pattern,
                        '%', '\%'),
                '_', '\_'),
        '*', '%')
) LIMIT 1 /*application:web,correlation_id:01HJ8925X8BKSS4NV9A19NNK05,endpoint_id:JwtController#auth,db_config_name:main,line:/app/models/container_registry/protection/rule.rb:37:in `for_push_exists?'*/
  ↳ app/models/container_registry/protection/rule.rb:37:in `for_push_exists?'

Screenshots or screen recordings

No frontend change. Only changes in the backend. See the next section to try it out for yourself ;-).

image

Click to see the console
gitlab git:(427546-protected-containters-write-protection-for-container-repositories-integration-container-registry-auth-service) ✗ docker login registry.test:5000 -u gitlab-token -p "ypCa3Dzb23o5nvsixwPA"
docker pull hello-world:latest
docker tag hello-world:latest registry.test:5000/flightjs/flight:v1.0

WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
latest: Pulling from library/hello-world
Digest: sha256:ac69084025c660510933cca701f615283cdbb3aa0963188770b54c31c8962493
Status: Image is up to date for hello-world:latest
docker.io/library/hello-world:latest

What's Next?
  1. Sign in to your Docker account → docker login
  2. View a summary of image vulnerabilities and recommendations → docker scout quickview hello-world:latest
➜  gitlab git:(427546-protected-containters-write-protection-for-container-repositories-integration-container-registry-auth-service) ✗ docker push registry.test:5000/flightjs/flight:v1.0

The push refers to repository [registry.test:5000/flightjs/flight]
12660636fe55: Retrying in 1 second 
unknown: repository path protected
➜  gitlab git:(427546-protected-containters-write-protection-for-container-repositories-integration-container-registry-auth-service) ✗ docker tag hello-world:latest registry.test:5000/flightjs/flight/sub-image:v1.0
docker push registry.test:5000/flightjs/flight/sub-image:v1.0

The push refers to repository [registry.test:5000/flightjs/flight/sub-image]
12660636fe55: Pushed 
v1.0: digest: sha256:a8ea96bb64d60208d6a56712042d1cf58aa4a7d3751b897b9320b0813c81cbb4 size: 524

How to set up and validate locally

  1. Enable the container registry, see https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/howto/registry.md (<= setup as HTTP and not HTTPS)
  2. In rails c, create a ContainerRegistry::Protection::Rule to protect against pushing new container images
ContainerRegistry::Protection::Rule.create(project: Project.find(7), repository_path_pattern: "flightjs/flight", push_protected_up_to_access_level: :owner, delete_protected_up_to_access_level: :owner)
  1. Open another terminal session
  2. Prepare for pushing the docker cli and docker container image, see https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/registry.md#using-the-docker-client
docker login registry.test:5000 -u gitlab-token -p "ypCa3Dzb23o5nvsixwPA"
docker pull hello-world:latest
docker tag hello-world:latest registry.test:5000/flightjs/flight:v1.0
  1. Push the container image => will be blocked by ContainerRepositoryProtectionRule
docker push registry.test:5000/flightjs/flight:v1.0
  1. This docker push should fail because the container registry protection rule protects the container repository from new images with the repository path
  2. Lets try pushing an image with another repository path
docker tag hello-world:latest registry.test:5000/flightjs/flight/sub-image:v1.0
docker push registry.test:5000/flightjs/flight/sub-image:v1.0
  1. This docker push should be successful because the container registry protection rule does not protect this new image.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #427546

Edited by Gerardo Navarro

Merge request reports