Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion app/services/encryption/kms_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ class KmsClient
end
# rubocop:enable Layout/LineLength

attr_reader :kms_key_id

def initialize(kms_key_id: IdentityConfig.store.aws_kms_key_id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we update AwsKmsClientHelper too to accept a key_id?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client helper already accepts a key ID argument for the mapped results. I added the key ID for the single operation stub.

@kms_key_id = kms_key_id
end

def encrypt(plaintext, encryption_context)
KmsLogger.log(:encrypt, encryption_context)
return encrypt_kms(plaintext, encryption_context) if FeatureManagement.use_kms?
Expand Down Expand Up @@ -69,7 +75,7 @@ def encrypt_raw_kms(plaintext, encryption_context)

KMS_CLIENT_POOL.with do |client|
client.encrypt(
key_id: IdentityConfig.store.aws_kms_key_id,
key_id: kms_key_id,
plaintext: plaintext,
encryption_context: encryption_context,
).ciphertext_blob
Expand Down
2 changes: 2 additions & 0 deletions config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ aws_http_retry_max_delay: 1
aws_kms_key_id: alias/login-dot-gov-test-keymaker
aws_kms_client_contextless_pool_size: 5
aws_kms_client_multi_pool_size: 5
aws_kms_multi_region_key_id: alias/login-dot-gov-keymaker-multi-region
aws_kms_multi_region_write_enabled: false
aws_logo_bucket: ''
aws_region: 'us-west-2'
backup_code_cost: '2000$8$1$'
Expand Down
2 changes: 2 additions & 0 deletions lib/identity_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ def self.build_store(config_map)
config.add(:aws_kms_client_contextless_pool_size, type: :integer)
config.add(:aws_kms_client_multi_pool_size, type: :integer)
config.add(:aws_kms_key_id, type: :string)
config.add(:aws_kms_multi_region_key_id, type: :string)
config.add(:aws_kms_multi_region_write_enabled, type: :boolean)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to add a spec for this being enabled/disabled, or does that come later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will come later

config.add(:aws_logo_bucket, type: :string)
config.add(:aws_region, type: :string)
config.add(:backup_code_cost, type: :string)
Expand Down
30 changes: 29 additions & 1 deletion spec/services/encryption/kms_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
before do
stub_const(
'Encryption::KmsClient::KMS_CLIENT_POOL',
FakeConnectionPool.new { Aws::KMS::Client.new(region: aws_region) },
FakeConnectionPool.new { aws_kms_client },
)

# rubocop:disable Layout/LineLength
Expand Down Expand Up @@ -36,6 +36,7 @@
allow(IdentityConfig.store).to receive(:aws_kms_key_id).and_return(key_id)
end

let(:aws_kms_client) { Aws::KMS::Client.new(region: aws_region) }
let(:key_id) { 'key1' }
let(:plaintext) { 'a' * 3000 + 'b' * 3000 + 'c' * 3000 }
let(:encryption_context) { { 'context' => 'attribute-bundle', 'user_id' => '123-abc-456-def' } }
Expand Down Expand Up @@ -72,6 +73,33 @@
end
end

context 'with a KMS key ID specified' do
subject { described_class.new(kms_key_id: 'custom-key-id') }

before do
stub_mapped_aws_kms_client(
[
# rubocop:disable Layout/LineLength
{ plaintext: 'a' * 3000, ciphertext: 'us-north-1:kms1', key_id: 'custom-key-id', region: 'us-north-1' },
{ plaintext: 'b' * 3000, ciphertext: 'us-north-1:kms2', key_id: 'custom-key-id', region: 'us-north-1' },
{ plaintext: 'c' * 3000, ciphertext: 'us-north-1:kms3', key_id: 'custom-key-id', region: 'us-north-1' },
# rubocop:enable Layout/LineLength
],
)
end

it 'encrypts with the specified key ID' do
result = subject.encrypt(plaintext, encryption_context)

expect(result).to eq(kms_ciphertext)
expect(aws_kms_client.api_requests.count).to eq(3)

aws_kms_client.api_requests.each do |api_request|
expect(api_request[:params][:key_id]).to eq('custom-key-id')
end
end
end

context 'with KMS disabled' do
let(:kms_enabled) { false }

Expand Down
5 changes: 4 additions & 1 deletion spec/support/aws_kms_client.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module AwsKmsClientHelper
def stub_aws_kms_client(random_key = random_str, ciphered_key = random_str)
def stub_aws_kms_client(
random_key = random_str,
ciphered_key = random_str,
aws_key_id = IdentityConfig.store.aws_kms_key_id
)
Aws.config[:kms] = {
stub_responses: {
encrypt: { ciphertext_blob: ciphered_key, key_id: aws_key_id },
Expand Down