Skip to content
Snippets Groups Projects
Commit 41a5e73e authored by Timo Furrer's avatar Timo Furrer Committed by Robert Marshall
Browse files

Generate and configure KAS WebSocket Token secret

This change set generates and configures a new secret for KAS.
It's used to sign and verify the WebSocket Token secret.

Refs:

- https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/issues/641
- https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/issues/644
- https://gitlab.com/gitlab-org/charts/gitlab/-/issues/5720

Changelog: added
parent 8386ee4a
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -2171,6 +2171,9 @@ external_url 'GENERATED_EXTERNAL_URL'
 
##! Shared secret used for authentication between different KAS instances in a multi-node setup
# gitlab_kas['private_api_secret_key'] = nil # Will be generated if not set. Base64 encoded and exactly 32 bytes long.
#
##! Secret used for WebSocket Token signing and verification. Must be shared in multi-node setup
# gitlab_kas['websocket_token_secret_key'] = nil # Will be generated if not set. Base64 encoded and exactly 72 bytes long.
 
##! Listen configuration for GitLab KAS
# gitlab_kas['listen_address'] = 'localhost:8150'
Loading
Loading
Loading
Loading
@@ -25,6 +25,7 @@ default['gitlab_kas']['internal_api_key_file'] = nil
default['gitlab_kas']['kubernetes_api_listen_address'] = 'localhost:8154'
default['gitlab_kas']['kubernetes_api_certificate_file'] = nil
default['gitlab_kas']['kubernetes_api_key_file'] = nil
default['gitlab_kas']['websocket_token_secret_key'] = nil
default['gitlab_kas']['private_api_secret_key'] = nil
default['gitlab_kas']['private_api_listen_address'] = 'localhost:8155'
default['gitlab_kas']['private_api_listen_network'] = 'tcp'
Loading
Loading
Loading
Loading
@@ -91,6 +91,7 @@ module GitlabKas
def parse_secrets
Gitlab['gitlab_kas']['api_secret_key'] ||= Base64.strict_encode64(SecretsHelper.generate_hex(16))
Gitlab['gitlab_kas']['private_api_secret_key'] ||= Base64.strict_encode64(SecretsHelper.generate_hex(16))
Gitlab['gitlab_kas']['websocket_token_secret_key'] ||= SecretsHelper.generate_base64(72)
end
 
def validate_secrets
Loading
Loading
@@ -100,10 +101,15 @@ module GitlabKas
raise "gitlab_kas['api_secret_key'] should be exactly 32 bytes" if api_secret_key.length != 32
end
 
return unless Gitlab['gitlab_kas']['private_api_secret_key']
if Gitlab['gitlab_kas']['private_api_secret_key']
private_api_secret_key = Base64.strict_decode64(Gitlab['gitlab_kas']['private_api_secret_key'])
raise "gitlab_kas['private_api_secret_key'] should be exactly 32 bytes" if private_api_secret_key.length != 32
end
return unless Gitlab['gitlab_kas']['websocket_token_secret_key']
 
private_api_secret_key = Base64.strict_decode64(Gitlab['gitlab_kas']['private_api_secret_key'])
raise "gitlab_kas['private_api_secret_key'] should be exactly 32 bytes" if private_api_secret_key.length != 32
websocket_token_secret_key = Base64.strict_decode64(Gitlab['gitlab_kas']['websocket_token_secret_key'])
raise "gitlab_kas['websocket_token_secret_key'] should be exactly 72 bytes" if websocket_token_secret_key.length != 72
end
 
def parse_redis_settings
Loading
Loading
Loading
Loading
@@ -26,6 +26,7 @@ gitlab_kas_static_etc_dir = '/opt/gitlab/etc/gitlab-kas'
gitlab_kas_config_file = File.join(working_dir, 'gitlab-kas-config.yml')
gitlab_kas_authentication_secret_file = File.join(working_dir, 'authentication_secret_file')
gitlab_kas_private_api_authentication_secret_file = File.join(working_dir, 'private_api_authentication_secret_file')
gitlab_kas_websocket_token_secret_file = File.join(working_dir, 'websocket_token_secret_file')
 
redis_params = redis_helper.redis_params
 
Loading
Loading
@@ -86,6 +87,14 @@ file gitlab_kas_private_api_authentication_secret_file do
notifies :restart, 'runit_service[gitlab-kas]' if omnibus_helper.should_notify?('gitlab-kas')
end
 
