Skip to content

Commit 9828a8e

Browse files
authored
feat: Support transport and binding-enforcement MDS parameters. (#1558)
* Support transport and binding-enforcement MDS parameters. * add some tests. * null or empty. * no default value in builder. * use enums to hold possible Transport + BindingEnforcement types * Enum labels + Transport -> AuthTransport. * separate constant with underscore. * add javadocs + getTransport -> getAuthTransport. * add test both params null. * AuthTransport -> GoogleAuthTransport. * add some javadoc. * move javadoc to GoogleAuthTransport javadoc. * clean up comments.
1 parent 1963f0c commit 9828a8e

File tree

2 files changed

+224
-1
lines changed

2 files changed

+224
-1
lines changed

oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,68 @@ public class ComputeEngineCredentials extends GoogleCredentials
109109
static final int MAX_COMPUTE_PING_TRIES = 3;
110110
static final int COMPUTE_PING_CONNECTION_TIMEOUT_MS = 500;
111111

112+
/**
113+
* Experimental Feature.
114+
*
115+
* <p>{@link GoogleAuthTransport} specifies how to authenticate to Google APIs.
116+
*
117+
* <p>Behavior of setting {@link GoogleAuthTransport} / {@link BindingEnforcement}:
118+
*
119+
* <p>MTLS-bound token where binding enforcement depends on IAM policy: MTLS / {}, {} /
120+
* IAM_POLICY, MTLS / IAM_POLICY
121+
*
122+
* <p>MTLS-bound token where bindings are always enforced: {} / ON, MTLS / ON
123+
*
124+
* <p>DirectPath bound token: ALTS / {}
125+
*/
126+
public enum GoogleAuthTransport {
127+
// Authenticating to Google APIs via DirectPath
128+
ALTS("alts"),
129+
// Authenticating to Google APIs via GFE
130+
MTLS("mtls");
131+
132+
private final String label;
133+
134+
private GoogleAuthTransport(String label) {
135+
this.label = label;
136+
}
137+
138+
public String getLabel() {
139+
return label;
140+
}
141+
}
142+
143+
/**
144+
* Experimental Feature.
145+
*
146+
* <p>{@link BindingEnforcement} specifies how binding info in tokens will be enforced.
147+
*
148+
* <p>Behavior of setting {@link GoogleAuthTransport} / {@link BindingEnforcement}:
149+
*
150+
* <p>MTLS-bound token where binding enforcement depends on IAM policy: MTLS / {}, {} /
151+
* IAM_POLICY, MTLS / IAM_POLICY
152+
*
153+
* <p>MTLS-bound token where bindings are always enforced: {} / ON, MTLS / ON
154+
*
155+
* <p>DirectPath bound token: ALTS / {}
156+
*/
157+
public enum BindingEnforcement {
158+
// Binding enforcement will always happen, irrespective of the IAM policy.
159+
ON("on"),
160+
// Binding enforcement will depend on IAM policy.
161+
IAM_POLICY("iam-policy");
162+
163+
private final String label;
164+
165+
private BindingEnforcement(String label) {
166+
this.label = label;
167+
}
168+
169+
public String getLabel() {
170+
return label;
171+
}
172+
}
173+
112174
private static final String METADATA_FLAVOR = "Metadata-Flavor";
113175
private static final String GOOGLE = "Google";
114176
private static final String WINDOWS = "windows";
@@ -122,6 +184,9 @@ public class ComputeEngineCredentials extends GoogleCredentials
122184

123185
private final Collection<String> scopes;
124186

187+
private final GoogleAuthTransport transport;
188+
private final BindingEnforcement bindingEnforcement;
189+
125190
private transient HttpTransportFactory transportFactory;
126191
private transient String serviceAccountEmail;
127192

@@ -152,6 +217,8 @@ private ComputeEngineCredentials(ComputeEngineCredentials.Builder builder) {
152217
scopeList.removeAll(Arrays.asList("", null));
153218
this.scopes = ImmutableSet.<String>copyOf(scopeList);
154219
}
220+
this.transport = builder.getGoogleAuthTransport();
221+
this.bindingEnforcement = builder.getBindingEnforcement();
155222
}
156223

