Skip to content

Commit

Permalink
fix: use IMDSv2 for all metadata service calls.
Browse files Browse the repository at this point in the history
Problem: We did not attach the token to IMDS calls, resulting in IMDSv1 being used. The SDK does support using tokens but only
for calls to the endpoint `/latest/meta-data/iam/security-credentials/`.
https://github.com/aws/aws-sdk-js/blob/3333f8b49283f5bbff823ab8a8469acedb7fe3d5/lib/metadata_service.js#L123-L235

Solution: Call the "private" sdk method to get the token so code isn't duplicated, and attach that in the header of our calls
just like the sdk does for the above endpoint.

AWS SDK v3 does not support token handling aws/aws-sdk-js-v3#4004
  • Loading branch information
hayemaxi committed Feb 1, 2024
1 parent 9c5edff commit 9c2d6f9
Showing 1 changed file with 27 additions and 10 deletions.
37 changes: 27 additions & 10 deletions src/shared/clients/ec2MetadataClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { ClassToInterfaceType } from '../utilities/tsUtils'
import { MetadataService } from 'aws-sdk'
import { AWSError, MetadataService } from 'aws-sdk'

export interface IamInfo {
Code: string
Expand Down Expand Up @@ -33,17 +33,34 @@ export class DefaultEc2MetadataClient {

public invoke<T>(path: string): Promise<T> {
return new Promise((resolve, reject) => {
this.metadata.request(path, (err, response) => {
if (err) {
reject(err)
// fetchMetadataToken is private for some reason, but has the exact token functionality
// that we want out of the metadata service.
;(this.metadata as any).fetchMetadataToken((tokenErr: AWSError, token: string) => {
if (tokenErr) {
reject(tokenErr)
return
}
try {
const jsonResponse: T = JSON.parse(response)
resolve(jsonResponse)
} catch (e) {
reject(`Ec2MetadataClient: invalid response from "${path}": ${response}\nerror: ${e}`)
}

this.metadata.request(
path,
{
// By attaching the token we force the use of IMDSv2.
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html
headers: { 'x-aws-ec2-metadata-token': token },
},
(err, response) => {
if (err) {
reject(err)
return
}
try {
const jsonResponse: T = JSON.parse(response)
resolve(jsonResponse)
} catch (e) {
reject(`Ec2MetadataClient: invalid response from "${path}": ${response}\nerror: ${e}`)
}
}
)
})
})
}
Expand Down

0 comments on commit 9c2d6f9

Please sign in to comment.