From b92d9e4dbb146c487ba85d4c214c82f7e780ef20 Mon Sep 17 00:00:00 2001 From: Pranav Iyer Date: Wed, 3 Jun 2026 19:08:42 -0700 Subject: [PATCH 1/4] feat(auth): Skip RAB lookup if MDS returns a non-email. --- .../src/auth/computeclient.ts | 6 ++- .../test/test.compute.ts | 45 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts index a5329e4cfa2b..3ab4f0f323da 100644 --- a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts +++ b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts @@ -147,8 +147,12 @@ export class Compute extends OAuth2Client { * @return The regional access boundary URL string. * @internal */ - public async getRegionalAccessBoundaryUrl(): Promise { + public async getRegionalAccessBoundaryUrl(): Promise { const email = await this.resolveServiceAccountEmail(); + const emailRegex = /^[^@]+@[^@]+\.[^@]+$/; + if (!email || !emailRegex.test(email)) { + return null; + } const regionalAccessBoundaryUrl = SERVICE_ACCOUNT_LOOKUP_ENDPOINT.replace( '{service_account_email}', encodeURIComponent(email), diff --git a/core/packages/google-auth-library-nodejs/test/test.compute.ts b/core/packages/google-auth-library-nodejs/test/test.compute.ts index 52c6ae85cf4d..ce70c3e0508e 100644 --- a/core/packages/google-auth-library-nodejs/test/test.compute.ts +++ b/core/packages/google-auth-library-nodejs/test/test.compute.ts @@ -370,5 +370,50 @@ describe('compute', () => { /RegionalAccessBoundary: Failed to retrieve default service account email from metadata server./, ); }); + + it('should return null from getRegionalAccessBoundaryUrl if email returned from metadata server is not a valid email format', async () => { + const compute = new Compute(); + const fakeEmail = 'not-a-valid-email'; + const metadataStub = sandbox.stub(gcpMetadata, 'instance'); + metadataStub.callThrough(); + metadataStub + .withArgs('service-accounts/default/email') + .resolves(fakeEmail); + + const url = await compute.getRegionalAccessBoundaryUrl(); + assert.strictEqual(url, null); + }); + + it('should return null from getRegionalAccessBoundaryUrl if custom serviceAccountEmail is not a valid email format', async () => { + const compute = new Compute({serviceAccountEmail: 'not-an-email'}); + const url = await compute.getRegionalAccessBoundaryUrl(); + assert.strictEqual(url, null); + }); + + it('should NOT trigger asynchronous RAB refresh and NOT attach RAB header if email from metadata server is not a valid email format', async () => { + const compute = new Compute(); + const fakeEmail = 'not-a-valid-email'; + const metadataStub = sandbox.stub(gcpMetadata, 'instance'); + metadataStub.callThrough(); + metadataStub + .withArgs('service-accounts/default/email') + .resolves(fakeEmail); + + const tokenScope = setupTokenNock('default'); + + const url = 'https://pubsub.googleapis.com'; + const headers = await compute.getRequestHeaders(url); + + // Headers should NOT have RAB + assert.strictEqual(headers.get('x-allowed-locations'), null); + + // Wait a little bit for any background task to run + await new Promise(r => setTimeout(r, 500)); + + // Regional access boundary data should remain null + assert.strictEqual(compute.getRegionalAccessBoundary(), null); + + tokenScope.done(); + }); }); }); From 8f2f170a4a14d95950b83394b82563e78bf05ddc Mon Sep 17 00:00:00 2001 From: Pranav Iyer Date: Wed, 3 Jun 2026 19:28:14 -0700 Subject: [PATCH 2/4] Added logic to skip MDS calls in case non-email is returned. Added tests. --- .../src/auth/computeclient.ts | 19 +++++++++++++++++- .../test/test.compute.ts | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts index 3ab4f0f323da..7c5e76d16509 100644 --- a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts +++ b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts @@ -15,6 +15,7 @@ import {GaxiosError} from 'gaxios'; import * as gcpMetadata from 'gcp-metadata'; +import {AuthClient} from './authclient'; import {CredentialRequest, Credentials} from './credentials'; import { GetTokenResponse, @@ -40,6 +41,8 @@ export interface ComputeOptions extends OAuth2ClientOptions { export class Compute extends OAuth2Client { readonly serviceAccountEmail: string; scopes: string[]; + private rabLookupSkippedWarningLogged = false; + private resolvedServiceAccountEmail?: string; /** * Google Compute Engine service account credentials. @@ -151,6 +154,12 @@ export class Compute extends OAuth2Client { const email = await this.resolveServiceAccountEmail(); const emailRegex = /^[^@]+@[^@]+\.[^@]+$/; if (!email || !emailRegex.test(email)) { + if (!this.rabLookupSkippedWarningLogged) { + AuthClient.log.info( + `RegionalAccessBoundary: Service account email "${email}" is not in a valid email format. Skipping regional access boundary lookup.` + ); + this.rabLookupSkippedWarningLogged = true; + } return null; } const regionalAccessBoundaryUrl = SERVICE_ACCOUNT_LOOKUP_ENDPOINT.replace( @@ -171,9 +180,17 @@ export class Compute extends OAuth2Client { return this.serviceAccountEmail; } + if (this.resolvedServiceAccountEmail !== undefined) { + return this.resolvedServiceAccountEmail; + } + // Otherwise, fetch the default email from the metadata server. try { - return await gcpMetadata.instance('service-accounts/default/email'); + const email = await gcpMetadata.instance( + 'service-accounts/default/email' + ); + this.resolvedServiceAccountEmail = email; + return email; } catch (e) { throw new Error( 'RegionalAccessBoundary: Failed to retrieve default service account email from metadata server.', diff --git a/core/packages/google-auth-library-nodejs/test/test.compute.ts b/core/packages/google-auth-library-nodejs/test/test.compute.ts index ce70c3e0508e..0a5ee48557da 100644 --- a/core/packages/google-auth-library-nodejs/test/test.compute.ts +++ b/core/packages/google-auth-library-nodejs/test/test.compute.ts @@ -415,5 +415,25 @@ describe('compute', () => { tokenScope.done(); }); + + it('should cache the service account email and avoid repeated metadata server calls when email is invalid', async () => { + const compute = new Compute(); + const fakeEmail = 'not-a-valid-email'; + const metadataStub = sandbox.stub(gcpMetadata, 'instance'); + metadataStub.callThrough(); + metadataStub + .withArgs('service-accounts/default/email') + .resolves(fakeEmail); + + // Call it the first time + let url = await compute.getRegionalAccessBoundaryUrl(); + assert.strictEqual(url, null); + assert.strictEqual(metadataStub.callCount, 1); + + // Call it a second time - should use cache and not call MDS again + url = await compute.getRegionalAccessBoundaryUrl(); + assert.strictEqual(url, null); + assert.strictEqual(metadataStub.callCount, 1); + }); }); }); From acecc8be705b197bf04c689ce255799852b7879c Mon Sep 17 00:00:00 2001 From: Pranav Iyer Date: Wed, 3 Jun 2026 19:47:45 -0700 Subject: [PATCH 3/4] Added email regex as a const. --- .../google-auth-library-nodejs/src/auth/computeclient.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts index 7c5e76d16509..a734c2fbf9c0 100644 --- a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts +++ b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts @@ -39,6 +39,7 @@ export interface ComputeOptions extends OAuth2ClientOptions { } export class Compute extends OAuth2Client { + private static readonly EMAIL_REGEX = /^[^@]+@[^@]+\.[^@]+$/; readonly serviceAccountEmail: string; scopes: string[]; private rabLookupSkippedWarningLogged = false; @@ -152,11 +153,10 @@ export class Compute extends OAuth2Client { */ public async getRegionalAccessBoundaryUrl(): Promise { const email = await this.resolveServiceAccountEmail(); - const emailRegex = /^[^@]+@[^@]+\.[^@]+$/; - if (!email || !emailRegex.test(email)) { + if (!email || !Compute.EMAIL_REGEX.test(email)) { if (!this.rabLookupSkippedWarningLogged) { AuthClient.log.info( - `RegionalAccessBoundary: Service account email "${email}" is not in a valid email format. Skipping regional access boundary lookup.` + `RegionalAccessBoundary: Service account email "${email}" is not in a valid email format. Skipping regional access boundary lookup.`, ); this.rabLookupSkippedWarningLogged = true; } @@ -187,7 +187,7 @@ export class Compute extends OAuth2Client { // Otherwise, fetch the default email from the metadata server. try { const email = await gcpMetadata.instance( - 'service-accounts/default/email' + 'service-accounts/default/email', ); this.resolvedServiceAccountEmail = email; return email; From 97fa19f1e8e9944f9a0599744520ab96f82e8fe7 Mon Sep 17 00:00:00 2001 From: Pranav Iyer Date: Thu, 4 Jun 2026 18:07:28 -0700 Subject: [PATCH 4/4] Simplified logic. --- .../src/auth/computeclient.ts | 44 +++++++++++-------- .../test/test.compute.ts | 28 ++++++++++-- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts index a734c2fbf9c0..4729e2c9df3b 100644 --- a/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts +++ b/core/packages/google-auth-library-nodejs/src/auth/computeclient.ts @@ -42,8 +42,7 @@ export class Compute extends OAuth2Client { private static readonly EMAIL_REGEX = /^[^@]+@[^@]+\.[^@]+$/; readonly serviceAccountEmail: string; scopes: string[]; - private rabLookupSkippedWarningLogged = false; - private resolvedServiceAccountEmail?: string; + private isNonEmailAccount = false; /** * Google Compute Engine service account credentials. @@ -145,21 +144,18 @@ export class Compute extends OAuth2Client { /** * Returns the regional access boundary lookup URL for the GCE instance. - * This implementation resolves the default service account email of the GCE - * instance to construct the lookup endpoint. + * This implementation resolves the service account email of the GCE + * instance to construct the lookup endpoint. If the resolved email is invalid + * or not found, it returns `null` to skip the regional access boundary check. * - * @return The regional access boundary URL string. + * @return The regional access boundary URL string, or null if regional access + * boundary checks should be skipped. * @internal */ public async getRegionalAccessBoundaryUrl(): Promise { const email = await this.resolveServiceAccountEmail(); - if (!email || !Compute.EMAIL_REGEX.test(email)) { - if (!this.rabLookupSkippedWarningLogged) { - AuthClient.log.info( - `RegionalAccessBoundary: Service account email "${email}" is not in a valid email format. Skipping regional access boundary lookup.`, - ); - this.rabLookupSkippedWarningLogged = true; - } + if (email === null) { + // This credential corresponds to a non-email account; skip RAB lookup. return null; } const regionalAccessBoundaryUrl = SERVICE_ACCOUNT_LOOKUP_ENDPOINT.replace( @@ -172,24 +168,34 @@ export class Compute extends OAuth2Client { /** * Resolves the service account email. If the email is set to 'default', * it fetches the email from the GCE metadata server. - * @returns A promise that resolves with the service account email. + * @returns A promise that resolves with the service account email, + * or null if MDS returns an invalid email format */ - private async resolveServiceAccountEmail(): Promise { + private async resolveServiceAccountEmail(): Promise { + if (this.isNonEmailAccount) { + return null; + } + if (this.serviceAccountEmail !== 'default') { // If a specific email is provided, return it directly. return this.serviceAccountEmail; } - if (this.resolvedServiceAccountEmail !== undefined) { - return this.resolvedServiceAccountEmail; - } - // Otherwise, fetch the default email from the metadata server. try { const email = await gcpMetadata.instance( 'service-accounts/default/email', ); - this.resolvedServiceAccountEmail = email; + + // If the metadata server returned an non-email format, log a warning only once. + if (!email || !Compute.EMAIL_REGEX.test(email)) { + AuthClient.log.info( + `RegionalAccessBoundary: Service account email "${email}" is not in a valid email format. Skipping regional access boundary lookup.`, + ); + this.isNonEmailAccount = true; + return null; + } + return email; } catch (e) { throw new Error( diff --git a/core/packages/google-auth-library-nodejs/test/test.compute.ts b/core/packages/google-auth-library-nodejs/test/test.compute.ts index 0a5ee48557da..85f4367a5166 100644 --- a/core/packages/google-auth-library-nodejs/test/test.compute.ts +++ b/core/packages/google-auth-library-nodejs/test/test.compute.ts @@ -384,10 +384,32 @@ describe('compute', () => { assert.strictEqual(url, null); }); - it('should return null from getRegionalAccessBoundaryUrl if custom serviceAccountEmail is not a valid email format', async () => { - const compute = new Compute({serviceAccountEmail: 'not-an-email'}); + it('should return valid URL from getRegionalAccessBoundaryUrl if custom serviceAccountEmail is set', async () => { + const email = 'custom-sa@example.com'; + const compute = new Compute({serviceAccountEmail: email}); const url = await compute.getRegionalAccessBoundaryUrl(); - assert.strictEqual(url, null); + const expectedUrl = SERVICE_ACCOUNT_LOOKUP_ENDPOINT.replace( + '{service_account_email}', + encodeURIComponent(email), + ); + assert.strictEqual(url, expectedUrl); + }); + + it('should return valid URL from getRegionalAccessBoundaryUrl when MDS returns a valid default service account email', async () => { + const compute = new Compute(); + const fakeEmail = 'fake-default-sa@developer.gserviceaccount.com'; + const metadataStub = sandbox.stub(gcpMetadata, 'instance'); + metadataStub.callThrough(); + metadataStub + .withArgs('service-accounts/default/email') + .resolves(fakeEmail); + + const url = await compute.getRegionalAccessBoundaryUrl(); + const expectedUrl = SERVICE_ACCOUNT_LOOKUP_ENDPOINT.replace( + '{service_account_email}', + encodeURIComponent(fakeEmail), + ); + assert.strictEqual(url, expectedUrl); }); it('should NOT trigger asynchronous RAB refresh and NOT attach RAB header if email from metadata server is not a valid email format', async () => {