# HG changeset patch # User Balasankar 'Balu' C <balasankar@gitlab.com> # Date 1726603624 0 # Tue Sep 17 20:07:04 2024 +0000 # Node ID b10ba2458230fe99dfdcfa3e5adf29ea3930681d # Parent 872d4e892c2f1b8a8e607f1dca5762edb61cb888 Add Gitaly authentication token attribute Rather than re-use the attribute from GitLab Shell, Gitaly stores the token it uses to authenticate with GitLab under a unique attribute. Closes https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/8688 Changelog: changed Signed-off-by: Balasankar "Balu" C <balasankar@gitlab.com> diff --git a/files/gitlab-cookbooks/gitaly/attributes/default.rb b/files/gitlab-cookbooks/gitaly/attributes/default.rb --- a/files/gitlab-cookbooks/gitaly/attributes/default.rb +++ b/files/gitlab-cookbooks/gitaly/attributes/default.rb @@ -22,5 +22,8 @@ use_bundled_binaries: true, bin_path: "#{node['package']['install-dir']}/embedded/bin/git" }, - storage: [] + storage: [], + gitlab: { + secret_file: "#{node['gitaly']['dir']}/.gitlab_secret" + } } diff --git a/files/gitlab-cookbooks/gitaly/libraries/gitaly.rb b/files/gitlab-cookbooks/gitaly/libraries/gitaly.rb --- a/files/gitlab-cookbooks/gitaly/libraries/gitaly.rb +++ b/files/gitlab-cookbooks/gitaly/libraries/gitaly.rb @@ -30,6 +30,16 @@ check_duplicate_storage_paths end + def parse_secrets + # The secret should be same between GitLab Rails, GitLab Shell, and + # Gitaly. GitLab Shell has a priority of 10, which means it gets parsed + # before Gitaly and Gitlab['gitlab_shell']['secret_token'] will + # definitely have a value. + Gitlab['gitaly']['gitlab_secret'] ||= Gitlab['gitlab_shell']['secret_token'] + + LoggingHelper.warning("Gitaly and GitLab Shell specifies different secrets to authenticate with GitLab") if Gitlab['gitaly']['gitlab_secret'] != Gitlab['gitlab_shell']['secret_token'] + end + def gitaly_address listen_addr = user_config.dig('configuration', 'listen_addr') || package_default.dig('configuration', 'listen_addr') socket_path = user_config.dig('configuration', 'socket_path') || package_default.dig('configuration', 'socket_path') diff --git a/files/gitlab-cookbooks/gitaly/recipes/enable.rb b/files/gitlab-cookbooks/gitaly/recipes/enable.rb --- a/files/gitlab-cookbooks/gitaly/recipes/enable.rb +++ b/files/gitlab-cookbooks/gitaly/recipes/enable.rb @@ -89,6 +89,16 @@ gitlab_url, gitlab_relative_path = WebServerHelper.internal_api_url(node) +secret_file = node['gitaly']['configuration']['gitlab']['secret_file'] +file secret_file do + owner "root" + group "root" + mode "0644" + sensitive true + content node['gitaly']['gitlab_secret'] + notifies :restart, 'runit_service[gitaly]' if omnibus_helper.should_notify?('gitaly') +end + template "Create Gitaly config.toml" do path config_path source "gitaly-config.toml.erb" diff --git a/files/gitlab-cookbooks/package/libraries/helpers/secrets_helper.rb b/files/gitlab-cookbooks/package/libraries/helpers/secrets_helper.rb --- a/files/gitlab-cookbooks/package/libraries/helpers/secrets_helper.rb +++ b/files/gitlab-cookbooks/package/libraries/helpers/secrets_helper.rb @@ -120,6 +120,9 @@ 'incoming_email_auth_token' => Gitlab['mailroom']['incoming_email_auth_token'], 'service_desk_email_auth_token' => Gitlab['mailroom']['service_desk_email_auth_token'], }, + 'gitaly' => { + 'gitlab_secret' => Gitlab['gitaly']['gitlab_secret'] + } } if Gitlab['mattermost']['gitlab_enable'] diff --git a/spec/chef/cookbooks/gitaly/recipes/gitaly_spec.rb b/spec/chef/cookbooks/gitaly/recipes/gitaly_spec.rb --- a/spec/chef/cookbooks/gitaly/recipes/gitaly_spec.rb +++ b/spec/chef/cookbooks/gitaly/recipes/gitaly_spec.rb @@ -64,8 +64,10 @@ let(:pack_objects_cache_enabled) { true } let(:pack_objects_cache_dir) { '/pack-objects-cache' } let(:pack_objects_cache_max_age) { '10m' } + before do allow(Gitlab).to receive(:[]).and_call_original + allow(SecretsHelper).to receive(:generate_hex).and_return('4ecd22c031fee5c7368a5a102f76dc41') end context 'by default' do @@ -84,6 +86,10 @@ expect(chef_run.version_file('Create version file for Gitaly')).to notify('runit_service[gitaly]').to(:hup) end + it 'creates secret file for authenticating with GitLab' do + expect(chef_run).to create_file('/var/opt/gitlab/gitaly/.gitlab_secret').with_content('4ecd22c031fee5c7368a5a102f76dc41') + end + it 'populates gitaly config.toml with defaults' do expect(get_rendered_toml(chef_run, '/var/opt/gitlab/gitaly/config.toml')).to eq( { @@ -95,7 +101,8 @@ }, gitlab: { relative_url_root: '', - url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket' + url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket', + secret_file: '/var/opt/gitlab/gitaly/.gitlab_secret' }, 'gitlab-shell': { dir: '/opt/gitlab/embedded/service/gitlab-shell' @@ -132,6 +139,56 @@ end end + context 'with a user specified GitLab secret' do + context 'when the Gitlab Shell and Gitaly secrets match' do + before do + stub_gitlab_rb( + gitaly: { + gitlab_secret: 'my-super-secret-password' + }, + gitlab_shell: { + secret_token: 'my-super-secret-password' + } + ) + end + + it 'populates the secret file with specified value' do + expect(chef_run).to create_file('/var/opt/gitlab/gitaly/.gitlab_secret').with_content('my-super-secret-password') + end + + it 'does not log a warning' do + expect(LoggingHelper).not_to receive(:warning).with("Gitaly and GitLab Shell specifies different secrets to authenticate with GitLab") + + chef_run + end + end + + context 'when the Gitlab Shell and Gitaly secrets differ' do + before do + stub_gitlab_rb( + gitaly: { + gitlab_secret: 'password-for-gitaly' + }, + gitlab_shell: { + secret_token: 'password-for-shell' + } + ) + + allow(LoggingHelper).to receive(:warning).and_call_original + end + + it 'populates the secret file with specified value' do + expect(chef_run).to create_file('/var/opt/gitlab/gitaly/.gitlab_secret').with_content('password-for-gitaly') + end + + it 'logs a secret mismatch warning' do + expect(LoggingHelper).to receive(:warning).with("Gitaly and GitLab Shell specifies different secrets to authenticate with GitLab") + + chef_run + end + end + end + context 'log directory and runit group' do context 'default values' do it_behaves_like 'enabled logged service', 'gitaly', true, { log_directory_owner: 'git' } @@ -425,6 +482,7 @@ gitlab: { url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket', relative_url_root: '', + secret_file: '/var/opt/gitlab/gitaly/.gitlab_secret' }, logging: { dir: 'overridden_logging_path', @@ -618,7 +676,8 @@ read_timeout: 123, user: 'user123' }, - url: 'http://localhost:3000' + url: 'http://localhost:3000', + secret_file: '/var/opt/gitlab/gitaly/.gitlab_secret' }, 'gitlab-shell': { dir: '/opt/gitlab/embedded/service/gitlab-shell'