31
31
import software .amazon .awssdk .annotations .SdkPublicApi ;
32
32
import software .amazon .awssdk .annotations .SdkTestInternalApi ;
33
33
import software .amazon .awssdk .auth .credentials .internal .Ec2MetadataConfigProvider ;
34
+ import software .amazon .awssdk .auth .credentials .internal .Ec2MetadataDisableV1Resolver ;
34
35
import software .amazon .awssdk .auth .credentials .internal .HttpCredentialsLoader ;
35
36
import software .amazon .awssdk .auth .credentials .internal .HttpCredentialsLoader .LoadedCredentials ;
36
37
import software .amazon .awssdk .auth .credentials .internal .StaticResourcesEndpointProvider ;
40
41
import software .amazon .awssdk .profiles .ProfileFile ;
41
42
import software .amazon .awssdk .profiles .ProfileFileSupplier ;
42
43
import software .amazon .awssdk .profiles .ProfileFileSystemSetting ;
44
+ import software .amazon .awssdk .profiles .ProfileProperty ;
43
45
import software .amazon .awssdk .regions .util .HttpResourcesUtils ;
44
46
import software .amazon .awssdk .regions .util .ResourcesEndpointProvider ;
45
47
import software .amazon .awssdk .utils .Logger ;
53
55
54
56
/**
55
57
* Credentials provider implementation that loads credentials from the Amazon EC2 Instance Metadata Service.
56
- *
57
- * <P>
58
+ * <p>
58
59
* If {@link SdkSystemSetting#AWS_EC2_METADATA_DISABLED} is set to true, it will not try to load
59
60
* credentials from EC2 metadata service and will return null.
61
+ * <p>
62
+ * If {@link SdkSystemSetting#AWS_EC2_METADATA_V1_DISABLED} or {@link ProfileProperty#EC2_METADATA_V1_DISABLED}
63
+ * is set to true, credentials will only be loaded from EC2 metadata service if a token is successfully retrieved -
64
+ * fallback to load credentials without a token will be disabled.
60
65
*/
61
66
@ SdkPublicApi
62
67
public final class InstanceProfileCredentialsProvider
@@ -225,17 +230,15 @@ private String getToken(String imdsHostname) {
225
230
return HttpResourcesUtils .instance ().readResource (tokenEndpoint , "PUT" );
226
231
} catch (SdkServiceException e ) {
227
232
if (e .statusCode () == 400 ) {
233
+
228
234
throw SdkClientException .builder ()
229
235
.message ("Unable to fetch metadata token." )
230
236
.cause (e )
231
237
.build ();
232
238
}
233
-
234
- log .debug (() -> "Ignoring non-fatal exception while attempting to load metadata token from instance profile." , e );
235
- return null ;
239
+ return handleTokenErrorResponse (e );
236
240
} catch (Exception e ) {
237
- log .debug (() -> "Ignoring non-fatal exception while attempting to load metadata token from instance profile." , e );
238
- return null ;
241
+ return handleTokenErrorResponse (e );
239
242
}
240
243
}
241
244
@@ -247,6 +250,25 @@ private URI getTokenEndpoint(String imdsHostname) {
247
250
return URI .create (finalHost + TOKEN_RESOURCE );
248
251
}
249
252
253
+ private String handleTokenErrorResponse (Exception e ) {
254
+ if (isInsecureFallbackDisabled ()) {
255
+ String message = String .format ("Failed to retrieve IMDS token, and fallback to IMDS v1 is disabled via the %s "
256
+ + "environment variable and/or %s system property" ,
257
+ SdkSystemSetting .AWS_EC2_METADATA_V1_DISABLED .environmentVariable (),
258
+ SdkSystemSetting .AWS_EC2_METADATA_V1_DISABLED .property ());
259
+ throw SdkClientException .builder ()
260
+ .message (message )
261
+ .cause (e )
262
+ .build ();
263
+ }
264
+ log .debug (() -> "Ignoring non-fatal exception while attempting to load metadata token from instance profile." , e );
265
+ return null ;
266
+ }
267
+
268
+ private boolean isInsecureFallbackDisabled () {
269
+ return Ec2MetadataDisableV1Resolver .create (profileFile , profileName ).resolve ();
270
+ }
271
+
250
272
private String [] getSecurityCredentials (String imdsHostname , String metadataToken ) {
251
273
ResourcesEndpointProvider securityCredentialsEndpoint =
252
274
new StaticResourcesEndpointProvider (URI .create (imdsHostname + SECURITY_CREDENTIALS_RESOURCE ),
0 commit comments