Skip to content

chore(auth): Address remaining Regional Access Boundary feedback#12867

Open
vverman wants to merge 10 commits intogoogleapis:regional-access-boundariesfrom
vverman:rab-clean
Open

chore(auth): Address remaining Regional Access Boundary feedback#12867
vverman wants to merge 10 commits intogoogleapis:regional-access-boundariesfrom
vverman:rab-clean

Conversation

@vverman
Copy link
Copy Markdown
Contributor

@vverman vverman commented Apr 20, 2026

  1. The RAB refresh uses a direct executor with a fixed thread pool as opposed to instantiating a new thread each time.

  2. The RAB env gate -> GOOGLE_AUTH_TRUST_BOUNDARY_ENABLE_EXPERIMENT has been removed. This means RAB refresh triggers by default.

  3. Added other fixes/suggestions made in the previous Java PR.

@vverman vverman requested review from a team as code owners April 20, 2026 22:06
@vverman vverman requested review from lqiu96 and nbayati April 20, 2026 22:08
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 the RegionalAccessBoundary and RegionalAccessBoundaryManager classes to improve resource management and testability. Key changes include replacing environment-variable-based feature toggling with a ThreadLocal mechanism for tests, migrating from manual thread creation to a bounded ExecutorService for asynchronous refresh tasks to prevent resource exhaustion, and ensuring HTTP responses are properly disconnected in a finally block. Additionally, the test suite has been migrated to JUnit 5, and several tests were cleaned up by removing deprecated environment provider mocks. I have no feedback to provide.

