aws-sdk-core 3.104.3 → 3.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7357ce5a3cd95241ed7e567a86b6f3e9edbfd324124b0cab96116b20f41197a6
4
- data.tar.gz: 8b255e4d03b48ff6cdf80167e3a115085b09aac23323f891daf305c93d3f7fb6
3
+ metadata.gz: 9be12fd3781d8257feb49c005af422cc726da47592e55368ebc3ce4d8032e21b
4
+ data.tar.gz: 28b66904da66dc5ab09acfb20fd37dd250cc6e83c54d6735b6b3e8b15ea22f72
5
5
  SHA512:
6
- metadata.gz: 57822a88212cd847c75ed5d0bd958962a3559ec92330e46eea7ab2b7a13fcf2d8fbeea3e0dc87f4beffa6ecdf5f2e17b15985781d720caf5eff803decf53284c
7
- data.tar.gz: 674a1b2b308b44f32ea037878292c9ea621c8734559acdcfde7b7008bb48bd1be183c4c29899cbed0d9355555e2801fdaffd5d52bf3a18c7d32c83c7f6785f72
6
+ metadata.gz: fb1a6fb1b39908e6627b4fae6331fd3574d34e10c413ddc55927460af5a7d8ac11abe1b7ecb7313c6faa141ddaf81c9173b76d33588cefc9e8c563573dc96682
7
+ data.tar.gz: ca41b1a8705dd842e72d147e4c8ba0c1aa167942f5db16ca456922604cc6a6582a498329e0178fc1b8880189587d4aa204f460c0fc7edc7c8930be2d97c650d2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.104.3
1
+ 3.109.0
@@ -18,9 +18,9 @@ require_relative 'aws-sdk-core/ecs_credentials'
18
18
  require_relative 'aws-sdk-core/instance_profile_credentials'
19
19
  require_relative 'aws-sdk-core/shared_credentials'
20
20
  require_relative 'aws-sdk-core/process_credentials'
21
+ require_relative 'aws-sdk-core/sso_credentials'
21
22
 
22
23
  # client modules
23
-
24
24
  require_relative 'aws-sdk-core/client_stubs'
25
25
  require_relative 'aws-sdk-core/async_client_stubs'
26
26
  require_relative 'aws-sdk-core/eager_loader'
@@ -86,10 +86,12 @@ require_relative 'aws-sdk-core/client_side_monitoring/publisher'
86
86
  require_relative 'aws-sdk-core/arn'
87
87
  require_relative 'aws-sdk-core/arn_parser'
88
88
 
89
- # aws-sdk-sts is vendored to support Aws::AssumeRoleCredentials
90
-
89
+ # aws-sdk-sts is included to support Aws::AssumeRoleCredentials
91
90
  require 'aws-sdk-sts'
92
91
 
92
+ # aws-sdk-sso is included to support Aws::SSOCredentials
93
+ require 'aws-sdk-sso'
94
+
93
95
  module Aws
94
96
 
95
97
  CORE_GEM_VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
@@ -75,5 +75,18 @@ module Aws
75
75
  def to_s
76
76
  "arn:#{partition}:#{service}:#{region}:#{account_id}:#{resource}"
77
77
  end
78
+
79
+ # Return the ARN as a hash
80
+ #
81
+ # @return [Hash]
82
+ def to_h
83
+ {
84
+ partition: @partition,
85
+ service: @service,
86
+ region: @region,
87
+ account_id: @account_id,
88
+ resource: @resource
89
+ }
90
+ end
78
91
  end
79
92
  end