157224
@Override
@@ -191,7 +258,10 @@ public final Collection<String> getScopes() {
191258
}
192259

193260
/**
194-
* If scopes is specified, add "?scopes=comma-separated-list-of-scopes" to the token url.
261+
* If scopes is specified, add "?scopes=comma-separated-list-of-scopes" to the token url. If
262+
* transport is specified, add "?transport=xyz" to the token url; xyz is one of "alts" or "mtls".
263+
* If bindingEnforcement is specified, add "?binding-enforcement=xyz" to the token url; xyz is one
264+
* of "iam-policy" or "on".
195265
*
196266
* @return token url with the given scopes
197267
*/
@@ -200,6 +270,12 @@ String createTokenUrlWithScopes() {
200270
if (!scopes.isEmpty()) {
201271
tokenUrl.set("scopes", Joiner.on(',').join(scopes));
202272
}
273+
if (transport != null) {
274+
tokenUrl.set("transport", transport.getLabel());
275+
}
276+
if (bindingEnforcement != null) {
277+
tokenUrl.set("binding-enforcement", bindingEnforcement.getLabel());
278+
}
203279
return tokenUrl.toString();
204280
}
205281

@@ -643,6 +719,9 @@ public static class Builder extends GoogleCredentials.Builder {
643719
private Collection<String> scopes;
644720
private Collection<String> defaultScopes;
645721

722+
private GoogleAuthTransport transport;
723+
private BindingEnforcement bindingEnforcement;
724+
646725
protected Builder() {
647726
setRefreshMargin(COMPUTE_REFRESH_MARGIN);
648727
setExpirationMargin(COMPUTE_EXPIRATION_MARGIN);
@@ -684,6 +763,28 @@ public Builder setQuotaProjectId(String quotaProjectId) {
684763
return this;
685764
}
686765

766+
/**
767+
* Set the {@code GoogleAuthTransport} type.
768+
*
769+
* @param transport the transport type over which to authenticate to Google APIs
770+
*/
771+
@CanIgnoreReturnValue
772+
public Builder setGoogleAuthTransport(GoogleAuthTransport transport) {
773+
this.transport = transport;
774+
return this;
775+
}
776+
777+
/**
778+
* Set the {@code BindingEnforcement} type.
779+
*
780+
* @param bindingEnforcement the token binding enforcement policy.
781+
*/
782+
@CanIgnoreReturnValue
783+
public Builder setBindingEnforcement(BindingEnforcement bindingEnforcement) {
784+
this.bindingEnforcement = bindingEnforcement;
785+
return this;
786+
}
787+
687788
public HttpTransportFactory getHttpTransportFactory() {
688789
return transportFactory;
689790
}
@@ -696,6 +797,24 @@ public Collection<String> getDefaultScopes() {
696797
return defaultScopes;
697798
}
698799

800+
/**
801+
* Get the {@code GoogleAuthTransport} type.
802+
*
803+
* @return the transport type over which to authenticate to Google APIs
804+
*/
805+
public GoogleAuthTransport getGoogleAuthTransport() {
806+
return transport;
807+
}
808+
809+
/**
810+
* Get the {@code BindingEnforcement} type.
811+
*
812+
* @return the token binding enforcement policy.
813+
*/
814+
public BindingEnforcement getBindingEnforcement() {
815+
return bindingEnforcement;
816+
}
817+
699818
@Override
700819
public ComputeEngineCredentials build() {
701820
return new ComputeEngineCredentials(this);

oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,110 @@ public void buildTokenUrlWithScopes_defaultScopes() {
190190
assertEquals("bar", scopes.toArray()[1]);
191191
}
192192

193+
@Test
194+
public void buildTokenUrl_nullTransport() {
195+
ComputeEngineCredentials credentials =
196+
ComputeEngineCredentials.newBuilder()
197+
.setGoogleAuthTransport(null)
198+
.setBindingEnforcement(ComputeEngineCredentials.BindingEnforcement.ON)
199+
.build();
200+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
201+
202+
assertEquals(TOKEN_URL + "?binding-enforcement=on", softBoundTokenUrl);
203+
}
204+
205+
@Test
206+
public void buildTokenUrl_nullBindingEnforcement() {
207+
ComputeEngineCredentials credentials =
208+
ComputeEngineCredentials.newBuilder()
209+
.setGoogleAuthTransport(ComputeEngineCredentials.GoogleAuthTransport.MTLS)
210+
.setBindingEnforcement(null)
211+
.build();
212+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
213+
214+
assertEquals(TOKEN_URL + "?transport=mtls", softBoundTokenUrl);
215+
}
216+
217+
@Test
218+
public void buildTokenUrl_nullTransport_nullBindingEnforcement() {
219+
ComputeEngineCredentials credentials =
220+
ComputeEngineCredentials.newBuilder()
221+
.setGoogleAuthTransport(null)
222+
.setBindingEnforcement(null)
223+
.build();
224+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
225+
226+
assertEquals(TOKEN_URL, softBoundTokenUrl);
227+
}
228+
229+
@Test
230+
public void buildTokenUrlSoftMtlsBound_mtls_transport() {
231+
ComputeEngineCredentials credentials =
232+
ComputeEngineCredentials.newBuilder()
233+
.setGoogleAuthTransport(ComputeEngineCredentials.GoogleAuthTransport.MTLS)
234+
.build();
235+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
236+
237+
assertEquals(TOKEN_URL + "?transport=mtls", softBoundTokenUrl);
238+
}
239+
240+
@Test
241+
public void buildTokenUrlSoftMtlsBound_iam_enforcement() {
242+
ComputeEngineCredentials credentials =
243+
ComputeEngineCredentials.newBuilder()
244+
.setBindingEnforcement(ComputeEngineCredentials.BindingEnforcement.IAM_POLICY)
245+
.build();
246+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
247+
248+
assertEquals(TOKEN_URL + "?binding-enforcement=iam-policy", softBoundTokenUrl);
249+
}
250+
251+
@Test
252+
public void buildTokenUrlSoftMtlsBound_mtls_transport_iam_enforcement() {
253+
ComputeEngineCredentials credentials =
254+
ComputeEngineCredentials.newBuilder()
255+
.setGoogleAuthTransport(ComputeEngineCredentials.GoogleAuthTransport.MTLS)
256+
.setBindingEnforcement(ComputeEngineCredentials.BindingEnforcement.IAM_POLICY)
257+
.build();
258+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
259+
260+
assertEquals(TOKEN_URL + "?transport=mtls&binding-enforcement=iam-policy", softBoundTokenUrl);
261+
}
262+
263+
@Test
264+
public void buildTokenUrlHardMtlsBound_always_enforced() {
265+
ComputeEngineCredentials credentials =
266+
ComputeEngineCredentials.newBuilder()
267+
.setBindingEnforcement(ComputeEngineCredentials.BindingEnforcement.ON)
268+
.build();
269+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
270+
271+
assertEquals(TOKEN_URL + "?binding-enforcement=on", softBoundTokenUrl);
272+
}
273+
274+
@Test
275+
public void buildTokenUrlHardMtlsBound_mtls_transport_always_enforced() {
276+
ComputeEngineCredentials credentials =
277+
ComputeEngineCredentials.newBuilder()
278+
.setGoogleAuthTransport(ComputeEngineCredentials.GoogleAuthTransport.MTLS)
279+
.setBindingEnforcement(ComputeEngineCredentials.BindingEnforcement.ON)
280+
.build();
281+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
282+
283+
assertEquals(TOKEN_URL + "?transport=mtls&binding-enforcement=on", softBoundTokenUrl);
284+
}
285+
286+
@Test
287+
public void buildTokenUrlHardDirectPathBound_alts_transport() {
288+
ComputeEngineCredentials credentials =
289+
ComputeEngineCredentials.newBuilder()
290+
.setGoogleAuthTransport(ComputeEngineCredentials.GoogleAuthTransport.ALTS)
291+
.build();
292+
String softBoundTokenUrl = credentials.createTokenUrlWithScopes();
293+
294+
assertEquals(TOKEN_URL + "?transport=alts", softBoundTokenUrl);
295+
}
296+
193297
@Test
194298
public void buildScoped_scopesPresent() throws IOException {
195299
ComputeEngineCredentials credentials =

0 commit comments

Comments
 (0)