Skip to content

Commit

Permalink
Credential scope config option
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermp committed Oct 17, 2023
1 parent a935633 commit 138718e
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def built_in_client_context_param_value(param_data)
else
'context.config.use_dualstack_endpoint'
end
when 'AWS::Auth::CredentialScope'
'context.config.credentials.credential_scope'
when 'AWS::STS::UseGlobalEndpoint'
"context.config.sts_regional_endpoints == 'legacy'"
when 'AWS::S3::UseGlobalEndpoint'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def static_credentials(options)
Credentials.new(
options[:config].access_key_id,
options[:config].secret_access_key,
options[:config].session_token
options[:config].session_token,
options[:config].credential_scope
)
end
end
Expand Down Expand Up @@ -94,7 +95,8 @@ 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]
Credentials.new(envar(key), envar(secret), envar(token))
scope = %w[AWS_CREDENTIAL_SCOPE]
Credentials.new(envar(key), envar(secret), envar(token), envar(scope))
end

def envar(keys)
Expand Down
18 changes: 12 additions & 6 deletions gems/aws-sdk-core/lib/aws-sdk-core/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,27 @@ class Credentials
# @param [String] access_key_id
# @param [String] secret_access_key
# @param [String] session_token (nil)
def initialize(access_key_id, secret_access_key, session_token = nil)
# @param [String] credential_scope (nil)
def initialize(access_key_id, secret_access_key, session_token = nil,
credential_scope = nil)
@access_key_id = access_key_id
@secret_access_key = secret_access_key
@session_token = session_token
@credential_scope = credential_scope
end

# @return [String, nil]
# @return [String]
attr_reader :access_key_id

# @return [String, nil]
# @return [String]
attr_reader :secret_access_key

# @return [String, nil]
attr_reader :session_token

# @return [String, nil]
attr_reader :credential_scope

# @return [Credentials]
def credentials
self
Expand All @@ -30,9 +36,9 @@ def credentials
# access key are both set.
def set?
!access_key_id.nil? &&
!access_key_id.empty? &&
!secret_access_key.nil? &&
!secret_access_key.empty?
!access_key_id.empty? &&
!secret_access_key.nil? &&
!secret_access_key.empty?
end

# Removing the secret access key from the default inspect string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class CredentialsConfiguration < Seahorse::Client::Plugin

option(:session_token, doc_type: String, docstring: '')

option(:credential_scope, doc_type: String, docstring: '')

