Skip to content

Enforce Dependency proxy access token scope checks, behind a feature flag

Context

What does this MR do and why?

  • During Dependency proxy authentication, enforce scope checks on personal access tokens and group access tokens (we already enforce scope checks on group deploy tokens):
    • docker login succeeds if the token has the required scopes read_registry + write_registry, or api. Otherwise, 403 (forbidden) is returned.
    • The check is behind the feature flag enforce_abilities_check_for_dependency_proxy.
  • Expands the list of abilities we accept to [read_container_image + create_container_image] or [build_read_container_image + build_create_container_image] (discussion)
  • Add TODO comments to cleanup code and specs related to the earlier scope check feature flag, packages_dependency_proxy_containers_scope_check. We have decided to go with the approach in #426887, instead of the approach we planned in !136655 (merged). The presence of the feature flag enforce_abilities_check_for_dependency_proxy alongside packages_dependency_proxy_containers_scope_check can be confusing, so hopefully these TODO comments will help clarify.

References

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

NA

How to set up and validate locally

Testing Dependency proxy invoked from CLI with an access token

Very similar to the local testing for !181756. But this time, instead of just logging, the request will be rejected if the FF is enabled.

🧪 Setup

Prepare a group with dependency proxy enabled ready. For this example, we'll use flightjs.

Prepare two PATs:

  • (1) with read_registry and write_registry scopes
  • (2) with read_registry scope only

🔬 Testing

  1. Login to Dependency proxy using PAT (1):

docker login gdk.test:3000/flightjs/dependency_proxy/containers -u <username> -p <pat1>

Expected result: Login Succeeded

WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /Users/rad/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
  1. Login to Dependency proxy using PAT (2):

Expected result: Login Succeeded

  1. Enable the feature flag: Feature.enable(:enforce_abilities_check_for_dependency_proxy)
  2. Login again using PAT (2)

Expected result: 403

WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get "http://gdk.test:3000/v2/": error parsing HTTP 403 response body: no error details found in HTTP response body: "{\"message\":\"access forbidden\",\"status\":\"error\",\"http_status\":403}"

Testing Dependency proxy invoked from CI

🧪 Setup

Prepare a project that has a .gitlab-ci.yml that authenticates with Dependency proxy. Refer to the documentation for an example .gitlab-ci.yml, or you can use this:

image: gdk.test:3000/flightjs/dependency_proxy/containers/alpine:latest

stages:
  - deploy

deploy:
  stage: deploy
  before_script:
    - echo "$CI_DEPENDENCY_PROXY_PASSWORD" | docker login $CI_DEPENDENCY_PROXY_SERVER -u $CI_DEPENDENCY_PROXY_USER --password-stdin
  script:
    - docker build -t test .
  script:
    - echo "Hello, world"

Before running the tests, tail the authentication logs with tail -f log/auth_json.log | grep "Dependency proxy missing authentication abilities"

🔬 Testing

Commit to the project to trigger a new pipeline, or rerun an existing pipeline.

The job should succeed on both master and the MR branch.

On master:

You'll see an output in the auth_json.log tail:

{"severity":"WARN","time":"2025-03-04T08:14:41.657Z","correlation_id":"01JNG3HAYWJ3AMQB47W0S7BN4W","meta.caller_id":"JwtController#auth","meta.feature_category":"container_registry","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.http_router_rule_action":"proxy","meta.user":"root","meta.user_id":1,"meta.client_id":"user/1","message":"Dependency proxy missing authentication abilities","authentication_abilities":["read_project","build_download_code","build_push_code","build_read_container_image","build_create_container_image","build_destroy_container_image"],"username":"root","user_id":1}

On the MR branch:

The message "Dependency proxy missing authentication abilities" should not be logged.

Related to #520313 (closed)

Edited by Radamanthus Batnag

Merge request reports

Loading