Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat!: check for trust boundaries before sending requests google apis. #1966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 0 commits into from

Conversation

vverman
Copy link
Collaborator

@vverman vverman commented May 14, 2025

This change includes trust boundaries for Service Accounts in the google auth nodejs library.

Impact

This will allow clients who use the google auth library to also enable trust boundaries ensuring service accounts can access only those resources which are within the trust boundary. We use this design doc as reference for the code changes.

Testing

Testing will be added in post initial design review.

@vverman vverman requested review from a team as code owners May 14, 2025 23:33
@product-auto-label product-auto-label bot added the size: l Pull request size is large. label May 14, 2025
@vverman vverman assigned vverman and unassigned vverman May 14, 2025
@vverman vverman requested a review from lsirac May 14, 2025 23:34
if (!this.trustBoundaryEnabled) {
return null;
}
//todo pjiyer, add Error handling
Copy link
Contributor

Choose a reason for hiding this comment

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

// TODO(pjiyer): Implement error handling logic for lookup endpoint.

requestOptions.headers = new Headers();
requestOptions.headers.set('authorization', authHeader);

console.log(`TrustBoundary: Fetching data from ${url}`);
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't forget to cleanup all these console.log comments

}
}

// --- Internal Helper Function ---
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be removed

requestOptions,
);
console.log('Response from lookup endpoint ' + response);
// const response: GaxiosResponse<AllowedLocationsResponse> = await authenticatedClient.request<AllowedLocationsResponse>(requestOptions);
Copy link
Contributor

Choose a reason for hiding this comment

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

Renove commented code

}
}

// --- Exported Lookup Function ---
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// --- Exported Lookup Function ---

Comment on lines 328 to 337
if (
!headers.has('x-goog-allowed-locations') && // don't override a value the user sets.
this.trustBoundary &&
this.trustBoundary.encodedLocations
) {
headers.set(
'x-goog-allowed-locations',
this.trustBoundary.encodedLocations,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Prefer comments inline, and maybe splitting this up for readability

const ServiceAccountAllowedLocationsEndpoint =
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s/allowedLocations';

// --- Interfaces ---
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// --- Interfaces ---

* Workload Identity Pool -> project_id, pool_id
* Workforce Pool -> pool_id
*/
export interface TrustBoundaryDescriptor {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is the right approach (mixing all of these together)

*/
async function _fetchTrustBoundaryData(
authenticatedClient: AuthClient,
authHeader: string,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this need to be passed? can't we get it from the auth client?

Copy link
Collaborator Author

@vverman vverman May 19, 2025

Choose a reason for hiding this comment

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

Since the lookup endpoint is called in the refreshTokenNoCache(), and in the refreshToken function, the new authClient credentials aren't set.

They are set in the getRequestMetadataAsync() in the oauth2client. We cannot make the trust boundary calls in the oauth2client as it doesn't exclusively pertain to service accounts.

That's why I chose to pass the authHeader exclusively.

Another option is to set the access_token of the client credentials in the refreshTokenNoCache function. That would allow us to get the header directly from the authClient without the header param.

I'd welcome suggestions to circumvent this.

* @param cachedData Optional previously fetched data to check for no-op or use as fallback on error.
* @returns A Promise resolving to TrustBoundaryData or null if fetching fails and no cache is available.
*/
export async function lookupServiceAccountTrustBoundary(
Copy link
Contributor

Choose a reason for hiding this comment

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

The difference in logic for retrieving the trust boundary based on credential type is just the lookup endpoint URL. So there should be one lookup method. Different auth clients can provide the lookup endpoint.

@lsirac
Copy link
Contributor

lsirac commented May 15, 2025

The current approach has each client duplicating trust boundary logic. Can we centralize and simplify this?

@vverman vverman force-pushed the trust_boundaries branch 2 times, most recently from f0454e7 to 6d8fd9d Compare May 19, 2025 20:26
@vverman vverman changed the title Included changes for trust boundaries service accounts feat!: check for trust boundaries before sending requests google apis. May 19, 2025
@@ -317,11 +325,22 @@ export abstract class AuthClient
) {
headers.set('x-goog-user-project', this.quotaProjectId);
}
if (
!headers.has('x-goog-allowed-locations') &&
Copy link

Choose a reason for hiding this comment

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

I think we need to send the most up to date TB data. The !headers.has('x-goog-allowed-locations') check will skip setting and updating the value it if was previously set.

if (
!headers.has('x-goog-allowed-locations') &&
this.trustBoundary &&
this.trustBoundary.encodedLocations
Copy link

Choose a reason for hiding this comment

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

Checking that encodedLocations is not an empty string is not enough.
We only want to set the header if the value is not no-op (0x0)

@@ -343,6 +363,10 @@ export abstract class AuthClient
target.set('authorization', authorizationHeader);
}

if (xGoogAllowedLocs) {
Copy link

Choose a reason for hiding this comment

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

The name of the method still implies that it only sets x-goog-user-project and authorization headers. I'd recommend either creating a separate method to set x-goog-allowed-locations, or updating the method name.

@vverman vverman closed this May 20, 2025
@vverman vverman force-pushed the trust_boundaries branch from 6d8fd9d to 813a63a Compare May 20, 2025 20:04
@product-auto-label product-auto-label bot added size: u Pull request is empty. and removed size: l Pull request size is large. labels May 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: u Pull request is empty.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.