diff --git a/app/graphql/mutations/dependency_proxy/group_settings/update.rb b/app/graphql/mutations/dependency_proxy/group_settings/update.rb index 9267d8af383395f0200ba90dad8a88a92a4fe750..37ce8de0b3475e96f49a952aea10eb374fcd1fe7 100644 --- a/app/graphql/mutations/dependency_proxy/group_settings/update.rb +++ b/app/graphql/mutations/dependency_proxy/group_settings/update.rb @@ -23,16 +23,11 @@ class Update < Mutations::BaseMutation description: copy_field_description(Types::DependencyProxy::ImageTtlGroupPolicyType, :enabled) argument :identity, GraphQL::Types::String, required: false, - experiment: { milestone: '17.10' }, - description: 'Identity credential used to authenticate with Docker Hub when pulling images. ' \ - 'Can be a username (for password or PAT) or organization name (for OAT). ' \ - 'Ignored if `dependency_proxy_containers_docker_hub_credentials` is disabled.' + description: copy_field_description(Types::DependencyProxy::GroupSettingType, :identity) argument :secret, GraphQL::Types::String, required: false, - experiment: { milestone: '17.10' }, description: 'Secret credential used to authenticate with Docker Hub when pulling images. ' \ - 'Can be a password, Personal Access Token (PAT), or Organization Access Token (OAT). ' \ - 'Ignored if `dependency_proxy_containers_docker_hub_credentials` is disabled.' + 'Can be a password, personal access token (PAT), or organization access token (OAT).' field :dependency_proxy_setting, Types::DependencyProxy::GroupSettingType, @@ -42,11 +37,6 @@ class Update < Mutations::BaseMutation def resolve(group_path:, **args) group = authorized_find!(group_path: group_path) - unless Feature.enabled?(:dependency_proxy_containers_docker_hub_credentials, group) - args.delete(:identity) - args.delete(:secret) - end - result = ::DependencyProxy::GroupSettings::UpdateService .new(container: group, current_user: current_user, params: args) .execute diff --git a/app/graphql/types/dependency_proxy/group_setting_type.rb b/app/graphql/types/dependency_proxy/group_setting_type.rb index b51d3d8a13f609f3a5c5f62143b1ac418cbd1045..0e28644fd1914e321b7b0c051e620971e7147a5f 100644 --- a/app/graphql/types/dependency_proxy/group_setting_type.rb +++ b/app/graphql/types/dependency_proxy/group_setting_type.rb @@ -10,13 +10,7 @@ class DependencyProxy::GroupSettingType < BaseObject field :enabled, GraphQL::Types::Boolean, null: false, description: 'Indicates whether the dependency proxy is enabled for the group.' field :identity, GraphQL::Types::String, null: true, - experiment: { milestone: '17.10' }, description: 'Identity credential used to authenticate with Docker Hub when pulling images. ' \ - 'Can be a username (for password or PAT) or organization name (for OAT). ' \ - 'Returns null if `dependency_proxy_containers_docker_hub_credentials` feature flag is disabled.' - - def identity - object.identity if Feature.enabled?(:dependency_proxy_containers_docker_hub_credentials, object.group) - end + 'Can be a username (for password or personal access token (PAT)) or organization name (for organization access token (OAT)).' end end diff --git a/app/models/dependency_proxy/group_setting.rb b/app/models/dependency_proxy/group_setting.rb index a9c865b8090c403d2e435a674c56ccef6991e843..0f1ea944b443e98b296eb50569ce5b3e7a723bb4 100644 --- a/app/models/dependency_proxy/group_setting.rb +++ b/app/models/dependency_proxy/group_setting.rb @@ -12,7 +12,6 @@ class DependencyProxy::GroupSetting < ApplicationRecord validates :identity, :secret, length: { maximum: 255 } def authorization_header - return {} unless Feature.enabled?(:dependency_proxy_containers_docker_hub_credentials, group) return {} unless identity? && secret? authorization = ActionController::HttpAuthentication::Basic.encode_credentials(identity, secret) diff --git a/config/feature_flags/gitlab_com_derisk/dependency_proxy_containers_docker_hub_credentials.yml b/config/feature_flags/gitlab_com_derisk/dependency_proxy_containers_docker_hub_credentials.yml deleted file mode 100644 index b7b930c07f1d4c69db209f9d19fbf9ee5d8038a8..0000000000000000000000000000000000000000 --- a/config/feature_flags/gitlab_com_derisk/dependency_proxy_containers_docker_hub_credentials.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: dependency_proxy_containers_docker_hub_credentials -feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331741 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/182748 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/521312 -milestone: '17.10' -group: group::container registry -type: gitlab_com_derisk -default_enabled: false diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 01ae2cd402c855a76d5a96ef1ef5794b8cd7ea1c..f29846817e2b4c9d98be77f0056b9e13253d5ae6 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -11262,8 +11262,8 @@ Input type: `UpdateDependencyProxySettingsInput` | <a id="mutationupdatedependencyproxysettingsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationupdatedependencyproxysettingsenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether the policy is enabled or disabled. | | <a id="mutationupdatedependencyproxysettingsgrouppath"></a>`groupPath` | [`ID!`](#id) | Group path for the group dependency proxy. | -| <a id="mutationupdatedependencyproxysettingsidentity"></a>`identity` {{< icon name="warning-solid" >}} | [`String`](#string) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.10. | -| <a id="mutationupdatedependencyproxysettingssecret"></a>`secret` {{< icon name="warning-solid" >}} | [`String`](#string) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.10. | +| <a id="mutationupdatedependencyproxysettingsidentity"></a>`identity` | [`String`](#string) | Identity credential used to authenticate with Docker Hub when pulling images. Can be a username (for password or personal access token (PAT)) or organization name (for organization access token (OAT)). | +| <a id="mutationupdatedependencyproxysettingssecret"></a>`secret` | [`String`](#string) | Secret credential used to authenticate with Docker Hub when pulling images. Can be a password, personal access token (PAT), or organization access token (OAT). | #### Fields @@ -24679,7 +24679,7 @@ Group-level Dependency Proxy settings. | Name | Type | Description | | ---- | ---- | ----------- | | <a id="dependencyproxysettingenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether the dependency proxy is enabled for the group. | -| <a id="dependencyproxysettingidentity"></a>`identity` {{< icon name="warning-solid" >}} | [`String`](#string) | **Introduced** in GitLab 17.10. **Status**: Experiment. Identity credential used to authenticate with Docker Hub when pulling images. Can be a username (for password or PAT) or organization name (for OAT). Returns null if `dependency_proxy_containers_docker_hub_credentials` feature flag is disabled. | +| <a id="dependencyproxysettingidentity"></a>`identity` | [`String`](#string) | Identity credential used to authenticate with Docker Hub when pulling images. Can be a username (for password or personal access token (PAT)) or organization name (for organization access token (OAT)). | ### `Deployment` diff --git a/doc/user/packages/dependency_proxy/_index.md b/doc/user/packages/dependency_proxy/_index.md index 00c2525a3c073f7f76428525178b303e4de3465e..b7486f8103716ddc8739b440ab79835d2303f1f7 100644 --- a/doc/user/packages/dependency_proxy/_index.md +++ b/doc/user/packages/dependency_proxy/_index.md @@ -188,6 +188,70 @@ build: You can also use [custom CI/CD variables](../../../ci/variables/_index.md#for-a-project) to store and access your personal access token or deploy token. +### Authenticate with Docker Hub + +{{< history >}} + +- Support for Docker Hub credentials [added](https://gitlab.com/gitlab-org/gitlab/-/issues/331741) in GitLab 17.10. + +{{< /history >}} + +By default, the Dependency Proxy does not use credentials when pulling images from Docker Hub. +You can configure Docker Hub authentication through the GraphQL API using your Docker Hub credentials or tokens. + +To authenticate with Docker Hub, you can use: + +- Your Docker Hub username and password. + - This method is not compatible with Docker Hub organizations that [enforce Single Sign-On (SSO)](https://docs.docker.com/security/faqs/single-sign-on/enforcement-faqs/#does-docker-sso-support-authenticating-through-the-command-line). +- A Docker Hub [Personal Access Token](https://docs.docker.com/security/for-developers/access-tokens/). +- A Docker Hub [Organization Access Token](https://docs.docker.com/security/for-admins/access-tokens/). + +UI support for configuring Docker Hub credentials for groups in self-managed instances is proposed in issue [521954](https://gitlab.com/gitlab-org/gitlab/-/issues/521954). + +#### Configure credentials using the GraphQL API + +To set Docker Hub credentials in the Dependency Proxy settings using the [GraphQL API](../../../api/graphql/_index.md): + +1. Go to GraphiQL: + - For GitLab.com, use [`https://gitlab.com/-/graphql-explorer`](https://gitlab.com/-/graphql-explorer). + - For GitLab Self-Managed, use `https://gitlab.example.com/-/graphql-explorer`. +1. In GraphiQL, enter this mutation: + + ```graphql + mutation { + updateDependencyProxySettings(input: { + enabled: true, + identity: "<identity>", + secret: "<secret>", + groupPath: "<group path>" + }) { + dependencyProxySetting { + enabled + identity + } + errors + } + } + ``` + + Where: + - `<identity>` is your username (for password or Personal Access Token) or organization name (for Organization Access Token). + - `<secret>` is your password, Personal Access Token, or Organization Access Token. + - `<group path>` is the path of the group where the Dependency Proxy is located. + +1. Select **Play**. +1. Check for any errors in the results pane. + +#### Verify your credentials + +After you authenticate with the Dependency Proxy, verify your Docker Hub credentials by pulling a Docker image: + +```shell +docker pull gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest +``` + +If authentication is successful, you'll see activity in your [Docker Hub Usage dashboard](https://hub.docker.com/usage/pulls). + ### Store a Docker image in dependency proxy cache To store a Docker image in dependency proxy storage: diff --git a/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb b/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb index 3fef8cf6cfd0237f384dbe5434a85a8c1b9f6104..f4d88ad9c4d6abd7f45ffe4d347e20ec8504d2b2 100644 --- a/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb +++ b/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb @@ -27,16 +27,6 @@ errors: [] ) end - - context 'with dependency_proxy_containers_docker_hub_credentials disabled' do - before do - stub_feature_flags(dependency_proxy_containers_docker_hub_credentials: false) - end - - it_behaves_like 'updating the dependency proxy group settings attributes', - from: { enabled: true, identity: 'username', secret: 'secret' }, - to: { enabled: false, identity: 'username', secret: 'secret' } - end end shared_examples 'denying access to dependency proxy group settings' do diff --git a/spec/models/dependency_proxy/group_setting_spec.rb b/spec/models/dependency_proxy/group_setting_spec.rb index e3bea555ba610866b741d2797876d86d8931b0ee..0c10658f79b330eb03e2e13d3bc3ac72a46efcd2 100644 --- a/spec/models/dependency_proxy/group_setting_spec.rb +++ b/spec/models/dependency_proxy/group_setting_spec.rb @@ -51,10 +51,6 @@ subject { dependency_proxy_setting.authorization_header } - shared_examples 'empty authorization headers' do - it { is_expected.to eq({}) } - end - context 'with identity and secret set' do let(:expected_headers) { { Authorization: 'Basic aTpz' } } @@ -63,14 +59,6 @@ end it { is_expected.to eq(expected_headers) } - - context 'when dependency_proxy_containers_docker_hub_credentials is disabled' do - before do - stub_feature_flags(dependency_proxy_containers_docker_hub_credentials: false) - end - - it_behaves_like 'empty authorization headers' - end end context 'with identity and secret not set' do @@ -78,15 +66,7 @@ dependency_proxy_setting.update!(identity: nil, secret: nil) end - it_behaves_like 'empty authorization headers' - - context 'when dependency_proxy_containers_docker_hub_credentials is disabled' do - before do - stub_feature_flags(dependency_proxy_containers_docker_hub_credentials: false) - end - - it_behaves_like 'empty authorization headers' - end + it { is_expected.to eq({}) } end end end diff --git a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb index 7e5d98abf775981bc288c2f3b8df1f42d7913f8b..45f3f606ce9eec5ef423ecd187e72940f9721e8b 100644 --- a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb +++ b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb @@ -89,22 +89,6 @@ end it_behaves_like 'dependency proxy group setting query' - - context 'with dependency_proxy_containers_docker_hub_credentials disabled' do - before do - stub_feature_flags(dependency_proxy_containers_docker_hub_credentials: false) - end - - it 'does not return the identity' do - group.add_owner(user) - post_query - - expect(dependency_proxy_group_setting_response).to eq( - 'enabled' => true, - 'identity' => nil - ) - end - end end context 'without the settings model created' do