@@ -22,11 +22,13 @@ module Aws
22
22
  [
23
23
  [:static_credentials, {}],
24
24
  [:static_profile_assume_role_web_identity_credentials, {}],
25
+ [:static_profile_sso_credentials, {}],
25
26
  [:static_profile_assume_role_credentials, {}],
26
27
  [:static_profile_credentials, {}],
27
28
  [:static_profile_process_credentials, {}],
28
29
  [:env_credentials, {}],
29
30
  [:assume_role_web_identity_credentials, {}],
31
+ [:sso_credentials, {}],
30
32
  [:assume_role_credentials, {}],
31
33
  [:shared_credentials, {}],
32
34
  [:process_credentials, {}],
@@ -57,6 +59,14 @@ module Aws
57
59
  end
58
60
  end
59
61
 
62
+ def static_profile_sso_credentials(options)
63
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
64
+ Aws.shared_config.sso_credentials_from_config(
65
+ profile: options[:config].profile
66
+ )
67
+ end
68
+ end
69
+
60
70
  def static_profile_assume_role_credentials(options)
61
71
  if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
62
72
  assume_role_with_profile(options, options[:config].profile)
@@ -115,6 +125,15 @@ module Aws
115
125
  nil
116
126
  end
117
127
 
128
+ def sso_credentials(options)
129
+ profile_name = determine_profile_name(options)
130
+ if Aws.shared_config.config_enabled?
131
+ Aws.shared_config.sso_credentials_from_config(profile: profile_name)
132
+ end
133
+ rescue Errors::NoSuchProfileError
134
+ nil
135
+ end
136
+
118
137
  def assume_role_credentials(options)
119
138
  if Aws.shared_config.config_enabled?
120
139
  assume_role_with_profile(options, determine_profile_name(options))
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
3
  require 'time'
5
4
  require 'net/http'
6
5
 
@@ -81,8 +80,8 @@ module Aws
81
80
  # service is responding but is returning invalid JSON documents
82
81
  # in response to the GET profile credentials call.
83
82
  begin
84
- retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
85
- c = JSON.parse(get_credentials.to_s)
83
+ retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
84
+ c = Aws::Json.load(get_credentials.to_s)
86
85
  @credentials = Credentials.new(
87
86
  c['AccessKeyId'],
88
87
  c['SecretAccessKey'],
@@ -90,7 +89,7 @@ module Aws
90
89
  )
91
90
  @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
92
91
  end
93
- rescue JSON::ParserError
92
+ rescue Aws::Json::ParseError
94
93
  raise Aws::Errors::MetadataParserError.new
95
94
  end
96
95
  end
@@ -207,6 +207,9 @@ module Aws
207
207
  # payload with either invalid version number or malformed contents
208
208
  class InvalidProcessCredentialsPayload < RuntimeError; end
209
209
 
210
+ # Raised when SSO Credentials are invalid
211
+ class InvalidSSOCredentials < RuntimeError; end
212
+
210
213
  # Raised when a client is constructed and region is not specified.
211
214
  class MissingRegionError < ArgumentError
212
215
  def initialize(*args)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
3
  require 'time'
5
4
  require 'net/http'
6
5
 
@@ -92,8 +91,8 @@ module Aws
92
91
  # service is responding but is returning invalid JSON documents
93
92
  # in response to the GET profile credentials call.
94
93
  begin
95
- retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
96
- c = JSON.parse(get_credentials.to_s)
94
+ retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
95
+ c = Aws::Json.load(get_credentials.to_s)
97
96
  @credentials = Credentials.new(
98
97
  c['AccessKeyId'],
99
98
  c['SecretAccessKey'],
@@ -101,7 +100,7 @@ module Aws
101
100
  )
102
101
  @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
103
102
  end
104
- rescue JSON::ParserError
103
+ rescue Aws::Json::ParseError
105
104
  raise Aws::Errors::MetadataParserError
106
105
  end
107
106
  end
@@ -39,7 +39,7 @@ module Aws
39
39
  require 'oj'
40
40
  [
41
41
  Oj,
42
- [{ mode: :compat, symbol_keys: false }],
42
+ [{ mode: :compat, symbol_keys: false, empty_string: false }],
43
43
  [{ mode: :compat }],
44
44
  oj_parse_error
45
45
  ]
@@ -30,13 +30,28 @@ following classes:
30
30
  * `Aws::Credentials` - Used for configuring static, non-refreshing
31
31
  credentials.
32
32
 
33
+ * `Aws::SharedCredentials` - Used for loading static credentials from a
34
+ shared file, such as `~/.aws/config`.
35
+
36
+ * `Aws::AssumeRoleCredentials` - Used when you need to assume a role.
37
+
38
+ * `Aws::AssumeRoleWebIdentityCredentials` - Used when you need to
39
+ assume a role after providing credentials via the web.
40
+
41
+ * `Aws::SSOCredentials` - Used for loading credentials from AWS SSO using an
42
+ access token generated from `aws login`.
43
+
44
+ * `Aws::ProcessCredentials` - Used for loading credentials from a
45
+ process that outputs to stdout.
46
+
33
47
  * `Aws::InstanceProfileCredentials` - Used for loading credentials
34
48
  from an EC2 IMDS on an EC2 instance.
35
49
 
36
- * `Aws::SharedCredentials` - Used for loading credentials from a
37
- shared file, such as `~/.aws/config`.
50
+ * `Aws::ECSCredentials` - Used for loading credentials from
51
+ instances running in ECS.
38
52
 
39
- * `Aws::AssumeRoleCredentials` - Used when you need to assume a role.
53
+ * `Aws::CognitoIdentityCredentials` - Used for loading credentials
54
+ from the Cognito Identity service.
40
55
 
41
56
  When `:credentials` are not configured directly, the following
42
57
  locations will be searched for credentials:
@@ -46,10 +61,10 @@ locations will be searched for credentials:
46
61
  * ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']
47
62
  * `~/.aws/credentials`
48
63
  * `~/.aws/config`
49
- * EC2 IMDS instance profile - When used by default, the timeouts are
50
- very aggressive. Construct and pass an instance of
51
- `Aws::InstanceProfileCredentails` to enable retries and extended
52
- timeouts.
64
+ * EC2/ECS IMDS instance profile - When used by default, the timeouts
65
+ are very aggressive. Construct and pass an instance of
66
+ `Aws::InstanceProfileCredentails` or `Aws::ECSCredentials` to
67
+ enable retries and extended timeouts.
53
68
  DOCS
54
69
  ) do |config|
