From 48fb67c6a57f052c52fdd3381ddab80f46c88dca Mon Sep 17 00:00:00 2001 From: Jake Goldsborough Date: Thu, 21 Aug 2025 14:49:15 -0700 Subject: [PATCH 1/3] Add support for credential_source=Environment in SharedConfig - Implements missing Environment credential source documented in AWS CLI docs - Returns Credentials object using AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN - Includes comprehensive test coverage - All existing tests pass (2315 examples, 0 failures) --- .../lib/aws-sdk-core/shared_config.rb | 6 +++ .../spec/aws/shared_config_spec.rb | 50 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb b/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb index e33d5d86e33..05484682f6e 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb @@ -369,6 +369,12 @@ def credentials_from_source(credential_source, config) ) when 'EcsContainer' ECSCredentials.new + when 'Environment' + Credentials.new( + ENV['AWS_ACCESS_KEY_ID'], + ENV['AWS_SECRET_ACCESS_KEY'], + ENV['AWS_SESSION_TOKEN'] + ) else raise Errors::InvalidCredentialSourceError, "Unsupported credential_source: #{credential_source}" end diff --git a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb index 6cf1a1bb1cd..84e8f0433ed 100644 --- a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb +++ b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb @@ -473,5 +473,55 @@ module Aws .to eq('http://localhost:8000') end end + + context 'credentials_from_source' do + let(:config) { SharedConfig.new } + + context 'with Environment credential source' do + before do + stub_const('ENV', { + 'AWS_ACCESS_KEY_ID' => 'test_access_key', + 'AWS_SECRET_ACCESS_KEY' => 'test_secret_key', + 'AWS_SESSION_TOKEN' => 'test_session_token' + }) + end + + it 'returns Credentials with environment variables' do + credentials = config.send(:credentials_from_source, 'Environment', nil) + + expect(credentials).to be_a(Aws::Credentials) + expect(credentials.access_key_id).to eq('test_access_key') + expect(credentials.secret_access_key).to eq('test_secret_key') + expect(credentials.session_token).to eq('test_session_token') + end + + context 'without session token' do + before do + stub_const('ENV', { + 'AWS_ACCESS_KEY_ID' => 'test_access_key', + 'AWS_SECRET_ACCESS_KEY' => 'test_secret_key' + }) + end + + it 'returns Credentials with nil session token' do + credentials = config.send(:credentials_from_source, 'Environment', nil) + + expect(credentials).to be_a(Aws::Credentials) + expect(credentials.access_key_id).to eq('test_access_key') + expect(credentials.secret_access_key).to eq('test_secret_key') + expect(credentials.session_token).to be_nil + end + end + end + + context 'with unsupported credential source' do + it 'raises InvalidCredentialSourceError' do + expect { + config.send(:credentials_from_source, 'UnsupportedSource', nil) + }.to raise_error(Aws::Errors::InvalidCredentialSourceError, + 'Unsupported credential_source: UnsupportedSource') + end + end + end end end From d98e2d05ef3ff81ca2746bfacf2fc78b9bd69a63 Mon Sep 17 00:00:00 2001 From: Richard Wang Date: Mon, 25 Aug 2025 09:13:13 -0700 Subject: [PATCH 2/3] Add feature id tracking and more tests --- .../lib/aws-sdk-core/shared_config.rb | 7 ++- .../aws/credential_resolution_chain_spec.rb | 49 +++++++++++++++++++ .../spec/aws/shared_config_spec.rb | 9 ++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb b/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb index 05484682f6e..b270b6ba12c 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb @@ -370,11 +370,14 @@ def credentials_from_source(credential_source, config) when 'EcsContainer' ECSCredentials.new when 'Environment' - Credentials.new( + creds = Credentials.new( ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'], - ENV['AWS_SESSION_TOKEN'] + ENV['AWS_SESSION_TOKEN'], + account_id: ENV['AWS_ACCOUNT_ID'] ) + creds.metrics = ['CREDENTIALS_ENV_VARS'] + creds else raise Errors::InvalidCredentialSourceError, "Unsupported credential_source: #{credential_source}" end diff --git a/gems/aws-sdk-core/spec/aws/credential_resolution_chain_spec.rb b/gems/aws-sdk-core/spec/aws/credential_resolution_chain_spec.rb index 60404c67e6f..80a57339351 100644 --- a/gems/aws-sdk-core/spec/aws/credential_resolution_chain_spec.rb +++ b/gems/aws-sdk-core/spec/aws/credential_resolution_chain_spec.rb @@ -960,6 +960,55 @@ module Aws region: 'us-east-1' ) end + + it 'can assume a role with ENV as a source' do + stub_const( + 'ENV', + 'AWS_ACCESS_KEY_ID' => 'AKID_ENV_STUB', + 'AWS_SECRET_ACCESS_KEY' => 'SECRET_ENV_STUB' + ) + profile = 'ar_env_src' + assume_role_stub( + 'arn:aws:iam::123456789012:role/foo', + 'AKID_ENV_STUB', + 'AR_AKID', + 'AR_SECRET', + 'AR_TOKEN' + ) + client = ApiHelper.sample_rest_xml::Client.new( + profile: profile, + region: 'us-east-1' + ) + expect( + client.config.credentials.credentials.access_key_id + ).to eq('AR_AKID') + expect(metric_values(client.config.credentials.metrics)).to include('p', 'g', 'i') + end + + it 'emits correct UserAgent metrics during STS calls for ENV as a source' do + stub_const( + 'ENV', + 'AWS_ACCESS_KEY_ID' => 'AKID_ENV_STUB', + 'AWS_SECRET_ACCESS_KEY' => 'SECRET_ENV_STUB' + ) + profile = 'ar_env_src' + assume_role_stub( + 'arn:aws:iam::123456789012:role/foo', + 'AKID_ENV_STUB', + 'AR_AKID', + 'AR_SECRET', + 'AR_TOKEN' + ) + expect_any_instance_of(STS::Client).to receive(:assume_role).and_wrap_original do |m, *args| + resp = m.call(*args) + expect(metrics_from_user_agent_header(resp)).to include('p', 'g') + resp + end + ApiHelper.sample_rest_xml::Client.new( + profile: profile, + region: 'us-east-1' + ) + end end describe 'AWS_SDK_CONFIG_OPT_OUT set' do diff --git a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb index 84e8f0433ed..67248ea8ebf 100644 --- a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb +++ b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb @@ -482,7 +482,8 @@ module Aws stub_const('ENV', { 'AWS_ACCESS_KEY_ID' => 'test_access_key', 'AWS_SECRET_ACCESS_KEY' => 'test_secret_key', - 'AWS_SESSION_TOKEN' => 'test_session_token' + 'AWS_SESSION_TOKEN' => 'test_session_token', + 'AWS_ACCOUNT_ID' => 'test_account_id' }) end @@ -493,9 +494,10 @@ module Aws expect(credentials.access_key_id).to eq('test_access_key') expect(credentials.secret_access_key).to eq('test_secret_key') expect(credentials.session_token).to eq('test_session_token') + expect(credentials.account_id).to eq('test_account_id') end - context 'without session token' do + context 'minimum inputs required' do before do stub_const('ENV', { 'AWS_ACCESS_KEY_ID' => 'test_access_key', @@ -503,13 +505,14 @@ module Aws }) end - it 'returns Credentials with nil session token' do + it 'returns Credentials with minimum inputs' do credentials = config.send(:credentials_from_source, 'Environment', nil) expect(credentials).to be_a(Aws::Credentials) expect(credentials.access_key_id).to eq('test_access_key') expect(credentials.secret_access_key).to eq('test_secret_key') expect(credentials.session_token).to be_nil + expect(credentials.session_token).to be_nil end end end From 72ca1bdc577187711a155cba993d2dc3e10894af Mon Sep 17 00:00:00 2001 From: Richard Wang Date: Mon, 25 Aug 2025 09:58:26 -0700 Subject: [PATCH 3/3] Add CHANGELOG entry and bump min core --- build_tools/services.rb | 4 +- gems/aws-sdk-core/CHANGELOG.md | 2 + .../spec/aws/shared_config_spec.rb | 53 ------------------- 3 files changed, 4 insertions(+), 55 deletions(-) diff --git a/build_tools/services.rb b/build_tools/services.rb index d01c193f55a..2c11ae86996 100644 --- a/build_tools/services.rb +++ b/build_tools/services.rb @@ -9,10 +9,10 @@ class ServiceEnumerator MANIFEST_PATH = File.expand_path('../../services.json', __FILE__) # Minimum `aws-sdk-core` version for new gem builds - MINIMUM_CORE_VERSION = "3.228.0" + MINIMUM_CORE_VERSION = "3.231.0" # Minimum `aws-sdk-core` version for new S3 gem builds - MINIMUM_CORE_VERSION_S3 = "3.228.0" + MINIMUM_CORE_VERSION_S3 = "3.231.0" EVENTSTREAM_PLUGIN = "Aws::Plugins::EventStreamConfiguration" diff --git a/gems/aws-sdk-core/CHANGELOG.md b/gems/aws-sdk-core/CHANGELOG.md index 18588223da6..2cb70a23703 100644 --- a/gems/aws-sdk-core/CHANGELOG.md +++ b/gems/aws-sdk-core/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Feature - Add support for ENV as credential source for `AssumeRoleCredentials`. + 3.230.0 (2025-08-21) ------------------ diff --git a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb index 67248ea8ebf..6cf1a1bb1cd 100644 --- a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb +++ b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb @@ -473,58 +473,5 @@ module Aws .to eq('http://localhost:8000') end end - - context 'credentials_from_source' do - let(:config) { SharedConfig.new } - - context 'with Environment credential source' do - before do - stub_const('ENV', { - 'AWS_ACCESS_KEY_ID' => 'test_access_key', - 'AWS_SECRET_ACCESS_KEY' => 'test_secret_key', - 'AWS_SESSION_TOKEN' => 'test_session_token', - 'AWS_ACCOUNT_ID' => 'test_account_id' - }) - end - - it 'returns Credentials with environment variables' do - credentials = config.send(:credentials_from_source, 'Environment', nil) - - expect(credentials).to be_a(Aws::Credentials) - expect(credentials.access_key_id).to eq('test_access_key') - expect(credentials.secret_access_key).to eq('test_secret_key') - expect(credentials.session_token).to eq('test_session_token') - expect(credentials.account_id).to eq('test_account_id') - end - - context 'minimum inputs required' do - before do - stub_const('ENV', { - 'AWS_ACCESS_KEY_ID' => 'test_access_key', - 'AWS_SECRET_ACCESS_KEY' => 'test_secret_key' - }) - end - - it 'returns Credentials with minimum inputs' do - credentials = config.send(:credentials_from_source, 'Environment', nil) - - expect(credentials).to be_a(Aws::Credentials) - expect(credentials.access_key_id).to eq('test_access_key') - expect(credentials.secret_access_key).to eq('test_secret_key') - expect(credentials.session_token).to be_nil - expect(credentials.session_token).to be_nil - end - end - end - - context 'with unsupported credential source' do - it 'raises InvalidCredentialSourceError' do - expect { - config.send(:credentials_from_source, 'UnsupportedSource', nil) - }.to raise_error(Aws::Errors::InvalidCredentialSourceError, - 'Unsupported credential_source: UnsupportedSource') - end - end - end end end