Skip to content

Conversation

@vverman
Copy link
Contributor

@vverman vverman commented Jan 25, 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.
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.

@vverman vverman requested review from a team as code owners January 25, 2026 21:35
@vverman vverman requested a review from a team January 25, 2026 21:35
@product-auto-label product-auto-label bot added the size: xl Pull request size is extra large. label Jan 25, 2026
@vverman vverman requested review from lqiu96 and nbayati January 25, 2026 21:49
@lqiu96 lqiu96 changed the base branch from feat-tb-sa to feat/agentic-identities-cloudrun February 3, 2026 19:16
@lqiu96 lqiu96 requested a review from a team as a code owner February 3, 2026 19:16
@vverman vverman changed the base branch from feat/agentic-identities-cloudrun to feat-tb-sa February 6, 2026 22:40
private static final Pattern INVALID_TOKEN_ERROR =
Pattern.compile("\\s*error\\s*=\\s*\"?invalid_token\"?");

private static final String STALE_RAB_ERROR_MESSAGE = "stale regional access boundary";
Copy link
Contributor

Choose a reason for hiding this comment

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

Still waiting for the backend team to confirm the wording, we might need to update this based on their response. see b/450921839

LOGGER_PROVIDER,
Level.INFO,
null,
"RAB lookup failed; entering cooldown for "
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"RAB lookup failed; entering cooldown for "
"Regional Access Boundary lookup failed; entering cooldown for "

nit: Spell out for user-facing error messages/ logs

Comment on lines 225 to 243
@@ -193,33 +228,41 @@ static TrustBoundary refresh(
.setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS)
.setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR)
.setMultiplier(OAuth2Utils.RETRY_MULTIPLIER)
.setMaxElapsedTimeMillis(maxRetryElapsedTimeMillis)
.build();

HttpUnsuccessfulResponseHandler unsuccessfulResponseHandler =
new HttpBackOffUnsuccessfulResponseHandler(backoff);
new HttpBackOffUnsuccessfulResponseHandler(backoff)
.setBackOffRequired(
response -> {
int statusCode = response.getStatusCode();
return statusCode == 500
|| statusCode == 502
|| statusCode == 503
|| statusCode == 504;
});
Copy link
Member

Choose a reason for hiding this comment

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

qq, since the server-side will still make the RAB call if we have failure (e.g. no header is attached), can we have this call not have any retries and max duration of like 1-2s?

The reason I'm thinking this way is that the async RAB call uses ForkJoinPool's commonPool. I think we should try to time bound the IO requests that go to that executor pool since that is a JDK executor pool that is shared with the customer's application.

Comment on lines +347 to 349
public final RegionalAccessBoundary getRegionalAccessBoundary() {
return regionalAccessBoundaryManager.getCachedRAB();
}
Copy link
Member

Choose a reason for hiding this comment

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

are the methods here intentional to be public (e.g. used by the customer)? Can they be package-private.

I know you mentioned the seeded RAB token is used by the customer

final class TrustBoundary {
public final class RegionalAccessBoundary implements Serializable {

public static final String HEADER_KEY = "x-allowed-locations";
Copy link
Member

Choose a reason for hiding this comment

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

nit: Can you give this a more descriptive constant name

e.g. perhaps ALLOWED_LOCATIONS_HEADER_KEY

}

private static class CooldownState {
/** The time (in milliseconds) when the current cooldown period started. */
Copy link
Member

@lqiu96 lqiu96 Feb 10, 2026

Choose a reason for hiding this comment

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

nit:

Suggested change
/** The time (in milliseconds) when the current cooldown period started. */
/** The time (milliseconds from epoch) when the current cooldown period started. */

Comment on lines +1150 to +1160
List<String> authHeaders = requestMetadata.get(AuthHttpConstants.AUTHORIZATION);
if (authHeaders != null && !authHeaders.isEmpty()) {
// Extract the token value to trigger a background Regional Access Boundary refresh.
String authHeader = authHeaders.get(0);
if (authHeader.startsWith(AuthHttpConstants.BEARER + " ")) {
String tokenValue = authHeader.substring((AuthHttpConstants.BEARER + " ").length());
// Use a null expiration as JWTs are short-lived anyway.
AccessToken wrappedToken = new AccessToken(tokenValue, null);
refreshRegionalAccessBoundaryIfExpired(uri, wrappedToken);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Add a small comment to explain this custom logic here.

e.g. something like SSJWT's don't go through the typical Oauth2Credential getRequestMetadata() flow that triggers the async RAB

Comment on lines +437 to +439
metadata = new HashMap<>(metadata);
metadata.put(
RegionalAccessBoundary.HEADER_KEY, Collections.singletonList(rab.getEncodedLocations()));
Copy link
Member

Choose a reason for hiding this comment

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

Can you use the ImmuatableMap.Builder() from guava to build the new metadata

@lqiu96 lqiu96 changed the title feat: Regional Access Boundary Update feat: Async Refresh for Regional Access Boundaries Feb 10, 2026
@lqiu96
Copy link
Member

lqiu96 commented Feb 10, 2026

Thanks for the clarification @vverman! Would it be possible to split the stable RAB + seeding logic into a separate PR?

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

Labels

size: xl Pull request size is extra large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants