4040import software .amazon .awssdk .auth .credentials .StaticCredentialsProvider ;
4141import software .amazon .awssdk .auth .credentials .SystemPropertyCredentialsProvider ;
4242import software .amazon .awssdk .core .internal .util .ClassLoaderHelper ;
43+ import software .amazon .awssdk .core .useragent .BusinessMetricFeatureId ;
4344import software .amazon .awssdk .profiles .Profile ;
4445import software .amazon .awssdk .profiles .ProfileFile ;
4546import software .amazon .awssdk .profiles .ProfileProperty ;
@@ -161,6 +162,7 @@ private AwsCredentialsProvider basicProfileCredentialsProvider() {
161162 .accessKeyId (properties .get (ProfileProperty .AWS_ACCESS_KEY_ID ))
162163 .secretAccessKey (properties .get (ProfileProperty .AWS_SECRET_ACCESS_KEY ))
163164 .accountId (properties .get (ProfileProperty .AWS_ACCOUNT_ID ))
165+ .providerName (BusinessMetricFeatureId .CREDENTIALS_PROFILE .value ())
164166 .build ();
165167 return StaticCredentialsProvider .create (credentials );
166168 }
@@ -177,6 +179,7 @@ private AwsCredentialsProvider sessionProfileCredentialsProvider() {
177179 .secretAccessKey (properties .get (ProfileProperty .AWS_SECRET_ACCESS_KEY ))
178180 .sessionToken (properties .get (ProfileProperty .AWS_SESSION_TOKEN ))
179181 .accountId (properties .get (ProfileProperty .AWS_ACCOUNT_ID ))
182+ .providerName (BusinessMetricFeatureId .CREDENTIALS_PROFILE .value ())
180183 .build ();
181184 return StaticCredentialsProvider .create (credentials );
182185 }
@@ -187,6 +190,7 @@ private AwsCredentialsProvider credentialProcessCredentialsProvider() {
187190 return ProcessCredentialsProvider .builder ()
188191 .command (properties .get (ProfileProperty .CREDENTIAL_PROCESS ))
189192 .staticAccountId (properties .get (ProfileProperty .AWS_ACCOUNT_ID ))
193+ .source (BusinessMetricFeatureId .CREDENTIALS_PROFILE_PROCESS .value ())
190194 .build ();
191195 }
192196
@@ -195,10 +199,16 @@ private AwsCredentialsProvider credentialProcessCredentialsProvider() {
195199 */
196200 private AwsCredentialsProvider ssoProfileCredentialsProvider () {
197201 validateRequiredPropertiesForSsoCredentialsProvider ();
202+ boolean isLegacy = isLegacySsoConfiguration ();
203+ String sourceFeatureId = isLegacy ?
204+ BusinessMetricFeatureId .CREDENTIALS_PROFILE_SSO_LEGACY .value () :
205+ BusinessMetricFeatureId .CREDENTIALS_PROFILE_SSO .value ();
206+
198207 return ssoCredentialsProviderFactory ().create (
199208 ProfileProviderCredentialsContext .builder ()
200209 .profile (profile )
201210 .profileFile (profileFile )
211+ .source (sourceFeatureId )
202212 .build ());
203213 }
204214
@@ -211,6 +221,10 @@ private void validateRequiredPropertiesForSsoCredentialsProvider() {
211221 }
212222 }
213223
224+ private boolean isLegacySsoConfiguration () {
225+ return !properties .containsKey (ProfileSection .SSO_SESSION .getPropertyKeyName ());
226+ }
227+
214228 private AwsCredentialsProvider roleAndWebIdentityTokenProfileCredentialsProvider () {
215229 requireProperties (ProfileProperty .ROLE_ARN , ProfileProperty .WEB_IDENTITY_TOKEN_FILE );
216230
@@ -223,6 +237,7 @@ private AwsCredentialsProvider roleAndWebIdentityTokenProfileCredentialsProvider
223237 .roleArn (roleArn )
224238 .roleSessionName (roleSessionName )
225239 .webIdentityTokenFile (webIdentityTokenFile )
240+ .source (BusinessMetricFeatureId .CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN .value ())
226241 .build ();
227242
228243 return WebIdentityCredentialsUtils .factory ().create (credentialProperties );
@@ -249,7 +264,8 @@ private AwsCredentialsProvider roleAndSourceProfileBasedProfileCredentialsProvid
249264 .credentialsProvider (children ))
250265 .orElseThrow (this ::noSourceCredentialsException );
251266
252- return stsCredentialsProviderFactory ().create (sourceCredentialsProvider , profile );
267+ String sourceFeatureId = BusinessMetricFeatureId .CREDENTIALS_PROFILE_SOURCE_PROFILE .value ();
268+ return createStsCredentialsProviderWithMetrics (sourceCredentialsProvider , sourceFeatureId );
253269 }
254270
255271 /**
@@ -260,8 +276,10 @@ private AwsCredentialsProvider roleAndCredentialSourceBasedProfileCredentialsPro
260276 requireProperties (ProfileProperty .CREDENTIAL_SOURCE );
261277
262278 CredentialSourceType credentialSource = CredentialSourceType .parse (properties .get (ProfileProperty .CREDENTIAL_SOURCE ));
279+ String profileSource = BusinessMetricFeatureId .CREDENTIALS_PROFILE_NAMED_PROVIDER .value ();
263280 AwsCredentialsProvider credentialsProvider = credentialSourceCredentialProvider (credentialSource );
264- return stsCredentialsProviderFactory ().create (credentialsProvider , profile );
281+
282+ return createStsCredentialsProviderWithMetrics (credentialsProvider , profileSource );
265283 }
266284
267285 private AwsCredentialsProvider credentialSourceCredentialProvider (CredentialSourceType credentialSource ) {
@@ -298,6 +316,39 @@ private IllegalStateException noSourceCredentialsException() {
298316 return new IllegalStateException (error );
299317 }
300318
319+ /**
320+ * Extract business metrics from a credentials provider by resolving credentials and checking the provider name.
321+ * This is used to propagate business metrics from source credentials to assume role operations.
322+ */
323+ private String extractBusinessMetricsFromProvider (AwsCredentialsProvider credentialsProvider ) {
324+ try {
325+ AwsCredentials credentials = credentialsProvider .resolveCredentials ();
326+ return credentials .providerName ().orElse (null );
327+ } catch (Exception e ) {
328+ return null ;
329+ }
330+ }
331+
332+ /**
333+ * Helper method to create STS credentials provider with business metrics propagation.
334+ * This method extracts business metrics from the source credentials provider and combines them
335+ * with the profile-level business metrics before creating the STS credentials provider.
336+ */
337+ private AwsCredentialsProvider createStsCredentialsProviderWithMetrics (AwsCredentialsProvider sourceCredentialsProvider ,
338+ String profileMetric ) {
339+ String sourceMetrics = extractBusinessMetricsFromProvider (sourceCredentialsProvider );
340+
341+ String combinedSource = profileMetric ;
342+ if (sourceMetrics != null && !sourceMetrics .isEmpty ()) {
343+ combinedSource = profileMetric + "," + sourceMetrics ;
344+ }
345+
346+ ChildProfileCredentialsProviderFactory .ChildProfileCredentialsRequest request =
347+ new ChildProfileCredentialsProviderFactory
348+ .ChildProfileCredentialsRequest (sourceCredentialsProvider , profile , combinedSource );
349+ return stsCredentialsProviderFactory ().create (request );
350+ }
351+
301352 /**
302353 * Load the factory that can be used to create the STS credentials provider, assuming it is on the classpath.
303354 */
0 commit comments