google-auth-library
Advanced tools
Comparing version 7.13.0 to 7.14.0
@@ -12,2 +12,3 @@ import { BaseExternalAccountClient, BaseExternalAccountClientOptions } from './baseexternalclient'; | ||
regional_cred_verification_url: string; | ||
imdsv2_session_token_url?: string; | ||
}; | ||
@@ -25,2 +26,3 @@ } | ||
private readonly regionalCredVerificationUrl; | ||
private readonly imdsV2SessionTokenUrl?; | ||
private awsRequestSigner; | ||
@@ -47,11 +49,15 @@ private region; | ||
* The logic is summarized as: | ||
* 1. Retrieve AWS region from availability-zone. | ||
* 2a. Check AWS credentials in environment variables. If not found, get | ||
* 1. If imdsv2_session_token_url is provided in the credential source, then | ||
* fetch the aws session token and include it in the headers of the | ||
* metadata requests. This is a requirement for IDMSv2 but optional | ||
* for IDMSv1. | ||
* 2. Retrieve AWS region from availability-zone. | ||
* 3a. Check AWS credentials in environment variables. If not found, get | ||
* from security-credentials endpoint. | ||
* 2b. Get AWS credentials from security-credentials endpoint. In order | ||
* 3b. Get AWS credentials from security-credentials endpoint. In order | ||
* to retrieve this, the AWS role needs to be determined by calling | ||
* security-credentials endpoint without any argument. Then the | ||
* credentials can be retrieved via: security-credentials/role_name | ||
* 3. Generate the signed request to AWS STS GetCallerIdentity action. | ||
* 4. Inject x-goog-cloud-target-resource into header and serialize the | ||
* 4. Generate the signed request to AWS STS GetCallerIdentity action. | ||
* 5. Inject x-goog-cloud-target-resource into header and serialize the | ||
* signed request. This will be the subject-token to pass to GCP STS. | ||
@@ -62,2 +68,7 @@ * @return A promise that resolves with the external subject token. | ||
/** | ||
* @return A promise that resolves with the IMDSv2 Session Token. | ||
*/ | ||
private getImdsV2SessionToken; | ||
/** | ||
* @param headers The headers to be used in the metadata request. | ||
* @return A promise that resolves with the current AWS region. | ||
@@ -67,2 +78,3 @@ */ | ||
/** | ||
* @param headers The headers to be used in the metadata request. | ||
* @return A promise that resolves with the assigned role to the current | ||
@@ -76,2 +88,3 @@ * AWS VM. This is needed for calling the security-credentials endpoint. | ||
* @param roleName The role attached to the current VM. | ||
* @param headers The headers to be used in the metadata request. | ||
* @return A promise that resolves with the temporary AWS credentials | ||
@@ -78,0 +91,0 @@ * needed for creating the GetCallerIdentity signed request. |
@@ -47,2 +47,4 @@ "use strict"; | ||
options.credential_source.regional_cred_verification_url; | ||
this.imdsV2SessionTokenUrl = | ||
options.credential_source.imdsv2_session_token_url; | ||
const match = (_a = this.environmentId) === null || _a === void 0 ? void 0 : _a.match(/^(aws)(\d+)$/); | ||
@@ -66,11 +68,15 @@ if (!match || !this.regionalCredVerificationUrl) { | ||
* The logic is summarized as: | ||
* 1. Retrieve AWS region from availability-zone. | ||
* 2a. Check AWS credentials in environment variables. If not found, get | ||
* 1. If imdsv2_session_token_url is provided in the credential source, then | ||
* fetch the aws session token and include it in the headers of the | ||
* metadata requests. This is a requirement for IDMSv2 but optional | ||
* for IDMSv1. | ||
* 2. Retrieve AWS region from availability-zone. | ||
* 3a. Check AWS credentials in environment variables. If not found, get | ||
* from security-credentials endpoint. | ||
* 2b. Get AWS credentials from security-credentials endpoint. In order | ||
* 3b. Get AWS credentials from security-credentials endpoint. In order | ||
* to retrieve this, the AWS role needs to be determined by calling | ||
* security-credentials endpoint without any argument. Then the | ||
* credentials can be retrieved via: security-credentials/role_name | ||
* 3. Generate the signed request to AWS STS GetCallerIdentity action. | ||
* 4. Inject x-goog-cloud-target-resource into header and serialize the | ||
* 4. Generate the signed request to AWS STS GetCallerIdentity action. | ||
* 5. Inject x-goog-cloud-target-resource into header and serialize the | ||
* signed request. This will be the subject-token to pass to GCP STS. | ||
@@ -82,3 +88,8 @@ * @return A promise that resolves with the external subject token. | ||
if (!this.awsRequestSigner) { | ||
this.region = await this.getAwsRegion(); | ||
const metadataHeaders = {}; | ||
if (this.imdsV2SessionTokenUrl) { | ||
metadataHeaders['x-aws-ec2-metadata-token'] = | ||
await this.getImdsV2SessionToken(); | ||
} | ||
this.region = await this.getAwsRegion(metadataHeaders); | ||
this.awsRequestSigner = new awsrequestsigner_1.AwsRequestSigner(async () => { | ||
@@ -97,3 +108,3 @@ // Check environment variables for permanent credentials first. | ||
// Since the role on a VM can change, we don't need to cache it. | ||
const roleName = await this.getAwsRoleName(); | ||
const roleName = await this.getAwsRoleName(metadataHeaders); | ||
// Temporary credentials typically last for several hours. | ||
@@ -103,3 +114,3 @@ // Expiration is returned in response. | ||
// until their natural expiration. | ||
const awsCreds = await this.getAwsSecurityCredentials(roleName); | ||
const awsCreds = await this.getAwsSecurityCredentials(roleName, metadataHeaders); | ||
return { | ||
@@ -153,5 +164,19 @@ accessKeyId: awsCreds.AccessKeyId, | ||
/** | ||
* @return A promise that resolves with the IMDSv2 Session Token. | ||
*/ | ||
async getImdsV2SessionToken() { | ||
const opts = { | ||
url: this.imdsV2SessionTokenUrl, | ||
method: 'PUT', | ||
responseType: 'text', | ||
headers: { 'x-aws-ec2-metadata-token-ttl-seconds': '300' }, | ||
}; | ||
const response = await this.transporter.request(opts); | ||
return response.data; | ||
} | ||
/** | ||
* @param headers The headers to be used in the metadata request. | ||
* @return A promise that resolves with the current AWS region. | ||
*/ | ||
async getAwsRegion() { | ||
async getAwsRegion(headers) { | ||
// Priority order for region determination: | ||
@@ -170,2 +195,3 @@ // AWS_REGION > AWS_DEFAULT_REGION > metadata server. | ||
responseType: 'text', | ||
headers: headers, | ||
}; | ||
@@ -178,6 +204,7 @@ const response = await this.transporter.request(opts); | ||
/** | ||
* @param headers The headers to be used in the metadata request. | ||
* @return A promise that resolves with the assigned role to the current | ||
* AWS VM. This is needed for calling the security-credentials endpoint. | ||
*/ | ||
async getAwsRoleName() { | ||
async getAwsRoleName(headers) { | ||
if (!this.securityCredentialsUrl) { | ||
@@ -191,2 +218,3 @@ throw new Error('Unable to determine AWS role name due to missing ' + | ||
responseType: 'text', | ||
headers: headers, | ||
}; | ||
@@ -200,9 +228,11 @@ const response = await this.transporter.request(opts); | ||
* @param roleName The role attached to the current VM. | ||
* @param headers The headers to be used in the metadata request. | ||
* @return A promise that resolves with the temporary AWS credentials | ||
* needed for creating the GetCallerIdentity signed request. | ||
*/ | ||
async getAwsSecurityCredentials(roleName) { | ||
async getAwsSecurityCredentials(roleName, headers) { | ||
const response = await this.transporter.request({ | ||
url: `${this.securityCredentialsUrl}/${roleName}`, | ||
responseType: 'json', | ||
headers: headers, | ||
}); | ||
@@ -209,0 +239,0 @@ return response.data; |
@@ -36,7 +36,7 @@ /// <reference types="node" /> | ||
} | ||
export interface GoogleAuthOptions { | ||
export interface GoogleAuthOptions<T extends AuthClient = JSONClient> { | ||
/** | ||
* An `AuthClient` to use | ||
*/ | ||
auth?: AuthClient; | ||
authClient?: T; | ||
/** | ||
@@ -69,3 +69,3 @@ * Path to a .json, .pem, or .p12 key file | ||
export declare const CLOUD_SDK_CLIENT_ID = "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com"; | ||
export declare class GoogleAuth { | ||
export declare class GoogleAuth<T extends AuthClient = JSONClient> { | ||
transporter?: Transporter; | ||
@@ -84,3 +84,3 @@ /** | ||
jsonContent: JWTInput | ExternalAccountClientOptions | null; | ||
cachedCredential: JSONClient | Impersonated | Compute | AuthClient | null; | ||
cachedCredential: JSONClient | Impersonated | Compute | T | null; | ||
/** | ||
@@ -98,3 +98,3 @@ * Scopes populated by the client library by default. We differentiate between | ||
static DefaultTransporter: typeof DefaultTransporter; | ||
constructor(opts?: GoogleAuthOptions); | ||
constructor(opts?: GoogleAuthOptions<T>); | ||
setGapicJWTValues(client: JWT): void; | ||
@@ -226,3 +226,3 @@ /** | ||
*/ | ||
getClient(options?: DeprecatedGetClientOptions): Promise<AuthClient | Compute | JWT | UserRefreshClient | Impersonated | BaseExternalAccountClient>; | ||
getClient(options?: DeprecatedGetClientOptions): Promise<Compute | JWT | UserRefreshClient | Impersonated | BaseExternalAccountClient | NonNullable<T>>; | ||
/** | ||
@@ -229,0 +229,0 @@ * Creates a client which will fetch an ID token for authorization. |
@@ -45,3 +45,3 @@ "use strict"; | ||
this._cachedProjectId = opts.projectId || null; | ||
this.cachedCredential = opts.auth || null; | ||
this.cachedCredential = opts.authClient || null; | ||
this.keyFilename = opts.keyFilename || opts.keyFile; | ||
@@ -48,0 +48,0 @@ this.scopes = opts.scopes; |
@@ -21,3 +21,3 @@ import { GoogleAuth } from './auth/googleauth'; | ||
export { DefaultTransporter } from './transporters'; | ||
declare const auth: GoogleAuth; | ||
declare const auth: GoogleAuth<import("./auth/googleauth").JSONClient>; | ||
export { auth, GoogleAuth }; |
@@ -7,2 +7,14 @@ # Changelog | ||
## [7.14.0](https://github.com/googleapis/google-auth-library-nodejs/compare/v7.13.0...v7.14.0) (2022-02-22) | ||
### Features | ||
* Add AWS Session Token to Metadata Requests ([#1363](https://github.com/googleapis/google-auth-library-nodejs/issues/1363)) ([9ea3e98](https://github.com/googleapis/google-auth-library-nodejs/commit/9ea3e98582e8a69dedef89952ae08d64c49f48ef)) | ||
### Bug Fixes | ||
* Rename `auth` to `authClient` & Use Generics for `AuthClient` ([#1371](https://github.com/googleapis/google-auth-library-nodejs/issues/1371)) ([8373000](https://github.com/googleapis/google-auth-library-nodejs/commit/8373000b2240cb694e9492f849e5cc7e13c89b1a)) | ||
## [7.13.0](https://github.com/googleapis/google-auth-library-nodejs/compare/v7.12.0...v7.13.0) (2022-02-17) | ||
@@ -9,0 +21,0 @@ |
{ | ||
"name": "google-auth-library", | ||
"version": "7.13.0", | ||
"version": "7.14.0", | ||
"author": "Google Inc.", | ||
@@ -5,0 +5,0 @@ "description": "Google APIs Authentication Client Library for Node.js", |
421278
7162