@@ -55,13 +55,24 @@ describe('AwsClient', () => {
5555 'https://sts.{region}.amazonaws.com?' +
5656 'Action=GetCallerIdentity&Version=2011-06-15' ,
5757 } ;
58+ const awsCredentialSourceWithImdsv2 = Object . assign (
59+ { imdsv2_session_token_url : `${ metadataBaseUrl } /latest/api/token` } ,
60+ awsCredentialSource
61+ ) ;
5862 const awsOptions = {
5963 type : 'external_account' ,
6064 audience,
6165 subject_token_type : 'urn:ietf:params:aws:token-type:aws4_request' ,
6266 token_url : getTokenUrl ( ) ,
6367 credential_source : awsCredentialSource ,
6468 } ;
69+ const awsOptionsWithImdsv2 = {
70+ type : 'external_account' ,
71+ audience,
72+ subject_token_type : 'urn:ietf:params:aws:token-type:aws4_request' ,
73+ token_url : getTokenUrl ( ) ,
74+ credential_source : awsCredentialSourceWithImdsv2 ,
75+ } ;
6576 const awsOptionsWithSA = Object . assign (
6677 {
6778 service_account_impersonation_url : getServiceAccountImpersonationUrl ( ) ,
@@ -385,19 +396,7 @@ describe('AwsClient', () => {
385396 . reply ( 200 , awsSecurityCredentials )
386397 ) ;
387398
388- const credentialSourceWithSessionTokenUrl = Object . assign (
389- { imdsv2_session_token_url : `${ metadataBaseUrl } /latest/api/token` } ,
390- awsCredentialSource
391- ) ;
392- const awsOptionsWithSessionTokenUrl = {
393- type : 'external_account' ,
394- audience,
395- subject_token_type : 'urn:ietf:params:aws:token-type:aws4_request' ,
396- token_url : getTokenUrl ( ) ,
397- credential_source : credentialSourceWithSessionTokenUrl ,
398- } ;
399-
400- const client = new AwsClient ( awsOptionsWithSessionTokenUrl ) ;
399+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
401400 const subjectToken = await client . retrieveSubjectToken ( ) ;
402401
403402 assert . deepEqual ( subjectToken , expectedSubjectToken ) ;
@@ -829,6 +828,163 @@ describe('AwsClient', () => {
829828
830829 assert . deepEqual ( subjectToken , expectedSubjectTokenNoToken ) ;
831830 } ) ;
831+
832+ it ( 'should resolve on success for permanent creds with imdsv2' , async ( ) => {
833+ process . env . AWS_ACCESS_KEY_ID = accessKeyId ;
834+ process . env . AWS_SECRET_ACCESS_KEY = secretAccessKey ;
835+
836+ const scopes : nock . Scope [ ] = [ ] ;
837+ scopes . push (
838+ nock ( metadataBaseUrl , {
839+ reqheaders : { 'x-aws-ec2-metadata-token-ttl-seconds' : '300' } ,
840+ } )
841+ . put ( '/latest/api/token' )
842+ . reply ( 200 , awsSessionToken )
843+ ) ;
844+
845+ scopes . push (
846+ nock ( metadataBaseUrl , {
847+ reqheaders : { 'x-aws-ec2-metadata-token' : awsSessionToken } ,
848+ } )
849+ . get ( '/latest/meta-data/placement/availability-zone' )
850+ . reply ( 200 , `${ awsRegion } b` )
851+ ) ;
852+
853+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
854+ const subjectToken = await client . retrieveSubjectToken ( ) ;
855+
856+ assert . deepEqual ( subjectToken , expectedSubjectTokenNoToken ) ;
857+ scopes . forEach ( scope => scope . done ( ) ) ;
858+ } ) ;
859+
860+ it ( 'should resolve on success for temporary creds with imdsv2' , async ( ) => {
861+ process . env . AWS_ACCESS_KEY_ID = accessKeyId ;
862+ process . env . AWS_SECRET_ACCESS_KEY = secretAccessKey ;
863+ process . env . AWS_SESSION_TOKEN = token ;
864+
865+ const scopes : nock . Scope [ ] = [ ] ;
866+ scopes . push (
867+ nock ( metadataBaseUrl , {
868+ reqheaders : { 'x-aws-ec2-metadata-token-ttl-seconds' : '300' } ,
869+ } )
870+ . put ( '/latest/api/token' )
871+ . reply ( 200 , awsSessionToken )
872+ ) ;
873+
874+ scopes . push (
875+ nock ( metadataBaseUrl , {
876+ reqheaders : { 'x-aws-ec2-metadata-token' : awsSessionToken } ,
877+ } )
878+ . get ( '/latest/meta-data/placement/availability-zone' )
879+ . reply ( 200 , `${ awsRegion } b` )
880+ ) ;
881+
882+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
883+ const subjectToken = await client . retrieveSubjectToken ( ) ;
884+
885+ assert . deepEqual ( subjectToken , expectedSubjectToken ) ;
886+ scopes . forEach ( scope => scope . done ( ) ) ;
887+ } ) ;
888+
889+ it ( 'should not call metadata server with imdsv2 if creds are retrievable through env' , async ( ) => {
890+ process . env . AWS_ACCESS_KEY_ID = accessKeyId ;
891+ process . env . AWS_SECRET_ACCESS_KEY = secretAccessKey ;
892+ process . env . AWS_REGION = awsRegion ;
893+
894+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
895+ const subjectToken = await client . retrieveSubjectToken ( ) ;
896+
897+ assert . deepEqual ( subjectToken , expectedSubjectTokenNoToken ) ;
898+ } ) ;
899+
900+ it ( 'should call metadata server with imdsv2 if creds are not retrievable through env' , async ( ) => {
901+ process . env . AWS_REGION = awsRegion ;
902+
903+ const scopes : nock . Scope [ ] = [ ] ;
904+ scopes . push (
905+ nock ( metadataBaseUrl , {
906+ reqheaders : { 'x-aws-ec2-metadata-token-ttl-seconds' : '300' } ,
907+ } )
908+ . put ( '/latest/api/token' )
909+ . reply ( 200 , awsSessionToken )
910+ ) ;
911+
912+ scopes . push (
913+ nock ( metadataBaseUrl , {
914+ reqheaders : { 'x-aws-ec2-metadata-token' : awsSessionToken } ,
915+ } )
916+ . get ( '/latest/meta-data/iam/security-credentials' )
917+ . reply ( 200 , awsRole )
918+ . get ( `/latest/meta-data/iam/security-credentials/${ awsRole } ` )
919+ . reply ( 200 , awsSecurityCredentials )
920+ ) ;
921+
922+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
923+ const subjectToken = await client . retrieveSubjectToken ( ) ;
924+
925+ assert . deepEqual ( subjectToken , expectedSubjectToken ) ;
926+ scopes . forEach ( scope => scope . done ( ) ) ;
927+ } ) ;
928+
929+ it ( 'should call metadata server with imdsv2 if secret access key is not not retrievable through env' , async ( ) => {
930+ process . env . AWS_REGION = awsRegion ;
931+ process . env . AWS_ACCESS_KEY_ID = accessKeyId ;
932+
933+ const scopes : nock . Scope [ ] = [ ] ;
934+ scopes . push (
935+ nock ( metadataBaseUrl , {
936+ reqheaders : { 'x-aws-ec2-metadata-token-ttl-seconds' : '300' } ,
937+ } )
938+ . put ( '/latest/api/token' )
939+ . reply ( 200 , awsSessionToken )
940+ ) ;
941+
942+ scopes . push (
943+ nock ( metadataBaseUrl , {
944+ reqheaders : { 'x-aws-ec2-metadata-token' : awsSessionToken } ,
945+ } )
946+ . get ( '/latest/meta-data/iam/security-credentials' )
947+ . reply ( 200 , awsRole )
948+ . get ( `/latest/meta-data/iam/security-credentials/${ awsRole } ` )
949+ . reply ( 200 , awsSecurityCredentials )
950+ ) ;
951+
952+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
953+ const subjectToken = await client . retrieveSubjectToken ( ) ;
954+
955+ assert . deepEqual ( subjectToken , expectedSubjectToken ) ;
956+ scopes . forEach ( scope => scope . done ( ) ) ;
957+ } ) ;
958+
959+ it ( 'should call metadata server with imdsv2 if access key is not not retrievable through env' , async ( ) => {
960+ process . env . AWS_DEFAULT_REGION = awsRegion ;
961+ process . env . AWS_SECRET_ACCESS_KEY = accessKeyId ;
962+
963+ const scopes : nock . Scope [ ] = [ ] ;
964+ scopes . push (
965+ nock ( metadataBaseUrl , {
966+ reqheaders : { 'x-aws-ec2-metadata-token-ttl-seconds' : '300' } ,
967+ } )
968+ . put ( '/latest/api/token' )
969+ . reply ( 200 , awsSessionToken )
970+ ) ;
971+
972+ scopes . push (
973+ nock ( metadataBaseUrl , {
974+ reqheaders : { 'x-aws-ec2-metadata-token' : awsSessionToken } ,
975+ } )
976+ . get ( '/latest/meta-data/iam/security-credentials' )
977+ . reply ( 200 , awsRole )
978+ . get ( `/latest/meta-data/iam/security-credentials/${ awsRole } ` )
979+ . reply ( 200 , awsSecurityCredentials )
980+ ) ;
981+
982+ const client = new AwsClient ( awsOptionsWithImdsv2 ) ;
983+ const subjectToken = await client . retrieveSubjectToken ( ) ;
984+
985+ assert . deepEqual ( subjectToken , expectedSubjectToken ) ;
986+ scopes . forEach ( scope => scope . done ( ) ) ;
987+ } ) ;
832988 } ) ;
833989
834990 describe ( 'getAccessToken()' , ( ) => {
0 commit comments