Repository navigation
Commit 1fed6d4
authored
feat(oauth2): Extract actor tokens for cert-bound OAuth2 STS exchange (#13955)
## Summary
Adds support for actor tokens in `IdentityPoolCredentials` during
certificate-bound OAuth2 STS token exchange, and implements per-cycle
mTLS certificate snapshotting and single-retry rotation.
---
## Architectural Changes & Review Feedback Resolutions
### 1. Actor Token Extraction & Atomic Reads
- Added package-private `IdentityPoolActorTokenSupplier` interface.
- Enhanced `FileIdentityPoolSubjectTokenSupplier` with `readTokens()` to
read and parse JSON credential files in a single atomic I/O operation,
returning a `TokenPair` for subject and actor tokens.
- Removed unreliable file timestamp caching; the file is read at most
once per refresh cycle.
- Added early validation in `IdentityPoolCredentialSource`:
`actorTokenFieldName` must be non-empty, distinct from
`subjectTokenFieldName`, and is supported only on JSON file sources.
### 2. Per-Cycle Certificate Pinning & 401 Rotation Retry
- `refreshAccessToken()` snapshots the `KeyStore` from `X509Provider` at
the start of each refresh cycle, creating a cycle-isolated
`MtlsHttpTransportFactory` passed to the STS exchange.
- On 401 Unauthorized from STS, `refreshAccessToken()` re-reads a fresh
`KeyStore` from `x509Provider` and retries the exchange once (preserving
original error context via `addSuppressed` if cert reload fails).
- Relaxed mTLS endpoint validation to check for `.mtls.` to support
custom universes and PSC endpoints.
### 3. Serialization & Binary Backward Compatibility
- **SUID Compatibility**: Preserved
`FileIdentityPoolSubjectTokenSupplier` class name and declared static
`serialVersionUID = 7152208690659890358L;`, matching the synthetic SUID
generated before this PR to prevent `InvalidClassException` on existing
serialized credentials.
- **Binary ABI Preservation**: Kept `public NetHttpTransport create()`
return type on `MtlsHttpTransportFactory` to preserve binary
compatibility for compiled callers via covariant return typing.
- **Post-Deserialization Usability**: Implemented custom `readObject()`
in `IdentityPoolCredentials` to reconstruct transient `x509Provider` and
`MtlsHttpTransportFactory` from the serialized `credentialSource`,
ensuring `refreshAccessToken()` and `createScoped()` remain fully
functional after deserialization.
- **KeyStore Validation**: `MtlsHttpTransportFactory.hasKeyStore()`
checks `mtlsKeyStore != null && mtlsKeyStore.size() > 0`, ensuring
uninitialized or empty KeyStores are not treated as mTLS-configured.
### 4. API Visibility
- Made `setActorTokenSupplier`, `setActorTokenType`, and
`setX509Provider` package-private on `IdentityPoolCredentials.Builder`
for internal/testing use.
---
## Test Coverage
- **1009 unit tests passing** (`oauth2_http` module).
- **Production Path Tests**: End-to-end tests parsing JSON configs via
`ExternalAccountCredentials.fromStream()` and executing
`refreshAccessToken()`.
- **Serialization Tests**: Verified backward compatibility against
pre-PR serialized byte fixtures and verified token refresh on
deserialized instances.
- **Cert Pinning & Retry Tests**: Verified single-snapshot cert
consistency and 401 cert rotation retries.
- **Google Java Format**: Verified 100% compliance with
`com.spotify.fmt:fmt-maven-plugin:2.25`.
### Manual Testing
- Verified end-to-end execution against live Google STS endpoints, token
exchange with actor tokens over mTLS, scoping, serialization round-trip
with `readObject()` restoration, and multi-cycle refreshes.
- Sample Test App: https://paste.googleplex.com/6209850244726784
- Sanitized Verification Output:
https://paste.googleplex.com/6325994750345216
## 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
See b/542238030 for tracking1 parent 62cd972 commit 1fed6d4
16 files changed
Lines changed: 3376 additions & 49 deletions
File tree
- google-auth-library-java/oauth2_http
- javatests/com/google/auth
- mtls
- oauth2
- java/com/google/auth
- mtls
- oauth2
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
39 | 43 | | |
40 | 44 | | |
| 45 | + | |
41 | 46 | | |
42 | 47 | | |
43 | 48 | | |
| |||
49 | 54 | | |
50 | 55 | | |
51 | 56 | | |
52 | | - | |
53 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
54 | 76 | | |
55 | 77 | | |
56 | 78 | | |
| |||
61 | 83 | | |
62 | 84 | | |
63 | 85 | | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
64 | 121 | | |
65 | 122 | | |
66 | 123 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
432 | 432 | | |
433 | 433 | | |
434 | 434 | | |
| 435 | + | |
435 | 436 | | |
436 | 437 | | |
437 | 438 | | |
| |||
488 | 489 | | |
489 | 490 | | |
490 | 491 | | |
| 492 | + | |
491 | 493 | | |
492 | 494 | | |
493 | 495 | | |
| |||
533 | 535 | | |
534 | 536 | | |
535 | 537 | | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
536 | 554 | | |
537 | 555 | | |
538 | 556 | | |
| |||
543 | 561 | | |
544 | 562 | | |
545 | 563 | | |
546 | | - | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
547 | 567 | | |
548 | 568 | | |
549 | 569 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
| 38 | + | |
36 | 39 | | |
37 | 40 | | |
38 | 41 | | |
39 | | - | |
40 | 42 | | |
41 | 43 | | |
42 | 44 | | |
| 45 | + | |
43 | 46 | | |
44 | 47 | | |
45 | 48 | | |
46 | 49 | | |
47 | 50 | | |
| 51 | + | |
48 | 52 | | |
49 | 53 | | |
50 | | - | |
51 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
52 | 60 | | |
53 | 61 | | |
54 | | - | |
| 62 | + | |
| 63 | + | |
55 | 64 | | |
56 | | - | |
| 65 | + | |
57 | 66 | | |
58 | 67 | | |
59 | 68 | | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | 69 | | |
66 | | - | |
| 70 | + | |
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
70 | 74 | | |
71 | | - | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
72 | 110 | | |
73 | 111 | | |
74 | 112 | | |
75 | 113 | | |
76 | 114 | | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
83 | 122 | | |
| 123 | + | |
| 124 | + | |
84 | 125 | | |
85 | 126 | | |
86 | | - | |
87 | | - | |
88 | | - | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
89 | 146 | | |
90 | 147 | | |
91 | 148 | | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
92 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
93 | 213 | | |
94 | | - | |
95 | | - | |
96 | | - | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
97 | 218 | | |
98 | | - | |
99 | | - | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
100 | 222 | | |
101 | | - | |
102 | 223 | | |
103 | 224 | | |
0 commit comments