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,27 @@ 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 "
256
+ + "%s system property, %s environment variable, or %s configuration file profile"
257
+ + " setting." ,
258
+ SdkSystemSetting .AWS_EC2_METADATA_V1_DISABLED .environmentVariable (),
259
+ SdkSystemSetting .AWS_EC2_METADATA_V1_DISABLED .property (),
260
+ ProfileProperty .EC2_METADATA_V1_DISABLED );
261
+ throw SdkClientException .builder ()
262
+ .message (message )
263
+ .cause (e )
264
+ .build ();
265
+ }
266
+ log .debug (() -> "Ignoring non-fatal exception while attempting to load metadata token from instance profile." , e );
267
+ return null ;
268
+ }
269
+
270
+ private boolean isInsecureFallbackDisabled () {
271
+ return Ec2MetadataDisableV1Resolver .create (profileFile , profileName ).resolve ();
272
+ }
273
+
250
274
private String [] getSecurityCredentials (String imdsHostname , String metadataToken ) {
251
275
ResourcesEndpointProvider securityCredentialsEndpoint =
252
276
new StaticResourcesEndpointProvider (URI .create (imdsHostname + SECURITY_CREDENTIALS_RESOURCE ),
0 commit comments