55
70
  CredentialProviderChain.new(config).resolve
@@ -15,17 +15,18 @@ to default service endpoint when available.
15
15
  )
16
16
 
17
17
  def add_handlers(handlers, config)
18
- if config.regional_endpoint && !config.disable_host_prefix_injection
19
- handlers.add(Handler, priority: 90)
20
- end
18
+ handlers.add(Handler, priority: 10)
21
19
  end
22
20
 
23
21
  class Handler < Seahorse::Client::Handler
24
22
 
25
23
  def call(context)
26
- endpoint_trait = context.operation.endpoint_pattern
27
- if endpoint_trait && !endpoint_trait.empty?
28
- _apply_endpoint_trait(context, endpoint_trait)
24
+ if context.config.regional_endpoint &&
25
+ !context.config.disable_host_prefix_injection
26
+ endpoint_trait = context.operation.endpoint_pattern
27
+ if endpoint_trait && !endpoint_trait.empty?
28
+ _apply_endpoint_trait(context, endpoint_trait)
29
+ end
29
30
  end
30
31
  @handler.call(context)
31
32
  end
@@ -38,7 +38,7 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
38
38
  end
39
39
 
40
40
  # check region is a valid RFC host label
41
- unless cfg.region =~ /^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)$/
41
+ unless Seahorse::Util.host_label?(cfg.region)
42
42
  raise Errors::InvalidRegionError
43
43
  end
44
44
 
@@ -42,8 +42,8 @@ module Aws
42
42
 
43
43
  if process_status.success?
44
44
  begin
45
- creds_json = JSON.parse(raw_out)
46
- rescue JSON::ParserError
45
+ creds_json = Aws::Json.load(raw_out)
46
+ rescue Aws::Json::ParseError
47
47
  raise Errors::InvalidProcessCredentialsPayload.new("Invalid JSON response")
48
48
  end
49
49
  payload_version = creds_json['Version']
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'time'
4
4
  require 'base64'
