Skip to content
Open
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
13 changes: 12 additions & 1 deletion gems/aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,22 @@ def static_profile_process_credentials(options)
nil
end

def env_credentials(_options)
def env_credentials(options)
key = %w[AWS_ACCESS_KEY_ID AMAZON_ACCESS_KEY_ID AWS_ACCESS_KEY]
secret = %w[AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY]
token = %w[AWS_SESSION_TOKEN AMAZON_SESSION_TOKEN]
account_id = %w[AWS_ACCOUNT_ID]

# Don't return env creds directly if they're meant to be used as source credentials
# for assume role with credential_source = Environment
if Aws.shared_config.config_enabled?
profile_name = options[:config] ? options[:config].profile : nil
profile_name ||= determine_profile_name(options)
if Aws.shared_config.profile_uses_env_as_credential_source?(profile_name)
return nil
end
end

creds = Credentials.new(
envar(key),
envar(secret),
Expand Down
20 changes: 20 additions & 0 deletions gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,26 @@ def self.config_reader(*attrs)
:ignore_configured_endpoint_urls
)

# Check if a profile is configured for assume role with credential_source = Environment
# This is used to determine if environment credentials should be used as source credentials
# for role assumption rather than returned directly.
# @param profile [String] the profile name to check
# @return [Boolean] true if the profile has both role_arn and credential_source = Environment
def profile_uses_env_as_credential_source?(profile)
return false unless @config_enabled && profile

# Check both credentials and config files - credentials takes precedence
prof_cfg = @parsed_credentials.fetch(profile, {}) if @parsed_credentials
# Only check config if credentials didn't have the keys we need
if prof_cfg.nil? || (!prof_cfg['role_arn'] && @parsed_config)
prof_cfg = @parsed_config.fetch(profile, {})
end

prof_cfg &&
prof_cfg['role_arn'] &&
prof_cfg['credential_source'] == 'Environment'
end

private

# Get a config value from from shared credential/config files.
Expand Down
53 changes: 53 additions & 0 deletions gems/aws-sdk-core/spec/aws/credential_resolution_chain_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,59 @@ module Aws
region: 'us-east-1'
)
end

it 'assumes role when default profile has credential_source=Environment, not return env vars directly' do
stub_const(
'ENV',
'AWS_ACCESS_KEY_ID' => 'AKID_ENV_STUB',
'AWS_SECRET_ACCESS_KEY' => 'SECRET_ENV_STUB'
)

# Create empty credentials file (no default profile)
temp_credentials = Tempfile.new(['aws_credentials', '.ini'])
temp_credentials.write("")
temp_credentials.close

# Create config file with default profile using credential_source = Environment
temp_config = Tempfile.new(['aws_config', '.ini'])
temp_config.write(<<~CONFIG)
[default]
region = us-east-1
role_arn = arn:aws:iam::123456789012:role/foo
credential_source = Environment
CONFIG
temp_config.close

# Reload config with temp files
Aws.shared_config.fresh(
config_enabled: true,
credentials_path: temp_credentials.path,
config_path: temp_config.path
)

assume_role_stub(
'arn:aws:iam::123456789012:role/foo',
'AKID_ENV_STUB', # Source creds
'AR_AKID', # Assumed role creds
'AR_SECRET',
'AR_TOKEN'
)

# Don't specify profile - should use default profile
client = ApiHelper.sample_rest_xml::Client.new(
region: 'us-east-1'
)
creds = client.config.credentials.credentials

# Should use assumed role credentials
expect(creds.access_key_id).to eq('AR_AKID')
# Should NOT return env credentials directly
expect(creds.access_key_id).not_to eq('AKID_ENV_STUB')

# Cleanup
temp_config.unlink
temp_credentials.unlink
end
end

describe 'AWS_SDK_CONFIG_OPT_OUT set' do
Expand Down