Add service_type claim to decouple Container Virtual Registry from Dependency Proxy auth
What does this MR do and why?
Add a service_type claim to JWT tokens minted by ContainerProxyAuthenticationService (formerly DependencyProxyAuthenticationService) to distinguish between Container Virtual Registry and Dependency Proxy requests.
This provides defense-in-depth for cross-service access prevention:
- Tokens for VR requests get
service_type='virtual_registry' - Tokens for DP requests get
service_type='dependency_proxy' - Login tokens (no scope) have no
service_typeclaim
The service_type is determined by inspecting the scope parameter passed to the /jwt/auth endpoint by the Docker client.
Controllers now validate the service_type claim:
-
VirtualRegistries::ContainerControllerrequires'virtual_registry' -
Groups::DependencyProxy::ApplicationControlleracceptsnilor'dependency_proxy'(backward compatible with cached login tokens)
The validation logic is implemented as a hook in JwtAuthenticatable that controllers override.
Why rename to ContainerProxyAuthenticationService?
The service now authenticates both Dependency Proxy and Container Virtual Registry requests, so the name DependencyProxyAuthenticationService no longer accurately describes its scope. The new name reflects that it serves container proxy authentication for both features.
Why not also rename DependencyProxy::AuthTokenService?
We considered renaming DependencyProxy::AuthTokenService to ContainerProxy::AuthTokenService for consistency. However, this would require creating a new ContainerProxy bounded context in config/bounded_contexts.yml. Per the bounded contexts guidelines, new contexts should only be added when introducing a new product category or extracting from an overly large context. Neither applies here.
How to test and validate locally
This is a refactor - no new behavior is introduced. We just need to verify that both Dependency Proxy for Containers and Container Virtual Registry are still working as before.
Prepare a personal access token with a read_virtual_registry + write_virtual_registry scopes
docker login gdk.test:3000
# paste the personal access token when prompted for the password
docker system prune -a -f
docker pull gdk.test:3000/flightjs/dependency_proxy/containers/alpine:latest
docker pull gdk.test:3000/virtual_registries/container/1/library/nginx:latest
References
Issue: #579774 (closed)