Skip to content

feat: Regional access boundaries#12766

Open
vverman wants to merge 2 commits intogoogleapis:mainfrom
vverman:regional-access-boundaries
Open

feat: Regional access boundaries#12766
vverman wants to merge 2 commits intogoogleapis:mainfrom
vverman:regional-access-boundaries

Conversation

@vverman
Copy link
Copy Markdown
Contributor

@vverman vverman commented Apr 11, 2026

Contains changes for the feature Regional Access Boundary (Previously Called Trust Boundaries).

The following are salient changes:

  • Calls to refresh RAB are now all async and in a separate thread, we use the Executor pattern here.
  • Logic for refreshing RAB now exists in its own class for cleaner maintenance.
  • Self-signed jwts are within scope.
  • Changes to how we trigger RAB refresh and deal with refresh errors.
  • The env. variable gate for RAB has been removed.

@vverman vverman requested review from a team as code owners April 11, 2026 03:10
@vverman vverman changed the title Regional access boundaries feat: Regional access boundaries Apr 11, 2026
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 introduces support for Regional Access Boundaries (RAB) across various credential types, including Compute Engine, External Account, and Service Account credentials. It adds a RegionalAccessBoundaryManager to handle the asynchronous fetching, caching, and cooldown logic for RAB data, which is then included as an x-allowed-locations header in outgoing requests. Feedback includes removing unnecessary .rej files from the repository, replacing an unbounded thread pool with a bounded one for safety, and simplifying the logic for adding quota project IDs to request metadata.

@@ -0,0 +1,26 @@
diff a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentials.java (rejected hunks)
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

The pull request contains several .rej files (e.g., ExternalAccountAuthorizedUserCredentials.java.rej, ExternalAccountCredentials.java.rej, etc.). These files are typically generated when a patch fails to apply cleanly and should not be committed to the repository. Please remove all .rej files from the PR.

Comment on lines +58 to +67
private static final ExecutorService REFRESH_EXECUTOR =
Executors.newCachedThreadPool(
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "RAB-refresh-thread");
t.setDaemon(true);
return t;
}
});
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

The use of an unbounded thread pool (Executors.newCachedThreadPool()) is discouraged as it can lead to excessive thread creation under high load. Per the general rules, a bounded thread pool should be used instead.

  private static final ExecutorService REFRESH_EXECUTOR =
      new java.util.concurrent.ThreadPoolExecutor(
          0,
          100,
          60L,
          java.util.concurrent.TimeUnit.SECONDS,
          new java.util.concurrent.SynchronousQueue<Runnable>(),
          new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
              Thread t = new Thread(r, "RAB-refresh-thread");
              t.setDaemon(true);
              return t;
            }
          });
References
  1. For safety, use a bounded thread pool (e.g., ThreadPoolExecutor with a defined maximum size) instead of an unbounded one (e.g., Executors.newCachedThreadPool()), even if the current logic seems to limit concurrent tasks.

Comment on lines +584 to +587
Map<String, List<String>> headers = new HashMap<>(super.getAdditionalHeaders());

String quotaProjectId = this.getQuotaProjectId();
if (quotaProjectId != null) {
return addQuotaProjectIdToRequestMetadata(quotaProjectId, headers);
}
return headers;
return addQuotaProjectIdToRequestMetadata(quotaProjectId, headers);
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

This method can be simplified by passing the result of super.getAdditionalHeaders() directly to addQuotaProjectIdToRequestMetadata. This avoids creating an unnecessary intermediate HashMap and ensures that an unmodifiable map is returned when quotaProjectId is null.

Suggested change
Map<String, List<String>> headers = new HashMap<>(super.getAdditionalHeaders());
String quotaProjectId = this.getQuotaProjectId();
if (quotaProjectId != null) {
return addQuotaProjectIdToRequestMetadata(quotaProjectId, headers);
}
return headers;
return addQuotaProjectIdToRequestMetadata(quotaProjectId, headers);
return addQuotaProjectIdToRequestMetadata(getQuotaProjectId(), super.getAdditionalHeaders());

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