Skip to content

feat(oauth2): Extract actor tokens for cert-bound OAuth2 STS exchange - #13955

Open
macastelaz wants to merge 13 commits into
googleapis:oauth2-bound-tokensfrom
macastelaz:cert-bound-oauth-part2
Open

feat(oauth2): Extract actor tokens for cert-bound OAuth2 STS exchange#13955
macastelaz wants to merge 13 commits into
googleapis:oauth2-bound-tokensfrom
macastelaz:cert-bound-oauth-part2

Conversation

@macastelaz

@macastelaz macastelaz commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Background

This PR is the first milestone in supporting Certificate-Bound
OAuth 2.0 Tokens for workloads calling Google APIs via mTLS.

Currently, ExternalAccountCredentials assumes that a workload
provides either a file credential or a certificate configuration,
but not both. For certificate-bound tokens, we need the mTLS
certificate configuration for the transport layer alongside a disk
file containing the JSON payload representing the identity tokens
(e.g., subject and actor tokens).

What this PR does

This PR updates the OAuth2 configuration extraction and STS
(Security Token Service) wire-up to support fetching bound tokens
with delegation.

Specifically, it includes:

  1. Relaxed Mutual Exclusivity
    Modified IdentityPoolCredentialSource to allow both a
    credential_source (file) and a certificate_config (mTLS) to co-
    exist without throwing an IllegalArgumentException.
  2. Actor Token Config Parsing
    IdentityPoolCredentialSource to parse actor_token_type and
    Extended ExternalAccountCredentials and
    actor_token_field_name from the JSON configuration payload.
  3. Dual-Token LRU Caching
    Refactored FileIdentityPoolSubjectTokenSupplier into a generalized
    FileIdentityPoolTokenSupplier capable of extracting both actor and
    subject tokens. Introduced a volatile cache so that requests for both tokens
    during a single refresh cycle do not result in redundant disk I/O.
  4. STS Token Request Injection
    Updated IdentityPoolCredentials to take in an
    IdentityPoolActorTokenSupplier and actorTokenType. Wired these
    directly into the StsTokenExchangeRequest using the existing
    ActingParty construct so that the actor token gets properly
    injected into the STS token exchange payload.

Manual Testing

Next Steps

The next phase (which will follow in a separate PR to keep reviews
scoped) will introduce dynamic mTLS transport rotation natively in
GAX and a 401 connection-draining interceptor required for
downstream service retry logic.

Based on design: https://docs.google.com/document/d/1NIKeJX86ETNAjoQA-lZIE_G_8mHspisBaL8gwNCO3dA/edit?resourcekey=0-z7teBZZk0WFIJEHL2ODZxw&tab=t.0

Implementation of Phase 1-3 of the Cert-Bound Oauth2 Design Document:
1. Extend IdentityPoolCredentialSource to parse actorTokenFieldName.
2. Relax mutual exclusivity to allow BOTH file and certificate configurations.
3. Parse actor_token_type in ExternalAccountCredentials.
4. Refactor FileIdentityPoolTokenSupplier and track file timestamp via volatile CachedFile for the parsed JSON payload.
5. Inject actor_token and actor_token_type into StsTokenExchangeRequest using ActingParty.
6. Enforce that actor token extraction requires an mTLS STS configuration.

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

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.

Code Review

This pull request introduces support for actor tokens in IdentityPoolCredentials by adding actor token types and field names, introducing the IdentityPoolActorTokenSupplier interface, and refactoring the file-based supplier to FileIdentityPoolTokenSupplier with caching. Feedback suggests optimizing disk I/O by sharing a single FileIdentityPoolTokenSupplier instance for both subject and actor tokens, passing the target field name dynamically, and relaxing the mTLS URL validation check to generically look for .mtls. to support custom universes and Private Service Connect endpoints.

@macastelaz
macastelaz changed the base branch from main to oauth2-bound-tokens July 30, 2026 02:48
@macastelaz
macastelaz marked this pull request as ready for review July 30, 2026 17:13
@macastelaz
macastelaz requested review from a team as code owners July 30, 2026 17:13
- Mark CachedFile and X509Provider transient to ensure clean serialization.
- Add static modifier to FileIdentityPoolTokenSupplier serialVersionUID.
- Make IdentityPoolActorTokenSupplier public with @NullMarked annotation.
- Preserve actorTokenSupplier in IdentityPoolCredentials Builder copy constructor.
- Mask actor_token in Slf4jLoggingHelpers sensitive keys.
- Add no-arg constructor to MtlsHttpTransportFactory for serialization support.
- Handle Data.isNull in FileIdentityPoolTokenSupplier JSON parsing.
- Add comprehensive test coverage for supplier caching, builder, serialization, and log masking.
…uilder copy constructor

- Guard actorTokenSupplier assignment with if (this.credentialSource == null) in Builder copy constructor.
- Add getIdentityPoolActorTokenSupplier getter for test assertions.
- Add createScoped tests for both file-sourced and supplier-sourced credentials with actor tokens.
…s and FileIdentityPoolTokenSupplier

- Add builder_actorTokenTypeWithoutSupplier_throws testing missing supplier validation.
- Add builder_fileWithCertificateConfig_initializesMtlsTransport testing mTLS initialization for composite file + cert sources.
- Add toBuilder_preservesConfiguration testing builder reconstruction.
- Add parseToken_textFormat_succeeds and parseToken_jsonFormat_missingFieldName_throws testing static token parsing methods.
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.

2 participants