Skip to content

feat(oauth2): implement IAM impersonation mTLS transport pinning and 401 recovery - #14212

Open
macastelaz wants to merge 2 commits into
googleapis:oauth2-bound-tokensfrom
macastelaz:cert-bound-oauth-iam-pinning
Open

macastelaz wants to merge 2 commits into
googleapis:oauth2-bound-tokensfrom
macastelaz:cert-bound-oauth-iam-pinning

Conversation

@macastelaz

@macastelaz macastelaz commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

🥞 Stacked PRs


Summary

Propagates the cycle-pinned mTLS transport factory into ImpersonatedCredentials during Workload Identity Federation with Service Account Impersonation, ensuring the IAM generateAccessToken call uses the exact same pinned client certificate as the STS token exchange.
Also extends 401 recovery in IdentityPoolCredentials to catch unauthorized responses across both STS and IAM calls, reloading fresh certificates and re-executing the full refresh cycle.

Test Coverage

  • 1,030 unit tests passing across oauth2_http (including transport pinning lifecycle, multi-cycle rotation, 401 retry on IAM, and suppressed error handling).
  • Google Java Format: 100% compliant (com.spotify.fmt:fmt-maven-plugin:2.25).
    See b/542238030 for tracking.

@macastelaz
macastelaz requested review from a team as code owners August 30, 2026 02:28
@macastelaz
macastelaz marked this pull request as draft August 30, 2026 02:28

@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 (specifically for file-based JSON credential sources over mTLS endpoints) and adds certificate pinning with automatic certificate reloading on 401 Unauthorized errors. It also updates other credential classes to support passing a custom HttpTransportFactory during token refresh, masks actor tokens in logs, and adds corresponding unit tests. The review feedback suggests persisting the reloaded transport factory back to this.transportFactory after a successful retry to prevent subsequent refreshes from failing first, and preserving programmatically set actorTokenSupplier instances in the Builder copy constructor.

…401 recovery

- Pin mTLS HttpTransportFactory across multi-step STS and IAM token exchanges so both requests use the exact same certificate snapshot within a single refresh cycle.
- Add 401 Unauthorized recovery with automatic certificate reload from X509Provider and single-retry coordination in IdentityPoolCredentials and ImpersonatedCredentials.
- Preserve custom non-default HttpTransportFactory instances when X509Provider is configured.
- Add comprehensive unit tests across IdentityPoolCredentialsTest, ImpersonatedCredentialsTest, and OAuth2UtilsTest.
@macastelaz
macastelaz force-pushed the cert-bound-oauth-iam-pinning branch from e09d76e to dadeda6 Compare September 17, 2026 03:17
…dentials and address review findings

- Explicitly scope inner sourceCredentials to CLOUD_PLATFORM_SCOPE in ExternalAccountCredentials.buildImpersonatedCredentials and ImpersonatedCredentials.refreshAccessToken so STS issues tokens authorized to call IAM generateAccessToken even when downstream target scopes are configured via createScoped.
- Ensure public no-arg ImpersonatedCredentials.refreshAccessToken delegates without overriding source credential transport settings.
- Preserve custom actorTokenSupplier in IdentityPoolCredentials.Builder copy constructor when credentialSource is present.
- Ensure HTTP response is closed in a finally block in ImpersonatedCredentials.refreshAccessToken.
- Attach initial 401 exception as suppressed when the 401 retry attempt fails in IdentityPoolCredentials.refreshWithRetry.
- Add unit tests in IdentityPoolCredentialsTest and ImpersonatedCredentialsTest covering scoped impersonation, custom actorTokenSupplier preservation, and retry exception chaining.
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