Skip to content

Commit 0044eca

Browse files
committed
Regional Access Boundaries
1 parent 4cb170d commit 0044eca

File tree

43 files changed

+6309
-32
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+6309
-32
lines changed

changes.diff

Lines changed: 3373 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.google.api.client.http.HttpStatusCodes;
4242
import com.google.api.client.json.JsonObjectParser;
4343
import com.google.api.client.util.GenericData;
44+
import com.google.api.core.InternalApi;
4445
import com.google.auth.CredentialTypeForMetrics;
4546
import com.google.auth.Credentials;
4647
import com.google.auth.Retryable;
@@ -80,7 +81,7 @@
8081
* <p>These credentials use the IAM API to sign data. See {@link #sign(byte[])} for more details.
8182
*/
8283
public class ComputeEngineCredentials extends GoogleCredentials
83-
implements ServiceAccountSigner, IdTokenProvider {
84+
implements ServiceAccountSigner, IdTokenProvider, RegionalAccessBoundaryProvider {
8485

8586
static final String METADATA_RESPONSE_EMPTY_CONTENT_ERROR_MESSAGE =
8687
"Empty content from metadata token server request.";
@@ -454,7 +455,6 @@ public AccessToken refreshAccessToken() throws IOException {
454455
int expiresInSeconds =
455456
OAuth2Utils.validateInt32(responseData, "expires_in", PARSE_ERROR_PREFIX);
456457
long expiresAtMilliseconds = clock.currentTimeMillis() + expiresInSeconds * 1000;
457-
458458
return new AccessToken(accessToken, new Date(expiresAtMilliseconds));
459459
}
460460

@@ -779,6 +779,11 @@ public static Builder newBuilder() {
779779
*
780780
* @throws RuntimeException if the default service account cannot be read
781781
*/
782+
@Override
783+
HttpTransportFactory getTransportFactory() {
784+
return transportFactory;
785+
}
786+
782787
@Override
783788
// todo(#314) getAccount should not throw a RuntimeException
784789
public String getAccount() {
@@ -792,6 +797,13 @@ public String getAccount() {
792797
return principal;
793798
}
794799

800+
@InternalApi
801+
@Override
802+
public String getRegionalAccessBoundaryUrl() throws IOException {
803+
return String.format(
804+
OAuth2Utils.IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_SERVICE_ACCOUNT, getAccount());
805+
}
806+
795807
/**
796808
* Signs the provided bytes using the private key associated with the service account.
797809
*

google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentials.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131

3232
package com.google.auth.oauth2;
3333

34+
import static com.google.auth.oauth2.OAuth2Utils.IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_WORKFORCE_POOL;
3435
import static com.google.auth.oauth2.OAuth2Utils.JSON_FACTORY;
36+
import static com.google.auth.oauth2.OAuth2Utils.WORKFORCE_AUDIENCE_PATTERN;
3537

3638
import com.google.api.client.http.GenericUrl;
3739
import com.google.api.client.http.HttpHeaders;
@@ -43,6 +45,7 @@
4345
import com.google.api.client.json.JsonObjectParser;
4446
import com.google.api.client.util.GenericData;
4547
import com.google.api.client.util.Preconditions;
48+
import com.google.api.core.InternalApi;
4649
import com.google.auth.http.HttpTransportFactory;
4750
import com.google.common.base.MoreObjects;
4851
import com.google.common.io.BaseEncoding;
@@ -54,6 +57,7 @@
5457
import java.util.Date;
5558
import java.util.Map;
5659
import java.util.Objects;
60+
import java.util.regex.Matcher;
5761
import javax.annotation.Nullable;
5862

5963
/**
@@ -74,7 +78,8 @@
7478
* }
7579
* </pre>
7680
*/
77-
public class ExternalAccountAuthorizedUserCredentials extends GoogleCredentials {
81+
public class ExternalAccountAuthorizedUserCredentials extends GoogleCredentials
82+
implements RegionalAccessBoundaryProvider {
7883
private static final LoggerProvider LOGGER_PROVIDER =
7984
LoggerProvider.forClazz(ExternalAccountAuthorizedUserCredentials.class);
8085

@@ -229,6 +234,24 @@ public AccessToken refreshAccessToken() throws IOException {
229234
.build();
230235
}
231236

237+
@InternalApi
238+
@Override
239+
public String getRegionalAccessBoundaryUrl() throws IOException {
240+
Matcher matcher = WORKFORCE_AUDIENCE_PATTERN.matcher(getAudience());
241+
if (!matcher.matches()) {
242+
throw new IllegalStateException(
243+
"The provided audience is not in the correct format for a workforce pool. "
244+
+ "Refer: https://docs.cloud.google.com/iam/docs/principal-identifiers");
245+
}
246+
String poolId = matcher.group("pool");
247+
return String.format(IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_WORKFORCE_POOL, poolId);
248+
}
249+
250+
@Override
251+
HttpTransportFactory getTransportFactory() {
252+
return transportFactory;
253+
}
254+
232255
@Nullable
233256
public String getAudience() {
234257
return audience;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
diff a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentials.java (rejected hunks)
2+
@@ -31,7 +31,9 @@
3+
4+
package com.google.auth.oauth2;
5+
6+
+import static com.google.auth.oauth2.OAuth2Utils.IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_WORKFORCE_POOL;
7+
import static com.google.auth.oauth2.OAuth2Utils.JSON_FACTORY;
8+
+import static com.google.auth.oauth2.OAuth2Utils.WORKFORCE_AUDIENCE_PATTERN;
9+
import static com.google.common.base.Preconditions.checkNotNull;
10+
11+
import com.google.api.client.http.GenericUrl;
12+
@@ -75,12 +79,12 @@
13+
* }
14+
* </pre>
15+
*/
16+
-public class ExternalAccountAuthorizedUserCredentials extends GoogleCredentials {
17+
+public class ExternalAccountAuthorizedUserCredentials extends GoogleCredentials
18+
+ implements RegionalAccessBoundaryProvider {
19+
20+
private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. ";
21+
22+
private static final long serialVersionUID = -2181779590486283287L;
23+
-
24+
private final String transportFactoryClassName;
25+
private final String audience;
26+
private final String tokenUrl;

google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
package com.google.auth.oauth2;
3333

34+
import static com.google.auth.oauth2.OAuth2Utils.WORKFORCE_AUDIENCE_PATTERN;
35+
import static com.google.auth.oauth2.OAuth2Utils.WORKLOAD_AUDIENCE_PATTERN;
3436
import static com.google.common.base.Preconditions.checkNotNull;
3537

3638
import com.google.api.client.http.HttpHeaders;
@@ -55,6 +57,7 @@
5557
import java.util.Locale;
5658
import java.util.Map;
5759
import java.util.concurrent.Executor;
60+
import java.util.regex.Matcher;
5861
import java.util.regex.Pattern;
5962
import javax.annotation.Nullable;
6063

@@ -64,7 +67,8 @@
6467
* <p>Handles initializing external credentials, calls to the Security Token Service, and service
6568
* account impersonation.
6669
*/
67-
public abstract class ExternalAccountCredentials extends GoogleCredentials {
70+
public abstract class ExternalAccountCredentials extends GoogleCredentials
71+
implements RegionalAccessBoundaryProvider {
6872

6973
private static final long serialVersionUID = 8049126194174465023L;
7074

@@ -581,6 +585,11 @@ protected AccessToken exchangeExternalCredentialForAccessToken(
581585
*/
582586
public abstract String retrieveSubjectToken() throws IOException;
583587

588+
@Override
589+
HttpTransportFactory getTransportFactory() {
590+
return transportFactory;
591+
}
592+
584593
public String getAudience() {
585594
return audience;
586595
}
@@ -624,6 +633,37 @@ public String getServiceAccountEmail() {
624633
return ImpersonatedCredentials.extractTargetPrincipal(serviceAccountImpersonationUrl);
625634
}
626635

636+
@InternalApi
637+
@Override
638+
public String getRegionalAccessBoundaryUrl() throws IOException {
639+
if (getServiceAccountEmail() != null) {
640+
return String.format(
641+
OAuth2Utils.IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_SERVICE_ACCOUNT,
642+
getServiceAccountEmail());
643+
}
644+
645+
Matcher workforceMatcher = WORKFORCE_AUDIENCE_PATTERN.matcher(getAudience());
646+
if (workforceMatcher.matches()) {
647+
String poolId = workforceMatcher.group("pool");
648+
return String.format(
649+
OAuth2Utils.IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_WORKFORCE_POOL, poolId);
650+
}
651+
652+
Matcher workloadMatcher = WORKLOAD_AUDIENCE_PATTERN.matcher(getAudience());
653+
if (workloadMatcher.matches()) {
654+
String projectNumber = workloadMatcher.group("project");
655+
String poolId = workloadMatcher.group("pool");
656+
return String.format(
657+
OAuth2Utils.IAM_CREDENTIALS_ALLOWED_LOCATIONS_URL_FORMAT_WORKLOAD_POOL,
658+
projectNumber,
659+
poolId);
660+
}
661+
662+
throw new IllegalStateException(
663+
"The provided audience is not in a valid format for either a workload identity pool or a workforce pool."
664+
+ " Refer: https://docs.cloud.google.com/iam/docs/principal-identifiers");
665+
}
666+
627667
@Nullable
628668
public String getClientId() {
629669
return clientId;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
diff a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java (rejected hunks)
2+
@@ -31,12 +31,15 @@
3+
4+
package com.google.auth.oauth2;
5+
6+
+import static com.google.auth.oauth2.OAuth2Utils.WORKFORCE_AUDIENCE_PATTERN;
7+
+import static com.google.auth.oauth2.OAuth2Utils.WORKLOAD_AUDIENCE_PATTERN;
8+
import static com.google.common.base.Preconditions.checkNotNull;
9+
10+
import com.google.api.client.http.HttpHeaders;
11+
import com.google.api.client.json.GenericJson;
12+
import com.google.api.client.json.JsonObjectParser;
13+
import com.google.api.client.util.Data;
14+
+import com.google.api.core.InternalApi;
15+
import com.google.auth.RequestMetadataCallback;
16+
import com.google.auth.http.HttpTransportFactory;
17+
import com.google.common.base.MoreObjects;

0 commit comments

Comments
 (0)