5
- require 'json'
6
5
 
7
6
  module Aws
8
7
  module Rest
@@ -68,7 +67,7 @@ module Aws
68
67
  end
69
68
 
70
69
  def extract_json_trait(value)
71
- JSON.parse(Base64.decode64(value))
70
+ Aws::Json.load(Base64.decode64(value))
72
71
  end
73
72
 
74
73
  end
@@ -3,6 +3,8 @@
3
3
  module Aws
4
4
  # @api private
5
5
  class SharedConfig
6
+ SSO_PROFILE_KEYS = %w[sso_start_url sso_region sso_account_id sso_role_name].freeze
7
+
6
8
  # @return [String]
7
9
  attr_reader :credentials_path
8
10
 
@@ -135,6 +137,18 @@ module Aws
135
137
  end
136
138
  end
137
139
 
140
+ # Attempts to load from shared config or shared credentials file.
141
+ # Will always attempt first to load from the shared credentials
142
+ # file, if present.
143
+ def sso_credentials_from_config(opts = {})
144
+ p = opts[:profile] || @profile_name
145
+ credentials = sso_credentials_from_profile(@parsed_credentials, p)
146
+ if @parsed_config
147
+ credentials ||= sso_credentials_from_profile(@parsed_config, p)
148
+ end
149
+ credentials
150
+ end
151
+
138
152
  # Add an accessor method (similar to attr_reader) to return a configuration value
139
153
  # Uses the get_config_value below to control where
140
154
  # values are loaded from
@@ -146,6 +160,7 @@ module Aws
146
160
 
