Skip to content

Commit 6d48c72

Browse files
Add feature id tracking for credentials (#3216)
Add feature id tracking for credentials
1 parent 3a75419 commit 6d48c72

21 files changed

+624
-114
lines changed

gems/aws-sdk-core/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Unreleased Changes
22
------------------
33

4+
* Issue - Additional metrics collection for credentials in the User-Agent plugin.
5+
46
3.222.1 (2025-03-28)
57
------------------
68

gems/aws-sdk-core/lib/aws-sdk-core/assume_role_credentials.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def initialize(options = {})
5050
end
5151
@client = client_opts[:client] || STS::Client.new(client_opts)
5252
@async_refresh = true
53+
@metrics = ['CREDENTIALS_STS_ASSUME_ROLE']
5354
super
5455
end
5556

gems/aws-sdk-core/lib/aws-sdk-core/assume_role_web_identity_credentials.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def initialize(options = {})
6161
@assume_role_web_identity_params[:role_session_name] = _session_name
6262
end
6363
@client = client_opts[:client] || STS::Client.new(client_opts.merge(credentials: nil))
64+
@metrics = ['CREDENTIALS_STS_ASSUME_ROLE_WEB_ID']
6465
super
6566
end
6667

gems/aws-sdk-core/lib/aws-sdk-core/credential_provider.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ module CredentialProvider
99
# @return [Time]
1010
attr_reader :expiration
1111

12+
# @api private
13+
# Returns UserAgent metrics for credentials.
14+
attr_accessor :metrics
15+
1216
# @return [Boolean]
1317
def set?
1418
!!@credentials && @credentials.set?

gems/aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ def providers
4242

4343
def static_credentials(options)
4444
if options[:config]
45-
Credentials.new(
45+
creds = Credentials.new(
4646
options[:config].access_key_id,
4747
options[:config].secret_access_key,
4848
options[:config].session_token,
4949
account_id: options[:config].account_id
5050
)
51+
creds.metrics = ['CREDENTIALS_PROFILE']
52+
creds
5153
end
5254
end
5355

@@ -76,7 +78,9 @@ def static_profile_assume_role_credentials(options)
7678

7779
def static_profile_credentials(options)
7880
if options[:config] && options[:config].profile
79-
SharedCredentials.new(profile_name: options[:config].profile)
81+
creds = SharedCredentials.new(profile_name: options[:config].profile)
82+
creds.metrics = ['CREDENTIALS_PROFILE']
83+
creds
8084
end
8185
rescue Errors::NoSuchProfileError
8286
nil
@@ -85,7 +89,11 @@ def static_profile_credentials(options)
8589
def static_profile_process_credentials(options)
8690
if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
8791
process_provider = Aws.shared_config.credential_process(profile: options[:config].profile)
88-
ProcessCredentials.new([process_provider]) if process_provider
92+
if process_provider
93+
creds = ProcessCredentials.new([process_provider])
94+
creds.metrics << 'CREDENTIALS_PROFILE_PROCESS'
95+
creds
96+
end
8997
end
9098
rescue Errors::NoSuchProfileError
9199
nil
@@ -96,12 +104,14 @@ def env_credentials(_options)
96104
secret = %w[AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY]
97105
token = %w[AWS_SESSION_TOKEN AMAZON_SESSION_TOKEN]
98106
account_id = %w[AWS_ACCOUNT_ID]
99-
Credentials.new(
107+
creds = Credentials.new(
100108
envar(key),
101109
envar(secret),
102110
envar(token),
103111
account_id: envar(account_id)
104112
)
113+
creds.metrics = ['CREDENTIALS_ENV_VARS']
114+
creds
105115
end
106116

107117
def envar(keys)
@@ -117,7 +127,9 @@ def determine_profile_name(options)
117127

118128
def shared_credentials(options)
119129
profile_name = determine_profile_name(options)
120-
SharedCredentials.new(profile_name: profile_name)
130+
creds = SharedCredentials.new(profile_name: profile_name)
131+
creds.metrics = ['CREDENTIALS_PROFILE']
132+
creds
121133
rescue Errors::NoSuchProfileError
122134
nil
123135
end
@@ -126,7 +138,11 @@ def process_credentials(options)
126138
profile_name = determine_profile_name(options)
127139
if Aws.shared_config.config_enabled?
128140
process_provider = Aws.shared_config.credential_process(profile: profile_name)
129-
ProcessCredentials.new([process_provider]) if process_provider
141+
if process_provider
142+
creds = ProcessCredentials.new([process_provider])
143+
creds.metrics << 'CREDENTIALS_PROFILE_PROCESS'
144+
creds
145+
end
130146
end
131147
rescue Errors::NoSuchProfileError
132148
nil
@@ -156,7 +172,11 @@ def assume_role_web_identity_credentials(options)
156172
role_session_name: ENV['AWS_ROLE_SESSION_NAME']
157173
}
158174
cfg[:region] = region if region
159-
AssumeRoleWebIdentityCredentials.new(cfg)
175+
Aws::Plugins::UserAgent.metric('CREDENTIALS_ENV_VARS_STS_WEB_ID_TOKEN') do
176+
creds = AssumeRoleWebIdentityCredentials.new(cfg)
177+
creds.metrics << 'CREDENTIALS_ENV_VARS_STS_WEB_ID_TOKEN'
178+
creds
179+
end
160180
elsif Aws.shared_config.config_enabled?
161181
profile = options[:config].profile if options[:config]
162182
Aws.shared_config.assume_role_web_identity_credentials_from_config(

gems/aws-sdk-core/lib/aws-sdk-core/credentials.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def initialize(access_key_id, secret_access_key, session_token = nil,
1414
@secret_access_key = secret_access_key
1515
@session_token = session_token
1616
@account_id = kwargs[:account_id]
17+
@metrics = ['CREDENTIALS_CODE']
1718
end
1819

1920
# @return [String]
@@ -28,6 +29,11 @@ def initialize(access_key_id, secret_access_key, session_token = nil,
2829
# @return [String, nil]
2930
attr_reader :account_id
3031

32+
# @api private
33+
# Returns the credentials source. Used for tracking credentials
34+
# related UserAgent metrics.
35+
attr_accessor :metrics
36+
3137
# @return [Credentials]
3238
def credentials
3339
self

gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def initialize(options = {})
7777
@http_debug_output = options[:http_debug_output]
7878
@backoff = backoff(options[:backoff])
7979
@async_refresh = false
80+
@metrics = ['CREDENTIALS_HTTP']
8081
super
8182
end
8283

gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def initialize(options = {})
9090
@token = nil
9191
@no_refresh_until = nil
9292
@async_refresh = false
93+
@metrics = ['CREDENTIALS_IMDS']
9394
super
9495
end
9596

gems/aws-sdk-core/lib/aws-sdk-core/plugins/client_metrics_plugin.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ def call(context)
180180
complete_opts = {
181181
latency: end_time - start_time,
182182
attempt_count: context.retries + 1,
183-
user_agent: context.http_request.headers["user-agent"],
184183
final_error_retryable: final_error_retryable,
185184
final_http_status_code: context.http_response.status_code,
186185
final_aws_exception: final_aws_exception,

gems/aws-sdk-core/lib/aws-sdk-core/plugins/sign.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,28 @@ def self.signer_for(auth_scheme, config, sigv4_region_override = nil, sigv4_cred
4141
class Handler < Seahorse::Client::Handler
4242
def call(context)
4343
# Skip signing if using sigv2 signing from s3_signer in S3
44+
credentials = nil
4445
unless v2_signing?(context.config)
4546
signer = Sign.signer_for(
4647
context[:auth_scheme],
4748
context.config,
4849
context[:sigv4_region],
4950
context[:sigv4_credentials]
5051
)
52+
credentials = signer.credentials if signer.is_a?(SignatureV4)
5153
signer.sign(context)
5254
end
53-
@handler.call(context)
55+
with_metrics(credentials) { @handler.call(context) }
5456
end
5557

5658
private
5759

60+
def with_metrics(credentials, &block)
61+
return block.call unless credentials&.respond_to?(:metrics)
62+
63+
Aws::Plugins::UserAgent.metric(*credentials.metrics, &block)
64+
end
65+
5866
def v2_signing?(config)
5967
# 's3' is legacy signing, 'v4' is default
6068
config.respond_to?(:signature_version) &&
@@ -92,6 +100,8 @@ def sign_event(*args)
92100

93101
# @api private
94102
class SignatureV4
103+
attr_reader :signer
104+
95105
def initialize(auth_scheme, config, sigv4_overrides = {})
96106
scheme_name = auth_scheme['name']
97107

@@ -155,6 +165,10 @@ def sign_event(*args)
155165
@signer.sign_event(*args)
156166
end
157167

168+
def credentials
169+
@signer.credentials_provider
170+
end
171+
158172
private
159173

160174
def apply_authtype(context, req)

0 commit comments

Comments
 (0)