@vverman vverman changed the title feat: Update Regional Access Boundary feat(auth): Update Regional Access Boundary Apr 22, 2026
@lqiu96 lqiu96 changed the title feat(auth): Update Regional Access Boundary chore(auth): Address remaining Regional Access Boundary feedback Apr 23, 2026
Comment on lines +84 to +96
// Unbounded thread creation is discouraged in library code to avoid resource
// exhaustion. A shared, bounded executor service ensures a hard limit (5)
// on concurrent refresh tasks, while threadCount provides unique names
// for easier debugging.
private static final AtomicInteger threadCount = new AtomicInteger(0);
private static final ExecutorService EXECUTOR =
Executors.newFixedThreadPool(
5,
r -> {
Thread t = new Thread(r, "RAB-refresh-" + threadCount.getAndIncrement());
t.setDaemon(true);
return t;
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The tradeoff we are making is between:

  1. Executor - Possible memory leak where the executor and the threads cannot be released as the auth library does not have a lifecycle.
  2. Thread - Possible unbounded threads created (note: we aim to limit the amount of threads spawning per credential, but it may be possible to spawn an unbounded number of credentials).

I don't think there will be perfect solution. For a middle ground, is it possible to add allowCoreThreadTimeOut() and set a keep-alive value of something like ~1ish hour(s)? Single credentials would end up just invoking new Thread() in the pool as the RAB call should be idle for the other ~5 hours. If there are multiple credentials that need RAB calls, the executor should be able to use the existing threads as they'll no longer be marked as idle. WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this is a good idea to manage memory usage, especially in situations where the application is redeployed.

In the present implementation, since we don't shutdown the threads within the pool, they would not be garbage collected and the reference would live on while the server doesn't use the old application.

With this thread shutdown suggestion, we avoid that pitfall.

I agree that the threads which are idle for an hour can be timed-out and removed from the pool.

@lqiu96
Copy link
Copy Markdown
Member

lqiu96 commented Apr 23, 2026

@vverman The sdk-platform-java-ci CI issues are not relevant for this PR (existing issues as part of the monorepo migration).

PTAL at the conventialcommit CI complaints: https://github.com/googleapis/google-cloud-java/pull/12867/checks?check_run_id=72739487063

@vverman
Copy link
Copy Markdown
Contributor Author

vverman commented Apr 24, 2026

Conventional commits addressed.

@vverman vverman requested a review from lqiu96 April 24, 2026 19:45
Copy link
Copy Markdown
Member

@lqiu96 lqiu96 left a comment

Choose a reason for hiding this comment

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

Changes LGTM overall. Added a few comments if you could take a look. I'm not entirely sure what the DISABLE_RAB_TESTS_ENV is for

@vverman
Copy link
Copy Markdown
Contributor Author

vverman commented May 1, 2026

Added per-test disablement of RAB refresh and bounded queue.

@vverman vverman requested review from lqiu96 and lsirac May 1, 2026 21:32
transportFactory.transport.setServiceAccountEmail("SA_CLIENT_EMAIL");
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
credentials.regionalAccessBoundaryManager.setCachedRAB(
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.

This seeds a fake cached RAB, but that isn't the same as disabling RAB.

We should replace the fake cached RAB setup with a real test-only disable path.

For non-RAB tests, we want two things:

  1. no background RAB refresh
  2. no x-allowed-locations header added to request metadata

Adding fake cached RAB only solves the first part, and changes the headers/logs under test.

Copy link
Copy Markdown
Contributor Author

@vverman vverman May 2, 2026

Choose a reason for hiding this comment

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

For non-RAB tests we want ... no x-allowed-locations header added to request metadata

For those test that do check the presence of the headers, they check for the presence of the authorization header. Which is rightly present, thereby not affecting the existing testing logic.

It is not that the x-allowed-locations header is incorrect, that we're 'disabling RAB' rather it is because async refreshes might non-deterministically consume mocks. That problem is avoided here.

Additionally, this method doesn't add any production logic exclusively for testing.

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.

The downside with your approach is you need to make sure to update all the assertions. There are now 5 log events, not 3, so the test is failing. Please make sure the necessary places are updated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the suggestion.

I checked the failure in LoggingTest and found the test which was failing "getRequestMetadata_hasAccessToken" was caused by the lazy loading of the universe domain, triggered by the new RAB check, rather than the RAB refresh itself."

For ComputeEngineCredentials, the first call to getUniverseDomain() fetches it from the metadata server, generating 2 extra logs. Since the RAB check now calls this lazily during getRequestMetadata(), these logs were captured in the test.

So I bumped the count for the test to 5. The rest of the tests weren't updated because they don't trigger a lazy load of the universe domain and aren't at risk of triggering the increased logs.

@vverman vverman requested a review from lsirac May 3, 2026 07:59
Comment on lines 167 to 173
/**
* Checks if the regional access boundary feature is enabled. The feature is enabled if the
* environment variable or system property "GOOGLE_AUTH_TRUST_BOUNDARY_ENABLE_EXPERIMENT" is set
* to "true" or "1" (case-insensitive).
* Checks if the regional access boundary feature is enabled.
*
* <p>This method is for internal use only and may be changed or removed in future releases.
*
* @return True if the regional access boundary feature is enabled, false otherwise.
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since we deleted the isEnabled() method, can we remove the associated method?


// Note: this is for internal testing use use only.
// TODO: Fix unit test mocks so this can be removed
// Refer -> https://github.com/googleapis/google-auth-library-java/issues/1898
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we close this ticket created here? Or we want to wait until this is merged into main?

LOGGER_PROVIDER,
java.util.logging.Level.WARNING,
null,
"Regional Access Boundary background refresh failed to schedule: " + e.getMessage());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I forgot to ask about this earlier. Do we plan to have any public docs regarding this to explain this behavior? I wonder if something like this may be confusing to the user and they may be asking what RAB is.

If not, can we use something that either has a bit softer wording or adding something that assures this is nothing to worry about

* This duplicates tests setups, but centralizes logging test setup in this class.
*/
class LoggingTest {
public class LoggingTest {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: is this needed? Or just slipped in

Comment on lines +137 to +139
awsCredential.regionalAccessBoundaryManager.setCachedRAB(
new RegionalAccessBoundary(
"dummy-locations", Arrays.asList("dummy-loc"), awsCredential.clock));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: changes make sense. thanks I like this more than the env var idea.

Is possible just to create one constant RegionalAccessBoundary object per file?

new Exception("Regional Access Boundary background refresh failed to schedule", e));
LoggingUtils.log(
LOGGER_PROVIDER,
java.util.logging.Level.WARNING,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: can you use the short name and import instead?

Copy link
Copy Markdown
Member

@lqiu96 lqiu96 left a comment

Choose a reason for hiding this comment

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

added a few small nits. Changes look fine on my end. PTAL at the nits and see if the make sense/ should be addressed. Feel free to merge afterwards

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.

4 participants