147
161
  config_reader(
148
162
  :region,
163
+ :ca_bundle,
149
164
  :credential_process,
150
165
  :endpoint_discovery_enabled,
151
166
  :max_attempts,
@@ -237,6 +252,8 @@ module Aws
237
252
  provider.credentials if provider.credentials.set?
238
253
  elsif (provider = assume_role_process_credentials_from_config(profile))
239
254
  provider.credentials if provider.credentials.set?
255
+ elsif (provider = sso_credentials_from_config(profile: profile))
256
+ provider.credentials if provider.credentials.set?
240
257
  end
241
258
  end
242
259
 
@@ -273,6 +290,22 @@ module Aws
273
290
  end
274
291
  end
275
292
 
293
+ # If any of the sso_ profile values are present, attempt to construct
294
+ # SSOCredentials
295
+ def sso_credentials_from_profile(cfg, profile)
296
+ if @parsed_config &&
297
+ (prof_config = cfg[profile]) &&
298
+ !(prof_config.keys & SSO_PROFILE_KEYS).empty?
299
+
300
+ SSOCredentials.new(
301
+ sso_start_url: prof_config['sso_start_url'],
302
+ sso_region: prof_config['sso_region'],
303
+ sso_account_id: prof_config['sso_account_id'],
304
+ sso_role_name: prof_config['sso_role_name']
305
+ )
306
+ end
307
+ end
308
+
276
309
  def credentials_from_profile(prof_config)
277
310
  creds = Credentials.new(
278
311
  prof_config['aws_access_key_id'],
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # An auto-refreshing credential provider that works by assuming a
5
+ # role via {Aws::SSO::Client#get_role_credentials} using a cached access
6
+ # token. This class does NOT implement the SSO login token flow - tokens
7
+ # must generated and refreshed separately by running `aws login` with the
8
+ # correct profile.
9
+ #
10
+ # For more background on AWS SSO see the official
11
+ # [what is SSO](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html]
12
+ # page.
13
+ #
14
+ # ## Refreshing Credentials from SSO
15
+ #
16
+ # The `SSOCredentials` will auto-refresh the AWS credentials from SSO. In
17
+ # addition to AWS credentials expiring after a given amount of time, the
18
+ # access token generated and cached from `aws login` will also expire.
19
+ # Once this token expires, it will not be usable to refresh AWS credentials,
20
+ # and another token will be needed. The SDK does not manage refreshing of
21
+ # the token value, but this can be done by running `aws login` with the
22
+ # correct profile.
23
+ class SSOCredentials
24
+
25
+ include CredentialProvider
26
+ include RefreshingCredentials
27
+
28
+ SSO_REQUIRED_OPTS = [:sso_account_id, :sso_region, :sso_role_name, :sso_start_url].freeze
29
+
30
+ SSO_LOGIN_GUIDANCE = 'The SSO session associated with this profile has '\
31
+ 'expired or is otherwise invalid. To refresh this SSO session run '\
32
+ 'aws sso login with the corresponding profile.'.freeze
33
+
34
+ # @option options [required, String] :sso_account_id The AWS account ID
35
+ # that temporary AWS credentials will be resolved for
36
+ #
37
+ # @option options [required, String] :sso_region The AWS region where the
38
+ # SSO directory for the given sso_start_url is hosted.
39
+ #
40
+ # @option options [required, String] :sso_role_name The corresponding
41
+ # IAM role in the AWS account that temporary AWS credentials
42
+ # will be resolved for.
43
+ #
44
+ # @option options [required, String] :sso_start_url The start URL is
45
+ # provided by the SSO service via the console and is the URL used to
46
+ # login to the SSO directory. This is also sometimes referred to as
47
+ # the "User Portal URL"
48
+
49
+ # @option options [SSO::Client] :client Optional `SSO::Client`. If not
50
+ # provided, a client will be constructed.
51
+ def initialize(options = {})
52
+
53
+ missing_keys = SSO_REQUIRED_OPTS.select { |k| options[k].nil? }
54
+ unless missing_keys.empty?
55
+ raise ArgumentError, "Missing required keys: #{missing_keys}"
56
+ end
57
+
58
+ @sso_start_url = options.delete(:sso_start_url)
59
+ @sso_region = options.delete(:sso_region)
60
+ @sso_role_name = options.delete(:sso_role_name)
61
+ @sso_account_id = options.delete(:sso_account_id)
62
+
63
+ # validate we can read the token file
64
+ read_cached_token
65
+
66
+ options[:region] = @sso_region
67
+ options[:credentials] = nil
68
+ @client = options[:client] || SSO::Client.new(options)
69
+ super
70
+ end
71
+
72
+ # @return [STS::Client]
73
+ attr_reader :client
74
+
75
+ private
76
+
77
+ def read_cached_token
78
+ cached_token = Json.load(File.read(sso_cache_file))
79
+ # validation
80
+ unless cached_token['accessToken'] && cached_token['expiresAt']
81
+ raise ArgumentError, 'Missing required field(s)'
82
+ end
83
+ expires_at = DateTime.parse(cached_token['expiresAt'])
84
+ if expires_at < DateTime.now
85
+ raise ArgumentError, 'Cached SSO Token is expired.'
86
+ end
87
+ cached_token
88
+ rescue Aws::Json::ParseError, ArgumentError
89
+ raise Errors::InvalidSSOCredentials, SSO_LOGIN_GUIDANCE
90
+ end
91
+
92
+ def refresh
93
+ cached_token = read_cached_token
94
+ c = @client.get_role_credentials(
95
+ account_id: @sso_account_id,
96
+ role_name: @sso_role_name,
97
+ access_token: cached_token['accessToken']
98
+ ).role_credentials
99
+
100
+ @credentials = Credentials.new(
101
+ c.access_key_id,
102
+ c.secret_access_key,
103
+ c.session_token
104
+ )
105
+ @expiration = c.expiration
106
+ end
107
+
108
+ def sso_cache_file
109
+ start_url_sha1 = OpenSSL::Digest::SHA1.hexdigest(@sso_start_url.encode('utf-8'))
110
+ File.join(Dir.home, '.aws', 'sso', 'cache', "#{start_url_sha1}.json")
111
+ rescue ArgumentError
112
+ # Dir.home raises ArgumentError when ENV['home'] is not set
113
+ raise ArgumentError, "Unable to load sso_cache_file: ENV['HOME'] is not set."
114
+ end
115
+ end
116
+ end