diff --git a/gems/aws-sdk-core/CHANGELOG.md b/gems/aws-sdk-core/CHANGELOG.md index a94da1d2da6..a2c89b13156 100644 --- a/gems/aws-sdk-core/CHANGELOG.md +++ b/gems/aws-sdk-core/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Feature - Support an auth scheme signing preference list using `ENV['AWS_AUTH_SCHEME_PREFERENCE']` or `auth_scheme_preference` in shared configuration. + 3.226.2 (2025-07-01) ------------------ diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/endpoints.rb b/gems/aws-sdk-core/lib/aws-sdk-core/endpoints.rb index 60d93cb7d5b..d1467198508 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/endpoints.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/endpoints.rb @@ -19,19 +19,28 @@ module Aws # @api private module Endpoints - SUPPORTED_AUTH_TRAITS = %w[ - aws.auth#sigv4 - aws.auth#sigv4a - smithy.api#httpBearerAuth - smithy.api#noAuth - ].freeze + # Maps config auth scheme preferences to endpoint auth scheme names. + ENDPOINT_AUTH_PREFERENCE_MAP = { + 'sigv4' => %w[sigv4 sigv4-s3express], + 'sigv4a' => ['sigv4a'], + 'httpBearerAuth' => ['bearer'], + 'noAuth' => ['none'] + }.freeze + SUPPORTED_ENDPOINT_AUTH = ENDPOINT_AUTH_PREFERENCE_MAP.values.flatten.freeze + + # Maps configured auth scheme preferences to modeled auth traits. + MODELED_AUTH_PREFERENCE_MAP = { + 'sigv4' => 'aws.auth#sigv4', + 'sigv4a' => 'aws.auth#sigv4a', + 'httpBearerAuth' => 'smithy.api#httpBearerAuth', + 'noAuth' => 'smithy.api#noAuth' + }.freeze + SUPPORTED_MODELED_AUTH = MODELED_AUTH_PREFERENCE_MAP.values.freeze class << self def resolve_auth_scheme(context, endpoint) if endpoint && (auth_schemes = endpoint.properties['authSchemes']) - auth_scheme = auth_schemes.find do |scheme| - Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES.include?(scheme['name']) - end + auth_scheme = endpoint_auth_scheme_preference(auth_schemes, context.config.auth_scheme_preference) raise 'No supported auth scheme for this endpoint.' unless auth_scheme merge_signing_defaults(auth_scheme, context.config) @@ -42,6 +51,16 @@ def resolve_auth_scheme(context, endpoint) private + def endpoint_auth_scheme_preference(auth_schemes, preferred_auth) + ordered_auth = preferred_auth.each_with_object([]) do |pref, list| + next unless ENDPOINT_AUTH_PREFERENCE_MAP.key?(pref) + + ENDPOINT_AUTH_PREFERENCE_MAP[pref].each { |name| list << { 'name' => name } } + end + ordered_auth += auth_schemes + ordered_auth.find { |auth| SUPPORTED_ENDPOINT_AUTH.include?(auth['name']) } + end + def merge_signing_defaults(auth_scheme, config) if %w[sigv4 sigv4a sigv4-s3express].include?(auth_scheme['name']) auth_scheme['signingName'] ||= sigv4_name(config) @@ -64,13 +83,12 @@ def merge_signing_defaults(auth_scheme, config) end def sigv4_name(config) - config.api.metadata['signingName'] || - config.api.metadata['endpointPrefix'] + config.api.metadata['signingName'] || config.api.metadata['endpointPrefix'] end def default_auth_scheme(context) - if (auth_list = default_api_auth(context)) - auth = auth_list.find { |a| SUPPORTED_AUTH_TRAITS.include?(a) } + if (modeled_auth = default_api_auth(context)) + auth = modeled_auth_scheme_preference(modeled_auth, context.config.auth_scheme_preference) case auth when 'aws.auth#sigv4', 'aws.auth#sigv4a' auth_scheme = { 'name' => auth.split('#').last } @@ -93,6 +111,12 @@ def default_auth_scheme(context) end end + def modeled_auth_scheme_preference(modeled_auth, preferred_auth) + ordered_auth = preferred_auth.map { |pref| MODELED_AUTH_PREFERENCE_MAP[pref] }.compact + ordered_auth += modeled_auth + ordered_auth.find { |auth| SUPPORTED_MODELED_AUTH.include?(auth) } + end + def default_api_auth(context) context.config.api.operation(context.operation_name)['auth'] || context.config.api.metadata['auth'] diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/credentials_configuration.rb b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/credentials_configuration.rb index 39904a631ab..3e47c7d245f 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/credentials_configuration.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/credentials_configuration.rb @@ -17,61 +17,66 @@ class CredentialsConfiguration < Seahorse::Client::Plugin option(:profile, doc_default: 'default', doc_type: String, - docstring: <<-DOCS) -Used when loading credentials from the shared credentials file -at HOME/.aws/credentials. When not specified, 'default' is used. + docstring: <<~DOCS) + Used when loading credentials from the shared credentials file at `HOME/.aws/credentials`. + When not specified, 'default' is used. DOCS option(:credentials, required: true, doc_type: 'Aws::CredentialProvider', rbs_type: 'untyped', - docstring: <<-DOCS -Your AWS credentials. This can be an instance of any one of the -following classes: - -* `Aws::Credentials` - Used for configuring static, non-refreshing - credentials. - -* `Aws::SharedCredentials` - Used for loading static credentials from a - shared file, such as `~/.aws/config`. - -* `Aws::AssumeRoleCredentials` - Used when you need to assume a role. - -* `Aws::AssumeRoleWebIdentityCredentials` - Used when you need to - assume a role after providing credentials via the web. - -* `Aws::SSOCredentials` - Used for loading credentials from AWS SSO using an - access token generated from `aws login`. - -* `Aws::ProcessCredentials` - Used for loading credentials from a - process that outputs to stdout. - -* `Aws::InstanceProfileCredentials` - Used for loading credentials - from an EC2 IMDS on an EC2 instance. - -* `Aws::ECSCredentials` - Used for loading credentials from - instances running in ECS. - -* `Aws::CognitoIdentityCredentials` - Used for loading credentials - from the Cognito Identity service. - -When `:credentials` are not configured directly, the following -locations will be searched for credentials: - -* `Aws.config[:credentials]` -* The `:access_key_id`, `:secret_access_key`, `:session_token`, and - `:account_id` options. -* ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'], - ENV['AWS_SESSION_TOKEN'], and ENV['AWS_ACCOUNT_ID'] -* `~/.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::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. + docstring: <<~DOCS + Your AWS credentials used for authentication. This can be an instance of any one of the + following classes: + + * `Aws::Credentials` - Used for configuring static, non-refreshing + credentials. + + * `Aws::SharedCredentials` - Used for loading static credentials from a + shared file, such as `~/.aws/config`. + + * `Aws::AssumeRoleCredentials` - Used when you need to assume a role. + + * `Aws::AssumeRoleWebIdentityCredentials` - Used when you need to + assume a role after providing credentials via the web. + + * `Aws::SSOCredentials` - Used for loading credentials from AWS SSO using an + access token generated from `aws login`. + + * `Aws::ProcessCredentials` - Used for loading credentials from a + process that outputs to stdout. + + * `Aws::InstanceProfileCredentials` - Used for loading credentials + from an EC2 IMDS on an EC2 instance. + + * `Aws::ECSCredentials` - Used for loading credentials from + instances running in ECS. + + * `Aws::CognitoIdentityCredentials` - Used for loading credentials + from the Cognito Identity service. + + When `:credentials` are not configured directly, the following + locations will be searched for credentials: + + * `Aws.config[:credentials]` + + * The `:access_key_id`, `:secret_access_key`, `:session_token`, and + `:account_id` options. + + * `ENV['AWS_ACCESS_KEY_ID']`, `ENV['AWS_SECRET_ACCESS_KEY']`, + `ENV['AWS_SESSION_TOKEN']`, and `ENV['AWS_ACCOUNT_ID']`. + + * `~/.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::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`. DOCS ) do |config| CredentialProviderChain.new(config).resolve @@ -82,22 +87,21 @@ class CredentialsConfiguration < Seahorse::Client::Plugin option(:instance_profile_credentials_timeout, 1) option(:token_provider, - required: false, - doc_type: 'Aws::TokenProvider', - rbs_type: 'untyped', - docstring: <<-DOCS -A Bearer Token Provider. This can be an instance of any one of the -following classes: - -* `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing - tokens. - -* `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an - access token generated from `aws login`. - -When `:token_provider` is not configured directly, the `Aws::TokenProviderChain` -will be used to search for tokens configured for your profile in shared configuration files. - DOCS + doc_type: 'Aws::TokenProvider', + rbs_type: 'untyped', + docstring: <<~DOCS + Your Bearer token used for authentication. This can be an instance of any one of the + following classes: + + * `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing + tokens. + + * `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an + access token generated from `aws login`. + + When `:token_provider` is not configured directly, the `Aws::TokenProviderChain` + will be used to search for tokens configured for your profile in shared configuration files. + DOCS ) do |config| if config.stub_responses StaticTokenProvider.new('token') @@ -106,6 +110,21 @@ class CredentialsConfiguration < Seahorse::Client::Plugin end end + option(:auth_scheme_preference, + doc_type: 'Array', + rbs_type: 'Array[String]', + docstring: <<~DOCS + A list of preferred authentication schemes to use when making a request. Supported values are: + `sigv4`, `sigv4a`, `httpBearerAuth`, and `noAuth`. When set using `ENV['AWS_AUTH_SCHEME_PREFERENCE']` or in + shared config as `auth_scheme_preference`, the value should be a comma-separated list. + DOCS + ) do |config| + value = + ENV['AWS_AUTH_SCHEME_PREFERENCE'] || + Aws.shared_config.auth_scheme_preference(profile: config.profile) || + '' + value.gsub(' ', '').gsub("\t", '').split(',') + end end end end diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/sign.rb b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/sign.rb index eba2235498f..68d5e969fa8 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/plugins/sign.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/plugins/sign.rb @@ -13,9 +13,6 @@ class Sign < Seahorse::Client::Plugin option(:sigv4_region) option(:unsigned_operations, default: []) - supported_auth_types = %w[sigv4 bearer sigv4-s3express sigv4a none] - SUPPORTED_AUTH_TYPES = supported_auth_types.freeze - def add_handlers(handlers, cfg) operations = cfg.api.operation_names - cfg.unsigned_operations handlers.add(Handler, step: :sign, operations: operations) 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 edd5d0266d2..e33d5d86e33 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 @@ -203,6 +203,7 @@ def self.config_reader(*attrs) config_reader( :region, :account_id_endpoint_mode, + :auth_scheme_preference, :sigv4a_signing_region_set, :ca_bundle, :credential_process, diff --git a/gems/aws-sdk-core/spec/auth_helper.rb b/gems/aws-sdk-core/spec/auth_helper.rb new file mode 100644 index 00000000000..d14c3453cd3 --- /dev/null +++ b/gems/aws-sdk-core/spec/auth_helper.rb @@ -0,0 +1,27 @@ +module AuthHelper + # Expect the signer to be called with the given auth scheme. + def expect_auth(expected_auth_scheme, region: nil, credentials: nil) + expect(Aws::Plugins::Sign).to receive(:signer_for).and_wrap_original do |m, *args| + actual_auth_scheme = args[0] + _config = args[1] + _sigv4_region_override = args[2] + _sigv4_credentials_override = args[3] + + expect(actual_auth_scheme).to include(expected_auth_scheme) + signer = m.call(*args) + case signer + when Aws::Plugins::Sign::SignatureV4 + sigv4_signer = signer.signer + case expected_auth_scheme['name'] + when 'sigv4' + region = region || expected_auth_scheme['signingRegion'] + when 'sigv4a' + region = region || expected_auth_scheme['signingRegionSet']&.join(',') + end + expect(sigv4_signer.region).to eq(region) if region + expect(sigv4_signer.credentials_provider).to eq(credentials) if credentials + end + signer + end + end +end diff --git a/gems/aws-sdk-core/spec/aws/endpoints_spec.rb b/gems/aws-sdk-core/spec/aws/endpoints_spec.rb index 78e84edebe9..705b43d8cc9 100644 --- a/gems/aws-sdk-core/spec/aws/endpoints_spec.rb +++ b/gems/aws-sdk-core/spec/aws/endpoints_spec.rb @@ -47,9 +47,8 @@ module Aws ) end - let(:client) do - endpoints_service.const_get(:Client).new(stub_responses: true) - end + let(:client_options) { { stub_responses: true } } + let(:client) { endpoints_service.const_get(:Client).new(client_options) } let(:endpoint) do Aws::Endpoints::Endpoint.new( @@ -114,13 +113,6 @@ module Aws end context 'sigv4a defaults' do - before do - stub_const( - 'Aws::Endpoints::SUPPORTED_AUTH_TRAITS', - Aws::Endpoints::SUPPORTED_AUTH_TRAITS + ['aws.auth#sigv4a'] - ) - end - let(:auth) { ['aws.auth#sigv4a'] } it 'signs with sigv4' do @@ -180,8 +172,8 @@ module Aws context 'unsupported' do before do stub_const( - 'Aws::Endpoints::SUPPORTED_AUTH_TRAITS', - Aws::Endpoints::SUPPORTED_AUTH_TRAITS - ['aws.auth#sigv4a'] + 'Aws::Endpoints::SUPPORTED_MODELED_AUTH', + Aws::Endpoints::SUPPORTED_MODELED_AUTH - ['aws.auth#sigv4a'] ) end @@ -206,8 +198,8 @@ module Aws context 'resolution order' do before do stub_const( - 'Aws::Endpoints::SUPPORTED_AUTH_TRAITS', - Aws::Endpoints::SUPPORTED_AUTH_TRAITS - ['aws.auth#sigv4a'] + 'Aws::Endpoints::SUPPORTED_MODELED_AUTH', + Aws::Endpoints::SUPPORTED_MODELED_AUTH - ['aws.auth#sigv4a'] ) end @@ -218,6 +210,52 @@ module Aws client.operation end end + + context 'auth scheme preference config' do + let(:auth) { %w[aws.auth#sigv4 aws.auth#sigv4a smithy.api#httpBearerAuth smithy.api#noAuth] } + + it 'selects the first supported auth scheme' do + client.config.auth_scheme_preference = ['sigv4a', 'httpBearerAuth', 'noAuth'] + expect_auth({ 'name' => 'sigv4a' }) + client.operation + end + + it 'can prefer sigv4' do + client.config.auth_scheme_preference = ['sigv4'] + expect_auth({ 'name' => 'sigv4' }) + client.operation + end + + it 'can prefer sigv4a' do + client.config.auth_scheme_preference = ['sigv4a'] + expect_auth({ 'name' => 'sigv4a' }) + client.operation + end + + it 'can prefer httpBearerAuth' do + client.config.auth_scheme_preference = ['httpBearerAuth'] + expect_auth({ 'name' => 'bearer' }) + client.operation + end + + it 'can prefer noAuth' do + client.config.auth_scheme_preference = ['noAuth'] + expect_auth({ 'name' => 'none' }) + client.operation + end + + it 'ignores unsupported auth schemes' do + client.config.auth_scheme_preference = ['unknown', 'sigv4'] + expect_auth({ 'name' => 'sigv4' }) + client.operation + end + + it 'falls back to model when auth scheme preference has unknowns' do + client.config.auth_scheme_preference = ['unknown'] + expect_auth({ 'name' => 'sigv4' }) + client.operation + end + end end context 'legacy signatureVersion and authtype' do @@ -360,6 +398,59 @@ module Aws client.operation end end + + context 'auth scheme preference config' do + let(:auth_schemes) do + [ + { 'name' => 'sigv4' }, + { 'name' => 'sigv4a' }, + { 'name' => 'bearer' }, + { 'name' => 'none' } + ] + end + + it 'selects the first supported auth scheme' do + client.config.auth_scheme_preference = ['sigv4a', 'httpBearerAuth', 'noAuth'] + expect_auth({ 'name' => 'sigv4a' }) + client.operation + end + + it 'can prefer sigv4' do + client.config.auth_scheme_preference = ['sigv4'] + expect_auth({ 'name' => 'sigv4' }) + client.operation + end + + it 'can prefer sigv4a' do + client.config.auth_scheme_preference = ['sigv4a'] + expect_auth({ 'name' => 'sigv4a' }) + client.operation + end + + it 'can prefer httpBearerAuth' do + client.config.auth_scheme_preference = ['httpBearerAuth'] + expect_auth({ 'name' => 'bearer' }) + client.operation + end + + it 'can prefer noAuth' do + client.config.auth_scheme_preference = ['noAuth'] + expect_auth({ 'name' => 'none' }) + client.operation + end + + it 'ignores unsupported auth schemes' do + client.config.auth_scheme_preference = ['unknown', 'sigv4'] + expect_auth({ 'name' => 'sigv4' }) + client.operation + end + + it 'falls back to model when auth scheme preference has unknowns' do + client.config.auth_scheme_preference = ['unknown'] + expect_auth({ 'name' => 'sigv4' }) + client.operation + end + end end end 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 f3825295b34..6cf1a1bb1cd 100644 --- a/gems/aws-sdk-core/spec/aws/shared_config_spec.rb +++ b/gems/aws-sdk-core/spec/aws/shared_config_spec.rb @@ -157,6 +157,17 @@ module Aws end end + context 'auth_scheme_preference selection' do + it 'can resolve auth_scheme_preference from config file' do + config = SharedConfig.new( + config_path: mock_config_file, + config_enabled: true, + profile_name: 'auth_scheme_preference' + ) + expect(config.auth_scheme_preference).to eq('httpBearerAuth,sigv4') + end + end + context 'ca_bundle selection' do it 'can resolve ca_bundle from config file' do config = SharedConfig.new( diff --git a/gems/aws-sdk-core/spec/fixtures/credentials/mock_shared_config b/gems/aws-sdk-core/spec/fixtures/credentials/mock_shared_config index 54ece93b05e..29e1660747f 100644 --- a/gems/aws-sdk-core/spec/fixtures/credentials/mock_shared_config +++ b/gems/aws-sdk-core/spec/fixtures/credentials/mock_shared_config @@ -115,6 +115,9 @@ aws_session_token = TOKEN_ARPC [profile account_id_endpoint_mode] account_id_endpoint_mode = disabled +[profile auth_scheme_preference] +auth_scheme_preference = httpBearerAuth,sigv4 + [profile ca_bundle] ca_bundle = /path/to/bundle.crt diff --git a/gems/aws-sdk-core/spec/shared_spec_helper.rb b/gems/aws-sdk-core/spec/shared_spec_helper.rb index 70dd39ab60c..dac6db3d896 100644 --- a/gems/aws-sdk-core/spec/shared_spec_helper.rb +++ b/gems/aws-sdk-core/spec/shared_spec_helper.rb @@ -8,7 +8,7 @@ require 'webmock/rspec' -require_relative './sigv4_helper' +require_relative './auth_helper' # Prevent the SDK unit tests from loading actual credentials while under test. # By default the SDK attempts to load credentials from: @@ -19,7 +19,7 @@ # RSpec.configure do |config| # Module to help check service signing - config.include Sigv4Helper + config.include AuthHelper config.before(:each) do # Clear the current ENV to avoid loading credentials. diff --git a/gems/aws-sdk-core/spec/sigv4_helper.rb b/gems/aws-sdk-core/spec/sigv4_helper.rb deleted file mode 100644 index c909eae3bc0..00000000000 --- a/gems/aws-sdk-core/spec/sigv4_helper.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Sigv4Helper - # perhaps belongs in an AuthHelper but we mainly check Sigv4 these days - def expect_auth(auth_scheme, region: nil, credentials: nil) - if auth_scheme['name'] == 'sigv4a' - stub_const( - 'Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES', - Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES + ['sigv4a'] - ) - end - expect(Aws::Plugins::Sign).to receive(:signer_for).and_wrap_original do |m, *args| - expect(args.first).to include(auth_scheme) - expect(args[2]).to eq(region) if region - expect(args[3]).to eq(credentials) if credentials - - if auth_scheme['name'] == 'sigv4a' - mock_signature = Aws::Sigv4::Signature.new(headers: {}) - signer = double('sigv4a_signer', sign_request: mock_signature) - region = region || args.first['signingRegionSet'].join(',') - - expect(Aws::Sigv4::Signer).to receive(:new) - .with(hash_including(signing_algorithm: :sigv4a, region: region)) - .and_return(signer) - expect(signer).to receive(:credentials_provider).and_return(credentials) - end - - m.call(*args) - end - end -end diff --git a/gems/aws-sdk-s3/spec/presigner_spec.rb b/gems/aws-sdk-s3/spec/presigner_spec.rb index be219e0c8e2..d3b937e1228 100644 --- a/gems/aws-sdk-s3/spec/presigner_spec.rb +++ b/gems/aws-sdk-s3/spec/presigner_spec.rb @@ -418,47 +418,19 @@ def initialize(expiration_time) end context 'MRAP ARNs' do - let(:signer) { double('sigv4a_signer') } let(:arn) { 'arn:aws:s3::123456789012:accesspoint:mfzwi23gnjvgw.mrap' } it 'creates a presigned url with sigv4a' do - stub_const( - 'Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES', - Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES + ['sigv4a'] - ) - - expect(Aws::Sigv4::Signer) - .to receive(:new) - .with(hash_including( - service: 's3', - region: '*', - signing_algorithm: :sigv4a - )) - .and_return(signer) - - expect(signer) - .to receive(:presign_url) - .with(hash_including( - url: URI.parse('https://mfzwi23gnjvgw.mrap.accesspoint.s3-global.amazonaws.com/obj') - )) - - subject.presigned_url(:get_object, bucket: arn, key: 'obj') - end - - context 's3_disable_multiregion_access_points is true' do - let(:client) do - Aws::S3::Client.new( - stub_responses: true, - s3_disable_multiregion_access_points: true - ) - end + url = subject.presigned_url(:get_object, bucket: arn, key: 'obj') + expect(url).to include('https://mfzwi23gnjvgw.mrap.accesspoint.s3-global.amazonaws.com/obj') + expect(url).to include('X-Amz-Region-Set=%2A') + end - it 'raises an ArgumentError' do - arn = 'arn:aws:s3::123456789012:accesspoint:mfzwi23gnjvgw.mrap' - expect do - subject.presigned_url(:get_object, bucket: arn, key: 'obj') - end.to raise_error(ArgumentError) - end + it 'raises an ArgumentError when MRAP is disabled' do + client.config.s3_disable_multiregion_access_points = true + expect do + subject.presigned_url(:get_object, bucket: arn, key: 'obj') + end.to raise_error(ArgumentError) end end