option(:profile,
doc_default: 'default',
doc_type: String,
Expand Down Expand Up @@ -57,13 +59,15 @@ class CredentialsConfiguration < Seahorse::Client::Plugin
locations will be searched for credentials:
* `Aws.config[:credentials]`
* The `:access_key_id`, `:secret_access_key`, and `:session_token` options.
* ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']
* The `:access_key_id`, `:secret_access_key`, `:session_token`, and
`credential_scope` options.
* ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'],
ENV['AWS_SESSION_TOKEN'], and ENV['AWS_CREDENTIAL_SCOPE']
* `~/.aws/credentials`
* `~/.aws/config`
* EC2/ECS IMDS instance profile - When used by default, the timeouts
are very aggressive. Construct and pass an instance of
`Aws::InstanceProfileCredentails` or `Aws::ECSCredentials` to
`Aws::InstanceProfileCredentials` or `Aws::ECSCredentials` to
enable retries and extended timeouts. Instance profile credential
fetching can be disabled by setting ENV['AWS_EC2_METADATA_DISABLED']
to true.
Expand Down
3 changes: 2 additions & 1 deletion gems/aws-sdk-core/lib/aws-sdk-core/shared_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ def credentials_from_profile(prof_config)
creds = Credentials.new(
prof_config['aws_access_key_id'],
prof_config['aws_secret_access_key'],
prof_config['aws_session_token']
prof_config['aws_session_token'],
prof_config['aws_credential_scope']
)
creds if creds.set?
end
Expand Down
49 changes: 28 additions & 21 deletions gems/aws-sdk-core/spec/aws/credential_provider_chain_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
module Aws
describe CredentialProviderChain do
def random_creds
{ access_key_id: SecureRandom.hex,
secret_access_key: SecureRandom.hex, session_token: SecureRandom.hex }
{
access_key_id: SecureRandom.hex,
secret_access_key: SecureRandom.hex,
session_token: SecureRandom.hex,
credential_scope: SecureRandom.hex
}
end

def with_shared_credentials(profile_name = SecureRandom.hex, credentials_file = nil)
Expand All @@ -19,6 +23,7 @@ def with_shared_credentials(profile_name = SecureRandom.hex, credentials_file =
aws_access_key_id = #{creds[:access_key_id]}
aws_secret_access_key = #{creds[:secret_access_key]}
aws_session_token = #{creds[:session_token]}
aws_credential_scope = #{creds[:credential_scope]}
CREDS
allow(Dir).to receive(:home).and_return('HOME')
allow(File).to receive(:exist?).with(path).and_return(true)
Expand All @@ -29,9 +34,10 @@ def with_shared_credentials(profile_name = SecureRandom.hex, credentials_file =

def with_env_credentials
creds = random_creds
env['AWS_ACCESS_KEY_ID'] = creds[:access_key_id]
env['AWS_SECRET_ACCESS_KEY'] = creds[:secret_access_key]
env['AWS_SESSION_TOKEN'] = creds[:session_token]
ENV['AWS_ACCESS_KEY_ID'] = creds[:access_key_id]
ENV['AWS_SECRET_ACCESS_KEY'] = creds[:secret_access_key]
ENV['AWS_SESSION_TOKEN'] = creds[:session_token]
ENV['AWS_CREDENTIAL_SCOPE'] = creds[:credential_scope]
creds
end

Expand All @@ -40,6 +46,7 @@ def with_config_credentials
allow(config).to receive(:access_key_id).and_return(creds[:access_key_id])
allow(config).to receive(:secret_access_key).and_return(creds[:secret_access_key])
allow(config).to receive(:session_token).and_return(creds[:session_token])
allow(config).to receive(:credential_scope).and_return(creds[:credential_scope])
creds
end

Expand All @@ -49,15 +56,15 @@ def validate_credentials(expected_creds)
expect(creds.access_key_id).to eq(expected_creds[:access_key_id])
expect(creds.secret_access_key).to eq(expected_creds[:secret_access_key])
expect(creds.session_token).to eq(expected_creds[:session_token])
expect(creds.credential_scope).to eq(expected_creds[:credential_scope])
end

let(:env) { {} }

let(:config) do
double('config',
access_key_id: nil,
secret_access_key: nil,
session_token: nil,
credential_scope: nil,
profile: nil,
region: nil,
instance_profile_credentials_timeout: 1,
Expand All @@ -71,7 +78,6 @@ def validate_credentials(expected_creds)
let(:credentials) { chain.resolve }

before(:each) do
stub_const('ENV', env)
allow(InstanceProfileCredentials).to receive(:new).and_return(mock_instance_creds)
end

Expand All @@ -82,31 +88,32 @@ def validate_credentials(expected_creds)

it 'hydrates credentials from ENV with prefix AWS_' do
expected_creds = random_creds
env['AWS_ACCESS_KEY_ID'] = expected_creds[:access_key_id]
env['AWS_SECRET_ACCESS_KEY'] = expected_creds[:secret_access_key]
env['AWS_SESSION_TOKEN'] = expected_creds[:session_token]
ENV['AWS_ACCESS_KEY_ID'] = expected_creds[:access_key_id]
ENV['AWS_SECRET_ACCESS_KEY'] = expected_creds[:secret_access_key]
ENV['AWS_SESSION_TOKEN'] = expected_creds[:session_token]
ENV['AWS_CREDENTIAL_SCOPE'] = expected_creds[:credential_scope]
validate_credentials(expected_creds)
end

it 'hydrates credentials from ENV with prefix AMAZON_' do
expected_creds = random_creds
env['AMAZON_ACCESS_KEY_ID'] = expected_creds[:access_key_id]
env['AMAZON_SECRET_ACCESS_KEY'] = expected_creds[:secret_access_key]
env['AMAZON_SESSION_TOKEN'] = expected_creds[:session_token]
expected_creds = random_creds.merge(credential_scope: nil)
ENV['AMAZON_ACCESS_KEY_ID'] = expected_creds[:access_key_id]
ENV['AMAZON_SECRET_ACCESS_KEY'] = expected_creds[:secret_access_key]
ENV['AMAZON_SESSION_TOKEN'] = expected_creds[:session_token]
validate_credentials(expected_creds)
end

it 'hydrates credentials from ENV at AWS_ACCESS_KEY & AWS_SECRET_KEY' do
expected_creds = random_creds.merge(session_token: nil)
env['AWS_ACCESS_KEY'] = expected_creds[:access_key_id]
env['AWS_SECRET_KEY'] = expected_creds[:secret_access_key]
expected_creds = random_creds.merge(session_token: nil, credential_scope: nil)
ENV['AWS_ACCESS_KEY'] = expected_creds[:access_key_id]
ENV['AWS_SECRET_KEY'] = expected_creds[:secret_access_key]
validate_credentials(expected_creds)
end

it 'hydrates credentials from ENV at AWS_ACCESS_KEY_ID & AWS_SECRET_KEY' do
expected_creds = random_creds.merge(session_token: nil)
env['AWS_ACCESS_KEY_ID'] = expected_creds[:access_key_id]
env['AWS_SECRET_KEY'] = expected_creds[:secret_access_key]
expected_creds = random_creds.merge(session_token: nil, credential_scope: nil)
ENV['AWS_ACCESS_KEY_ID'] = expected_creds[:access_key_id]
ENV['AWS_SECRET_KEY'] = expected_creds[:secret_access_key]
validate_credentials(expected_creds)
end

Expand Down
11 changes: 10 additions & 1 deletion gems/aws-sdk-core/spec/aws/credentials_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Aws
expect(Credentials.new('akid', 'secret').secret_access_key).to eq('secret')
end

it 'provides access to the session tokey' do
it 'provides access to the session token' do
creds = Credentials.new('akid', 'secret', 'token')
expect(creds.session_token).to eq('token')
end
Expand All @@ -22,6 +22,15 @@ module Aws
expect(Credentials.new('akid', 'secret').session_token).to be(nil)
end

it 'provides access to the credential scope' do
creds = Credentials.new('akid', 'secret', nil, 'scope')
expect(creds.credential_scope).to eq('scope')
end

it 'defaults the credential scope to nil' do
expect(Credentials.new('akid', 'secret').credential_scope).to be(nil)
end

describe '#set?' do

it 'returns true when the key and secret are both non nil values' do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ region = us-east-1
aws_access_key_id = ACCESS_KEY_SHARED
aws_secret_access_key = SECRET_KEY_SHARED
aws_session_token = TOKEN_SHARED
aws_credential_scope = SCOPE_SHARED

[profile assumerole_prof]
role_arn = arn:aws:iam:123456789012:role/foo
Expand Down

0 comments on commit 138718e

Please sign in to comment.