file gitlab_kas_websocket_token_secret_file do
content node['gitlab_kas']['websocket_token_secret_key']
owner 'root'
group account_helper.gitlab_group
mode '0640'
notifies :restart, 'runit_service[gitlab-kas]' if omnibus_helper.should_notify?('gitlab-kas')
end
file gitlab_kas_redis_password_file do
content redis_password
owner 'root'
Loading
Loading
@@ -115,6 +124,7 @@ template gitlab_kas_config_file do
node['gitlab_kas'].to_hash.merge(
authentication_secret_file: gitlab_kas_authentication_secret_file,
private_api_authentication_secret_file: gitlab_kas_private_api_authentication_secret_file,
websocket_token_secret_file: gitlab_kas_websocket_token_secret_file,
redis_network: redis_params[:network],
redis_address: redis_params[:address],
redis_ssl: redis_params[:ssl],
Loading
Loading
Loading
Loading
@@ -21,6 +21,7 @@ agent:
key_file: <%= @kubernetes_api_key_file %>
<%- end %>
url_path_prefix: /
websocket_token_secret_file: <%= @websocket_token_secret_file %>
info_cache_ttl: <%= @agent_info_cache_ttl %>s
info_cache_error_ttl: <%= @agent_info_cache_error_ttl %>s
gitlab:
Loading
Loading
Loading
Loading
@@ -99,7 +99,8 @@ class SecretsHelper
},
'gitlab_kas' => {
'api_secret_key' => Gitlab['gitlab_kas']['api_secret_key'],
'private_api_secret_key' => Gitlab['gitlab_kas']['private_api_secret_key']
'private_api_secret_key' => Gitlab['gitlab_kas']['private_api_secret_key'],
'websocket_token_secret_key' => Gitlab['gitlab_kas']['websocket_token_secret_key']
},
'suggested_reviewers' => {
'api_secret_key' => Gitlab['suggested_reviewers']['api_secret_key']
Loading
Loading
Loading
Loading
@@ -62,7 +62,8 @@ RSpec.describe 'gitlab-kas' do
listen: {
address: 'localhost:8154',
},
url_path_prefix: '/'
url_path_prefix: '/',
websocket_token_secret_file: "/var/opt/gitlab/gitlab-kas/websocket_token_secret_file"
}
),
observability: {
Loading
Loading
@@ -93,6 +94,7 @@ RSpec.describe 'gitlab-kas' do
it 'correctly renders the KAS authentication secret files' do
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-kas/authentication_secret_file").with_content { |content| Base64.strict_decode64(content).size == 32 }
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-kas/private_api_authentication_secret_file").with_content { |content| Base64.strict_decode64(content).size == 32 }
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-kas/websocket_token_secret_file").with_content { |content| Base64.strict_decode64(content).size == 72 }
end
 
it 'sets OWN_PRIVATE_API_URL and SSL_CERT_DIR' do
Loading
Loading
@@ -104,6 +106,7 @@ RSpec.describe 'gitlab-kas' do
context 'with user settings' do
let(:api_secret_key) { Base64.strict_encode64('1' * 32) }
let(:private_api_secret_key) { Base64.strict_encode64('2' * 32) }
let(:websocket_token_secret_key) { Base64.strict_encode64('3' * 72) }
 
before do
stub_gitlab_rb(
Loading
Loading
@@ -111,6 +114,7 @@ RSpec.describe 'gitlab-kas' do
gitlab_kas: {
api_secret_key: api_secret_key,
private_api_secret_key: private_api_secret_key,
websocket_token_secret_key: websocket_token_secret_key,
listen_address: 'localhost:5006',
listen_websocket: false,
observability_listen_address: '0.0.0.0:8151',
Loading
Loading
@@ -162,6 +166,7 @@ RSpec.describe 'gitlab-kas' do
it 'correctly renders the KAS authentication secret files' do
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-kas/authentication_secret_file").with_content(api_secret_key)
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-kas/private_api_authentication_secret_file").with_content(private_api_secret_key)
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-kas/websocket_token_secret_file").with_content(websocket_token_secret_key)
end
 
it 'sets OWN_PRIVATE_API_HOST' do
Loading
Loading
@@ -709,6 +714,7 @@ RSpec.describe 'gitlab-kas' do
@files ||= %w(
/var/opt/gitlab/gitlab-kas/authentication_secret_file
/var/opt/gitlab/gitlab-kas/private_api_authentication_secret_file
/var/opt/gitlab/gitlab-kas/websocket_token_secret_file
/var/opt/gitlab/gitlab-kas/redis_password_file
/var/opt/gitlab/gitlab-kas/redis_sentinels_password_file
)
Loading
Loading
Loading
Loading
@@ -105,7 +105,8 @@ RSpec.describe 'gitlab::database-migrations' do
 
context 'not set' do
before do
allow(SecretsHelper).to receive(:generate_base64).and_return('LFQLd2ayKNpthh+Ehxqy7ROxsmpzACy55EcOYoMfRlk=')
allow(SecretsHelper).to receive(:generate_base64).and_call_original
allow(SecretsHelper).to receive(:generate_base64).with(32).and_return('LFQLd2ayKNpthh+Ehxqy7ROxsmpzACy55EcOYoMfRlk=')
end
 
it 'generates a random root password and runs DB migration with GITLAB_ROOT_PASSWORD set to it' do
Loading
Loading
@@ -133,7 +134,8 @@ RSpec.describe 'gitlab::database-migrations' do
 
context 'initial license file' do
before do
allow(SecretsHelper).to receive(:generate_base64).and_return('LFQLd2ayKNpthh+Ehxqy7ROxsmpzACy55EcOYoMfRlk=')
allow(SecretsHelper).to receive(:generate_base64).and_call_original
allow(SecretsHelper).to receive(:generate_base64).with(32).and_return('LFQLd2ayKNpthh+Ehxqy7ROxsmpzACy55EcOYoMfRlk=')
end
 
it 'detects license file from /etc/gitlab' do
Loading
Loading
Loading
Loading
@@ -116,6 +116,7 @@ RSpec.describe 'gitlab::mailroom' do
 
context 'auth token is not specified' do
before do
allow(SecretsHelper).to receive(:generate_base64).and_call_original
allow(SecretsHelper).to receive(:generate_base64).with(32).and_return("a" * 32)
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment