Skip to content

feat(auth) Regional Access Boundaries mTLS endpoint#8450

Open
vverman wants to merge 2 commits into
googleapis:regional-access-boundariesfrom
vverman:rab-auto-switch-mtls-endpoint
Open

feat(auth) Regional Access Boundaries mTLS endpoint#8450
vverman wants to merge 2 commits into
googleapis:regional-access-boundariesfrom
vverman:rab-auto-switch-mtls-endpoint

Conversation

@vverman
Copy link
Copy Markdown
Contributor

@vverman vverman commented Jun 6, 2026

Added logic to:

Centralize mTLS enablement logic within the auth library.
Based on 1. determine whether mtls or regular RAB lookup endpoint should be called.
Added tests for the same.

@vverman vverman requested a review from a team as a code owner June 6, 2026 02:17
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors mTLS configuration and path resolution logic by extracting shared helpers into a new mtlsutils.ts module, and updates RegionalAccessBoundaryManager to support mTLS. The review feedback suggests caching the https.Agent using a WeakMap to avoid redundant disk I/O and enable TCP connection reuse across requests. Additionally, it recommends throwing CertificateSourceUnavailableError instead of a generic Error when referenced certificate or key files are missing to maintain consistency with the rest of the library.

Comment on lines +17 to 20
import * as https from 'https';
import {canMtlsBeEnabled, getClientCertAndKey} from './mtlsutils';

const log = makeLog('auth');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

To support efficient connection pooling and avoid test isolation issues, we should cache the https.Agent promise. Using a WeakMap keyed by the RegionalAccessBoundaryManager instance ensures that each manager instance reuses its agent across requests, while keeping tests isolated.

Suggested change
import * as https from 'https';
import {canMtlsBeEnabled, getClientCertAndKey} from './mtlsutils';
const log = makeLog('auth');
import * as https from 'https';
import {canMtlsBeEnabled, getClientCertAndKey} from './mtlsutils';
const log = makeLog('auth');
const mtlsAgentCache = new WeakMap<
RegionalAccessBoundaryManager,
Promise<https.Agent | null>
>();

Comment on lines +252 to +265
// If mTLS can be enabled, use mTLS agent and switch to the mTLS endpoint
try {
if (await canMtlsBeEnabled()) {
const {cert, key} = await getClientCertAndKey();
opts.agent = new https.Agent({cert, key});
regionalAccessBoundaryUrl = regionalAccessBoundaryUrl.replace(
'iamcredentials.googleapis.com',
'iamcredentials.mtls.googleapis.com',
);
opts.url = regionalAccessBoundaryUrl;
}
} catch (e) {
log.error('RegionalAccessBoundary: Failed to initialize mTLS: ', e);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Creating a new https.Agent and reading the certificate/key files from disk on every single request is highly inefficient and prevents TCP connection reuse (keep-alive). We should reuse the cached agent promise from the WeakMap to enable connection pooling and avoid redundant I/O.

    // If mTLS can be enabled, use mTLS agent and switch to the mTLS endpoint
    let agentPromise = mtlsAgentCache.get(this);
    if (!agentPromise) {
      agentPromise = (async () => {
        try {
          if (await canMtlsBeEnabled()) {
            const {cert, key} = await getClientCertAndKey();
            return new https.Agent({cert, key});
          }
        } catch (e) {
          log.error('RegionalAccessBoundary: Failed to initialize mTLS: ', e);
        }
        return null;
      })();
      mtlsAgentCache.set(this, agentPromise);
    }

    try {
      const agent = await agentPromise;
      if (agent) {
        opts.agent = agent;
        regionalAccessBoundaryUrl = regionalAccessBoundaryUrl.replace(
          'iamcredentials.googleapis.com',
          'iamcredentials.mtls.googleapis.com',
        );
        opts.url = regionalAccessBoundaryUrl;
      }
    } catch (e) {
      log.error('RegionalAccessBoundary: Failed to initialize mTLS: ', e);
    }

Comment on lines +113 to +115
throw new Error(
`Certificate configuration exists but referenced files are missing: cert_path=${certPath}, key_path=${keyPath}`,
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with other certificate resolution errors in this library, we should throw CertificateSourceUnavailableError instead of a generic Error when the referenced certificate or key files are missing.

Suggested change
throw new Error(
`Certificate configuration exists but referenced files are missing: cert_path=${certPath}, key_path=${keyPath}`,
);
throw new CertificateSourceUnavailableError(
'Certificate configuration exists but referenced files are missing: cert_path=' + certPath + ', key_path=' + keyPath,
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant