diff --git a/cab-token-generator/java/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactory.java b/cab-token-generator/java/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactory.java new file mode 100644 index 000000000..3b5745acc --- /dev/null +++ b/cab-token-generator/java/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactory.java @@ -0,0 +1,767 @@ +/* + * Copyright 2025, Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.google.auth.credentialaccessboundary; + +import static com.google.auth.oauth2.OAuth2Credentials.getFromServiceLoader; +import static com.google.auth.oauth2.OAuth2Utils.TOKEN_EXCHANGE_URL_FORMAT; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.client.util.Clock; +import com.google.auth.Credentials; +import com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto.ClientSideAccessBoundary; +import com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto.ClientSideAccessBoundaryRule; +import com.google.auth.http.HttpTransportFactory; +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.CredentialAccessBoundary; +import com.google.auth.oauth2.CredentialAccessBoundary.AccessBoundaryRule; +import com.google.auth.oauth2.DownscopedCredentials; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.auth.oauth2.OAuth2CredentialsWithRefresh; +import com.google.auth.oauth2.OAuth2Utils; +import com.google.auth.oauth2.StsRequestHandler; +import com.google.auth.oauth2.StsTokenExchangeRequest; +import com.google.auth.oauth2.StsTokenExchangeResponse; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; +import com.google.common.util.concurrent.AbstractFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListenableFutureTask; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.crypto.tink.Aead; +import com.google.crypto.tink.InsecureSecretKeyAccess; +import com.google.crypto.tink.KeysetHandle; +import com.google.crypto.tink.RegistryConfiguration; +import com.google.crypto.tink.TinkProtoKeysetFormat; +import com.google.crypto.tink.aead.AeadConfig; +import com.google.errorprone.annotations.CanIgnoreReturnValue; +import dev.cel.common.CelAbstractSyntaxTree; +import dev.cel.common.CelOptions; +import dev.cel.common.CelProtoAbstractSyntaxTree; +import dev.cel.common.CelValidationException; +import dev.cel.compiler.CelCompiler; +import dev.cel.compiler.CelCompilerFactory; +import dev.cel.expr.Expr; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.time.Duration; +import java.util.Base64; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; +import javax.annotation.Nullable; + +/** + * A factory for generating downscoped access tokens using a client-side approach. + * + *
Downscoped tokens enable the ability to downscope, or restrict, the Identity and Access + * Management (IAM) permissions that a short-lived credential can use for accessing Google Cloud + * Storage. This factory allows clients to efficiently generate multiple downscoped tokens locally, + * minimizing calls to the Security Token Service (STS). This client-side approach is particularly + * beneficial when Credential Access Boundary rules change frequently or when many unique downscoped + * tokens are required. For scenarios where rules change infrequently or a single downscoped + * credential is reused many times, the server-side approach using {@link DownscopedCredentials} is + * more appropriate. + * + *
To downscope permissions you must define a {@link CredentialAccessBoundary} which specifies + * the upper bound of permissions that the credential can access. You must also provide a source + * credential which will be used to acquire the downscoped credential. + * + *
The factory can be configured with options such as the {@code refreshMargin} and {@code + * minimumTokenLifetime}. The {@code refreshMargin} controls how far in advance of the underlying + * credentials' expiry a refresh is attempted. The {@code minimumTokenLifetime} ensures that + * generated tokens have a minimum usable lifespan. See the {@link Builder} class for more details + * on these options. + * + *
Usage: + * + *
+ * GoogleCredentials sourceCredentials = GoogleCredentials.getApplicationDefault()
+ * .createScoped("https://www.googleapis.com/auth/cloud-platform");
+ *
+ * ClientSideCredentialAccessBoundaryFactory factory =
+ * ClientSideCredentialAccessBoundaryFactory.newBuilder()
+ * .setSourceCredential(sourceCredentials)
+ * .build();
+ *
+ * CredentialAccessBoundary.AccessBoundaryRule rule =
+ * CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
+ * .setAvailableResource(
+ * "//storage.googleapis.com/projects/_/buckets/bucket")
+ * .addAvailablePermission("inRole:roles/storage.objectViewer")
+ * .build();
+ *
+ * CredentialAccessBoundary credentialAccessBoundary =
+ * CredentialAccessBoundary.newBuilder().addRule(rule).build();
+ *
+ * AccessToken downscopedAccessToken = factory.generateToken(credentialAccessBoundary);
+ *
+ * OAuth2Credentials credentials = OAuth2Credentials.create(downscopedAccessToken);
+ *
+ * Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
+ *
+ * Blob blob = storage.get(BlobId.of("bucket", "object"));
+ * System.out.printf("Blob %s retrieved.", blob.getBlobId());
+ *
+ *
+ * Note that {@link OAuth2CredentialsWithRefresh} can instead be used to consume the downscoped
+ * token, allowing for automatic token refreshes by providing a {@link
+ * OAuth2CredentialsWithRefresh.OAuth2RefreshHandler}.
+ */
+public class ClientSideCredentialAccessBoundaryFactory {
+ static final Duration DEFAULT_REFRESH_MARGIN = Duration.ofMinutes(45);
+ static final Duration DEFAULT_MINIMUM_TOKEN_LIFETIME = Duration.ofMinutes(30);
+ private final GoogleCredentials sourceCredential;
+ private final transient HttpTransportFactory transportFactory;
+ private final String tokenExchangeEndpoint;
+ private final Duration minimumTokenLifetime;
+ private final Duration refreshMargin;
+ private RefreshTask refreshTask;
+ private final Object refreshLock = new byte[0];
+ private IntermediateCredentials intermediateCredentials = null;
+ private final Clock clock;
+ private final CelCompiler celCompiler;
+
+ enum RefreshType {
+ NONE,
+ ASYNC,
+ BLOCKING
+ }
+
+ private ClientSideCredentialAccessBoundaryFactory(Builder builder) {
+ this.transportFactory = builder.transportFactory;
+ this.sourceCredential = builder.sourceCredential;
+ this.tokenExchangeEndpoint = builder.tokenExchangeEndpoint;
+ this.refreshMargin = builder.refreshMargin;
+ this.minimumTokenLifetime = builder.minimumTokenLifetime;
+ this.clock = builder.clock;
+
+ // Initializes the Tink AEAD registry for encrypting the client-side restrictions.
+ try {
+ AeadConfig.register();
+ } catch (GeneralSecurityException e) {
+ throw new IllegalStateException("Error occurred when registering Tink", e);
+ }
+
+ CelOptions options = CelOptions.current().build();
+ this.celCompiler = CelCompilerFactory.standardCelCompilerBuilder().setOptions(options).build();
+ }
+
+ /**
+ * Generates a downscoped access token given the {@link CredentialAccessBoundary}.
+ *
+ * @param accessBoundary The credential access boundary that defines the restrictions for the
+ * generated CAB token.
+ * @return The downscoped access token in an {@link AccessToken} object
+ * @throws IOException If an I/O error occurs while refreshing the source credentials
+ * @throws CelValidationException If the availability condition is an invalid CEL expression
+ * @throws GeneralSecurityException If an error occurs during encryption
+ */
+ public AccessToken generateToken(CredentialAccessBoundary accessBoundary)
+ throws IOException, CelValidationException, GeneralSecurityException {
+ this.refreshCredentialsIfRequired();
+
+ String intermediateToken;
+ String sessionKey;
+ Date intermediateTokenExpirationTime;
+
+ synchronized (refreshLock) {
+ intermediateToken = this.intermediateCredentials.intermediateAccessToken.getTokenValue();
+ intermediateTokenExpirationTime =
+ this.intermediateCredentials.intermediateAccessToken.getExpirationTime();
+ sessionKey = this.intermediateCredentials.accessBoundarySessionKey;
+ }
+
+ byte[] rawRestrictions = this.serializeCredentialAccessBoundary(accessBoundary);
+
+ byte[] encryptedRestrictions = this.encryptRestrictions(rawRestrictions, sessionKey);
+
+ String tokenValue =
+ intermediateToken + "." + Base64.getUrlEncoder().encodeToString(encryptedRestrictions);
+
+ return new AccessToken(tokenValue, intermediateTokenExpirationTime);
+ }
+
+ /**
+ * Refreshes the intermediate access token and access boundary session key if required.
+ *
+ * This method checks the expiration time of the current intermediate access token and + * initiates a refresh if necessary. The refresh process also refreshes the underlying source + * credentials. + * + * @throws IOException If an error occurs during the refresh process, such as network issues, + * invalid credentials, or problems with the token exchange endpoint. + */ + @VisibleForTesting + void refreshCredentialsIfRequired() throws IOException { + RefreshType refreshType = determineRefreshType(); + + if (refreshType == RefreshType.NONE) { + // No refresh needed, token is still valid. + return; + } + + // If a refresh is required, create or retrieve the refresh task. + RefreshTask currentRefreshTask = getOrCreateRefreshTask(); + + // Handle the refresh based on the determined refresh type. + switch (refreshType) { + case BLOCKING: + if (currentRefreshTask.isNew) { + // Start a new refresh task only if the task is new. + MoreExecutors.directExecutor().execute(currentRefreshTask.task); + } + try { + // Wait for the refresh task to complete. + currentRefreshTask.task.get(); + } catch (InterruptedException e) { + // Restore the interrupted status and throw an exception. + Thread.currentThread().interrupt(); + throw new IOException( + "Interrupted while asynchronously refreshing the intermediate credentials", e); + } catch (ExecutionException e) { + // Unwrap the underlying cause of the execution exception. + Throwable cause = e.getCause(); + if (cause instanceof IOException) { + throw (IOException) cause; + } else if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else { + // Wrap other exceptions in an IOException. + throw new IOException("Unexpected error refreshing intermediate credentials", cause); + } + } + break; + case ASYNC: + if (currentRefreshTask.isNew) { + // Starts a new background thread for the refresh task if it's a new task. + // We create a new thread because the Auth Library doesn't currently include a background + // executor. Introducing an executor would add complexity in managing its lifecycle and + // could potentially lead to memory leaks. + // We limit the number of concurrent refresh threads to 1, so the overhead of creating new + // threads for asynchronous calls should be acceptable. + new Thread(currentRefreshTask.task).start(); + } // (No else needed - if not new, another thread is handling the refresh) + break; + default: + // This should not happen unless RefreshType enum is extended and this method is not + // updated. + throw new IllegalStateException("Unexpected refresh type: " + refreshType); + } + } + + private RefreshType determineRefreshType() { + AccessToken intermediateAccessToken; + synchronized (refreshLock) { + if (intermediateCredentials == null + || intermediateCredentials.intermediateAccessToken == null) { + // A blocking refresh is needed if the intermediate access token doesn't exist. + return RefreshType.BLOCKING; + } + intermediateAccessToken = intermediateCredentials.intermediateAccessToken; + } + + Date expirationTime = intermediateAccessToken.getExpirationTime(); + if (expirationTime == null) { + // Token does not expire, no refresh needed. + return RefreshType.NONE; + } + + Duration remaining = Duration.ofMillis(expirationTime.getTime() - clock.currentTimeMillis()); + + if (remaining.compareTo(minimumTokenLifetime) <= 0) { + // Intermediate token has expired or remaining lifetime is less than the minimum required + // for CAB token generation. A blocking refresh is necessary. + return RefreshType.BLOCKING; + } else if (remaining.compareTo(refreshMargin) <= 0) { + // The token is nearing expiration, an async refresh is needed. + return RefreshType.ASYNC; + } + // Token is still fresh, no refresh needed. + return RefreshType.NONE; + } + + /** + * Atomically creates a single flight refresh task. + * + *
Only a single refresh task can be scheduled at a time. If there is an existing task, it will
+ * be returned for subsequent invocations. However, if a new task is created, it is the
+ * responsibility of the caller to execute it. The task will clear the single flight slot upon
+ * completion.
+ */
+ private RefreshTask getOrCreateRefreshTask() {
+ synchronized (refreshLock) {
+ if (refreshTask != null) {
+ // An existing refresh task is already in progress. Return a NEW RefreshTask instance with
+ // the existing task, but set isNew to false. This indicates to the caller that a new
+ // refresh task was NOT created.
+ return new RefreshTask(refreshTask.task, false);
+ }
+
+ final ListenableFutureTask The source credential is refreshed, and a token exchange request is made to the STS endpoint
+ * to obtain an intermediate access token and an associated access boundary session key. This
+ * ensures the intermediate access token meets this factory's refresh margin and minimum lifetime
+ * requirements.
+ *
+ * @return The fetched {@link IntermediateCredentials} containing the intermediate access token
+ * and access boundary session key.
+ * @throws IOException If an error occurs during credential refresh or token exchange.
+ */
+ @VisibleForTesting
+ IntermediateCredentials fetchIntermediateCredentials() throws IOException {
+ try {
+ // Force a refresh on the source credentials. The intermediate token's lifetime is tied to the
+ // source credential's expiration. The factory's refreshMargin might be different from the
+ // refreshMargin on source credentials. This ensures the intermediate access token
+ // meets this factory's refresh margin and minimum lifetime requirements.
+ sourceCredential.refresh();
+ } catch (IOException e) {
+ throw new IOException("Unable to refresh the provided source credential.", e);
+ }
+
+ AccessToken sourceAccessToken = sourceCredential.getAccessToken();
+ if (sourceAccessToken == null || Strings.isNullOrEmpty(sourceAccessToken.getTokenValue())) {
+ throw new IllegalStateException("The source credential does not have an access token.");
+ }
+
+ StsTokenExchangeRequest request =
+ StsTokenExchangeRequest.newBuilder(
+ sourceAccessToken.getTokenValue(), OAuth2Utils.TOKEN_TYPE_ACCESS_TOKEN)
+ .setRequestTokenType(OAuth2Utils.TOKEN_TYPE_ACCESS_BOUNDARY_INTERMEDIARY_TOKEN)
+ .build();
+
+ StsRequestHandler handler =
+ StsRequestHandler.newBuilder(
+ tokenExchangeEndpoint, request, transportFactory.create().createRequestFactory())
+ .build();
+
+ StsTokenExchangeResponse response = handler.exchangeToken();
+ return new IntermediateCredentials(
+ getTokenFromResponse(response, sourceAccessToken), response.getAccessBoundarySessionKey());
+ }
+
+ /**
+ * Extracts the access token from the STS exchange response and sets the appropriate expiration
+ * time.
+ *
+ * @param response The STS token exchange response.
+ * @param sourceAccessToken The original access token used for the exchange.
+ * @return The intermediate access token.
+ */
+ private static AccessToken getTokenFromResponse(
+ StsTokenExchangeResponse response, AccessToken sourceAccessToken) {
+ AccessToken intermediateToken = response.getAccessToken();
+
+ // The STS endpoint will only return the expiration time for the intermediate token
+ // if the original access token represents a service account.
+ // The intermediate token's expiration time will always match the source credential expiration.
+ // When no expires_in is returned, we can copy the source credential's expiration time.
+ if (intermediateToken.getExpirationTime() == null
+ && sourceAccessToken.getExpirationTime() != null) {
+ return new AccessToken(
+ intermediateToken.getTokenValue(), sourceAccessToken.getExpirationTime());
+ }
+
+ // Return original if no modification needed.
+ return intermediateToken;
+ }
+
+ /**
+ * Completes the refresh task by storing the results and clearing the single flight slot.
+ *
+ * This method is called when a refresh task finishes. It stores the refreshed credentials if
+ * successful. The single-flight "slot" is cleared, allowing subsequent refresh attempts. Any
+ * exceptions during the refresh are caught and suppressed to prevent indefinite blocking of
+ * subsequent refresh attempts.
+ */
+ private void finishRefreshTask(ListenableFuture These credentials include an intermediate access token and an access boundary session key.
+ */
+ @VisibleForTesting
+ static class IntermediateCredentials {
+ private final AccessToken intermediateAccessToken;
+ private final String accessBoundarySessionKey;
+
+ IntermediateCredentials(AccessToken accessToken, String accessBoundarySessionKey) {
+ this.intermediateAccessToken = accessToken;
+ this.accessBoundarySessionKey = accessBoundarySessionKey;
+ }
+
+ String getAccessBoundarySessionKey() {
+ return accessBoundarySessionKey;
+ }
+
+ AccessToken getIntermediateAccessToken() {
+ return intermediateAccessToken;
+ }
+ }
+
+ /**
+ * Represents a task for refreshing intermediate credentials, ensuring that only one refresh
+ * operation is in progress at a time.
+ *
+ * The {@code isNew} flag indicates whether this is a newly initiated refresh operation or an
+ * existing one already in progress. This distinction is used to prevent redundant refreshes.
+ */
+ class RefreshTask extends AbstractFuture Use this builder to create instances of {@code ClientSideCredentialAccessBoundaryFactory}
+ * with the desired configuration options.
+ */
+ public static class Builder {
+ private GoogleCredentials sourceCredential;
+ private HttpTransportFactory transportFactory;
+ private String universeDomain;
+ private String tokenExchangeEndpoint;
+ private Duration minimumTokenLifetime;
+ private Duration refreshMargin;
+ private Clock clock = Clock.SYSTEM; // Default to system clock;
+
+ private Builder() {}
+
+ /**
+ * Sets the required source credential.
+ *
+ * @param sourceCredential the {@code GoogleCredentials} to set. This is a
+ * required parameter.
+ * @return this {@code Builder} object for chaining.
+ * @throws NullPointerException if {@code sourceCredential} is {@code null}.
+ */
+ @CanIgnoreReturnValue
+ public Builder setSourceCredential(GoogleCredentials sourceCredential) {
+ checkNotNull(sourceCredential, "Source credential must not be null.");
+ this.sourceCredential = sourceCredential;
+ return this;
+ }
+
+ /**
+ * Sets the minimum acceptable lifetime for a generated downscoped access token.
+ *
+ * This parameter ensures that any generated downscoped access token has a minimum validity
+ * period. If the time remaining before the underlying credentials expire is less than this
+ * value, the factory will perform a blocking refresh, meaning that it will wait until the
+ * credentials are refreshed before generating a new downscoped token. This guarantees that the
+ * generated token will be valid for at least {@code minimumTokenLifetime}. A reasonable value
+ * should be chosen based on the expected duration of operations using the downscoped token. If
+ * not set, the default value is defined by {@link #DEFAULT_MINIMUM_TOKEN_LIFETIME}.
+ *
+ * @param minimumTokenLifetime The minimum acceptable lifetime for a generated downscoped access
+ * token. Must be greater than zero.
+ * @return This {@code Builder} object.
+ * @throws IllegalArgumentException if {@code minimumTokenLifetime} is negative or zero.
+ */
+ @CanIgnoreReturnValue
+ public Builder setMinimumTokenLifetime(Duration minimumTokenLifetime) {
+ checkNotNull(minimumTokenLifetime, "Minimum token lifetime must not be null.");
+ if (minimumTokenLifetime.isNegative() || minimumTokenLifetime.isZero()) {
+ throw new IllegalArgumentException("Minimum token lifetime must be greater than zero.");
+ }
+ this.minimumTokenLifetime = minimumTokenLifetime;
+ return this;
+ }
+
+ /**
+ * Sets the refresh margin for the underlying credentials.
+ *
+ * This duration specifies how far in advance of the credentials' expiration time an
+ * asynchronous refresh should be initiated. This refresh happens in the background, without
+ * blocking the main thread. If not provided, it will default to the value defined by {@link
+ * #DEFAULT_REFRESH_MARGIN}.
+ *
+ * Note: The {@code refreshMargin} must be at least one minute longer than the {@code
+ * minimumTokenLifetime}.
+ *
+ * @param refreshMargin The refresh margin. Must be greater than zero.
+ * @return This {@code Builder} object.
+ * @throws IllegalArgumentException if {@code refreshMargin} is negative or zero.
+ */
+ @CanIgnoreReturnValue
+ public Builder setRefreshMargin(Duration refreshMargin) {
+ checkNotNull(refreshMargin, "Refresh margin must not be null.");
+ if (refreshMargin.isNegative() || refreshMargin.isZero()) {
+ throw new IllegalArgumentException("Refresh margin must be greater than zero.");
+ }
+ this.refreshMargin = refreshMargin;
+ return this;
+ }
+
+ /**
+ * Sets the HTTP transport factory.
+ *
+ * @param transportFactory the {@code HttpTransportFactory} to set
+ * @return this {@code Builder} object
+ */
+ @CanIgnoreReturnValue
+ public Builder setHttpTransportFactory(HttpTransportFactory transportFactory) {
+ this.transportFactory = transportFactory;
+ return this;
+ }
+
+ /**
+ * Sets the optional universe domain.
+ *
+ * @param universeDomain the universe domain to set
+ * @return this {@code Builder} object
+ */
+ @CanIgnoreReturnValue
+ public Builder setUniverseDomain(String universeDomain) {
+ this.universeDomain = universeDomain;
+ return this;
+ }
+
+ /**
+ * Set the clock for checking token expiry. Used for testing.
+ *
+ * @param clock the clock to use. Defaults to the system clock
+ * @return the builder
+ */
+ public Builder setClock(Clock clock) {
+ this.clock = clock;
+ return this;
+ }
+
+ /**
+ * Creates a new {@code ClientSideCredentialAccessBoundaryFactory} instance based on the current
+ * builder configuration.
+ *
+ * @return A new {@code ClientSideCredentialAccessBoundaryFactory} instance.
+ * @throws IllegalStateException if the builder is not properly configured (e.g., if the source
+ * credential is not set).
+ * @throws IllegalArgumentException if the refresh margin is not at least one minute longer than
+ * the minimum token lifetime.
+ */
+ public ClientSideCredentialAccessBoundaryFactory build() {
+ checkNotNull(sourceCredential, "Source credential must not be null.");
+
+ // Use the default HTTP transport factory if none was provided.
+ if (transportFactory == null) {
+ this.transportFactory =
+ getFromServiceLoader(HttpTransportFactory.class, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
+ }
+
+ // Default to GDU when not supplied.
+ if (Strings.isNullOrEmpty(universeDomain)) {
+ this.universeDomain = Credentials.GOOGLE_DEFAULT_UNIVERSE;
+ }
+
+ // Ensure source credential's universe domain matches.
+ try {
+ if (!universeDomain.equals(sourceCredential.getUniverseDomain())) {
+ throw new IllegalArgumentException(
+ "The client side access boundary credential's universe domain must be the same as the source "
+ + "credential.");
+ }
+ } catch (IOException e) {
+ // Throwing an IOException would be a breaking change, so wrap it here.
+ throw new IllegalStateException(
+ "Error occurred when attempting to retrieve source credential universe domain.", e);
+ }
+
+ // Use default values for refreshMargin if not provided.
+ if (refreshMargin == null) {
+ this.refreshMargin = DEFAULT_REFRESH_MARGIN;
+ }
+
+ // Use default values for minimumTokenLifetime if not provided.
+ if (minimumTokenLifetime == null) {
+ this.minimumTokenLifetime = DEFAULT_MINIMUM_TOKEN_LIFETIME;
+ }
+
+ // Check if refreshMargin is at least one minute longer than minimumTokenLifetime.
+ Duration minRefreshMargin = minimumTokenLifetime.plusMinutes(1);
+ if (refreshMargin.compareTo(minRefreshMargin) < 0) {
+ throw new IllegalArgumentException(
+ "Refresh margin must be at least one minute longer than the minimum token lifetime.");
+ }
+
+ this.tokenExchangeEndpoint = String.format(TOKEN_EXCHANGE_URL_FORMAT, universeDomain);
+ return new ClientSideCredentialAccessBoundaryFactory(this);
+ }
+ }
+}
diff --git a/cab-token-generator/java/com/google/auth/credentialaccessboundary/protobuf/ClientSideAccessBoundaryProto.java b/cab-token-generator/java/com/google/auth/credentialaccessboundary/protobuf/ClientSideAccessBoundaryProto.java
new file mode 100644
index 000000000..7a26c73c8
--- /dev/null
+++ b/cab-token-generator/java/com/google/auth/credentialaccessboundary/protobuf/ClientSideAccessBoundaryProto.java
@@ -0,0 +1,2174 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: client_side_access_boundary.proto
+
+// Protobuf Java Version: 3.25.5
+package com.google.auth.credentialaccessboundary.protobuf;
+
+public final class ClientSideAccessBoundaryProto {
+ private ClientSideAccessBoundaryProto() {}
+
+ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {}
+
+ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
+ registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry);
+ }
+
+ public interface ClientSideAccessBoundaryRuleOrBuilder
+ extends
+ // @@protoc_insertion_point(interface_extends:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule)
+ com.google.protobuf.MessageOrBuilder {
+
+ /**
+ * The only requirements for this test suite to run is to set the environment variable
+ * GOOGLE_APPLICATION_CREDENTIALS to point to the same service account configured in the setup
+ * script (downscoping-with-cab-setup.sh).
+ */
+public final class ITClientSideCredentialAccessBoundaryTest {
+
+ // Output copied from the setup script (downscoping-with-cab-setup.sh).
+ private static final String GCS_BUCKET_NAME = "cab-int-bucket-cbi3qrv5";
+ private static final String GCS_OBJECT_NAME_WITH_PERMISSION = "cab-first-cbi3qrv5.txt";
+ private static final String GCS_OBJECT_NAME_WITHOUT_PERMISSION = "cab-second-cbi3qrv5.txt";
+
+ // This Credential Access Boundary enables the objectViewer permission to the specified object in
+ // the specified bucket.
+ private static final CredentialAccessBoundary CREDENTIAL_ACCESS_BOUNDARY =
+ CredentialAccessBoundary.newBuilder()
+ .addRule(
+ CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
+ .setAvailableResource(
+ String.format(
+ "//storage.googleapis.com/projects/_/buckets/%s", GCS_BUCKET_NAME))
+ .addAvailablePermission("inRole:roles/storage.objectViewer")
+ .setAvailabilityCondition(
+ CredentialAccessBoundary.AccessBoundaryRule.AvailabilityCondition.newBuilder()
+ .setExpression(
+ String.format(
+ "resource.name.startsWith('projects/_/buckets/%s/objects/%s')",
+ GCS_BUCKET_NAME, GCS_OBJECT_NAME_WITH_PERMISSION))
+ .build())
+ .build())
+ .build();
+
+ /**
+ * A downscoped credential is obtained using ClientSideCredentialAccessBoundaryFactory with
+ * permissions to access an object in the GCS bucket configured. We should only have access to
+ * retrieve this object.
+ *
+ * We confirm this by: 1. Validating that we can successfully retrieve this object with the
+ * downscoped token. 2. Validating that we do not have permission to retrieve a different object
+ * in the same bucket.
+ */
+ @Test
+ public void clientSideCredentialAccessBoundary_serviceAccountSource() throws IOException {
+ OAuth2CredentialsWithRefresh.OAuth2RefreshHandler refreshHandler =
+ () -> {
+ ServiceAccountCredentials sourceCredentials =
+ (ServiceAccountCredentials)
+ GoogleCredentials.getApplicationDefault()
+ .createScoped("https://www.googleapis.com/auth/cloud-platform");
+
+ ClientSideCredentialAccessBoundaryFactory factory =
+ ClientSideCredentialAccessBoundaryFactory.newBuilder()
+ .setSourceCredential(sourceCredentials)
+ .build();
+
+ try {
+ return factory.generateToken(CREDENTIAL_ACCESS_BOUNDARY);
+ } catch (CelValidationException | GeneralSecurityException e) {
+ throw new RuntimeException(e);
+ }
+ };
+
+ OAuth2CredentialsWithRefresh credentials =
+ OAuth2CredentialsWithRefresh.newBuilder().setRefreshHandler(refreshHandler).build();
+
+ // Attempt to retrieve the object that the downscoped token has access to.
+ retrieveObjectFromGcs(credentials, GCS_OBJECT_NAME_WITH_PERMISSION);
+
+ // Attempt to retrieve the object that the downscoped token does not have access to. This should
+ // fail.
+ HttpResponseException exception =
+ assertThrows(
+ HttpResponseException.class,
+ () -> retrieveObjectFromGcs(credentials, GCS_OBJECT_NAME_WITHOUT_PERMISSION));
+ assertEquals(403, exception.getStatusCode());
+ }
+
+ private void retrieveObjectFromGcs(Credentials credentials, String objectName)
+ throws IOException {
+ String url =
+ String.format(
+ "https://storage.googleapis.com/storage/v1/b/%s/o/%s", GCS_BUCKET_NAME, objectName);
+
+ HttpCredentialsAdapter credentialsAdapter = new HttpCredentialsAdapter(credentials);
+ HttpRequestFactory requestFactory =
+ new NetHttpTransport().createRequestFactory(credentialsAdapter);
+ HttpRequest request = requestFactory.buildGetRequest(new GenericUrl(url));
+
+ JsonObjectParser parser = new JsonObjectParser(GsonFactory.getDefaultInstance());
+ request.setParser(parser);
+
+ HttpResponse response = request.execute();
+ assertTrue(response.isSuccessStatusCode());
+ }
+}
diff --git a/cab-token-generator/pom.xml b/cab-token-generator/pom.xml
new file mode 100644
index 000000000..4a3c3b0ff
--- /dev/null
+++ b/cab-token-generator/pom.xml
@@ -0,0 +1,86 @@
+
+ This class provides a server-side approach for generating downscoped tokens, suitable for
+ * situations where Credential Access Boundary rules change infrequently or a single downscoped
+ * credential is reused many times. For scenarios where rules change frequently, or you need to
+ * generate many unique downscoped tokens, the client-side approach using {@code
+ * com.google.auth.credentialaccessboundary.ClientSideCredentialAccessBoundaryFactory} is more
+ * efficient.
+ *
* To downscope permissions you must define a {@link CredentialAccessBoundary} which specifies
* the upper bound of permissions that the credential can access. You must also provide a source
* credential which will be used to acquire the downscoped credential.
@@ -88,7 +96,6 @@
*/
public final class DownscopedCredentials extends OAuth2Credentials {
- private final String TOKEN_EXCHANGE_URL_FORMAT = "https://sts.{universe_domain}/v1/token";
private final GoogleCredentials sourceCredential;
private final CredentialAccessBoundary credentialAccessBoundary;
private final String universeDomain;
@@ -125,8 +132,7 @@ private DownscopedCredentials(Builder builder) {
throw new IllegalStateException(
"Error occurred when attempting to retrieve source credential universe domain.", e);
}
- this.tokenExchangeEndpoint =
- TOKEN_EXCHANGE_URL_FORMAT.replace("{universe_domain}", universeDomain);
+ this.tokenExchangeEndpoint = String.format(TOKEN_EXCHANGE_URL_FORMAT, universeDomain);
}
@Override
diff --git a/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java b/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
index 20e1c92e5..3d569b02f 100644
--- a/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
@@ -484,7 +484,16 @@ protected static These classes are marked public but should be treated effectively as internal classes only.
+ * They are not subject to any backwards compatibility guarantees and might change or be removed at
+ * any time. They are provided only as a convenience for other libraries within the {@code
+ * com.google.auth} family. Application developers should avoid using these classes directly; they
+ * are not part of the public API.
+ */
+public class OAuth2Utils {
+
static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
- static final String TOKEN_TYPE_ACCESS_TOKEN = "urn:ietf:params:oauth:token-type:access_token";
+ public static final String TOKEN_TYPE_ACCESS_TOKEN =
+ "urn:ietf:params:oauth:token-type:access_token";
static final String TOKEN_TYPE_TOKEN_EXCHANGE = "urn:ietf:params:oauth:token-type:token-exchange";
+ public static final String TOKEN_TYPE_ACCESS_BOUNDARY_INTERMEDIARY_TOKEN =
+ "urn:ietf:params:oauth:token-type:access_boundary_intermediary_token";
static final String GRANT_TYPE_JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
+ public static final String TOKEN_EXCHANGE_URL_FORMAT = "https://sts.%s/v1/token";
static final URI TOKEN_SERVER_URI = URI.create("https://oauth2.googleapis.com/token");
static final URI TOKEN_REVOKE_URI = URI.create("https://oauth2.googleapis.com/revoke");
@@ -84,7 +97,8 @@ class OAuth2Utils {
static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
- static final HttpTransportFactory HTTP_TRANSPORT_FACTORY = new DefaultHttpTransportFactory();
+ public static final HttpTransportFactory HTTP_TRANSPORT_FACTORY =
+ new DefaultHttpTransportFactory();
static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
@@ -241,8 +255,15 @@ static Map This class handles the process of exchanging one type of token for another using the Security
+ * Token Service (STS). It constructs and sends the token exchange request to the STS endpoint and
+ * parses the response to create an {@link StsTokenExchangeResponse} object.
+ *
+ * Use the {@link #newBuilder(String, StsTokenExchangeRequest, HttpRequestFactory)} method to
+ * create a new builder for constructing an instance of this class.
+ */
+public final class StsRequestHandler {
private static final String TOKEN_EXCHANGE_GRANT_TYPE =
"urn:ietf:params:oauth:grant-type:token-exchange";
private static final String PARSE_ERROR_PREFIX = "Error parsing token response.";
@@ -85,6 +95,14 @@ private StsRequestHandler(
this.internalOptions = internalOptions;
}
+ /**
+ * Returns a new builder for creating an instance of {@link StsRequestHandler}.
+ *
+ * @param tokenExchangeEndpoint The STS token exchange endpoint.
+ * @param stsTokenExchangeRequest The STS token exchange request.
+ * @param httpRequestFactory The HTTP request factory to use for sending the request.
+ * @return A new builder instance.
+ */
public static Builder newBuilder(
String tokenExchangeEndpoint,
StsTokenExchangeRequest stsTokenExchangeRequest,
@@ -175,6 +193,11 @@ private StsTokenExchangeResponse buildResponse(GenericData responseData) throws
String scope = OAuth2Utils.validateString(responseData, "scope", PARSE_ERROR_PREFIX);
builder.setScopes(Arrays.asList(scope.trim().split("\\s+")));
}
+ if (responseData.containsKey("access_boundary_session_key")) {
+ builder.setAccessBoundarySessionKey(
+ OAuth2Utils.validateString(
+ responseData, "access_boundary_session_key", PARSE_ERROR_PREFIX));
+ }
return builder.build();
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeRequest.java b/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeRequest.java
index a231fe383..f0ce390ed 100644
--- a/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeRequest.java
+++ b/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeRequest.java
@@ -38,10 +38,18 @@
import javax.annotation.Nullable;
/**
- * Defines an OAuth 2.0 token exchange request. Based on
- * https://tools.ietf.org/html/rfc8693#section-2.1.
+ * Represents an OAuth 2.0 token exchange request, as defined in RFC 8693, Section 2.1.
+ *
+ * This class encapsulates the parameters necessary for making a token exchange request to Google
+ * Security Token Service (STS). It includes the subject token, subject token type, optional
+ * parameters like acting party, scopes, resource, audience, requested token type, and internal
+ * options.
+ *
+ * Instances of this class are immutable. Use the {@link #newBuilder(String, String)} method to
+ * create a new builder.
*/
-final class StsTokenExchangeRequest {
+public final class StsTokenExchangeRequest {
private static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange";
private final String subjectToken;
@@ -73,6 +81,15 @@ private StsTokenExchangeRequest(
this.internalOptions = internalOptions;
}
+ /**
+ * Returns a new {@link StsTokenExchangeRequest.Builder} instance.
+ *
+ * @param subjectToken The token being exchanged. This represents the credentials being used to
+ * authorize the token exchange request.
+ * @param subjectTokenType The type of the {@code subjectToken}. For example, {@link
+ * OAuth2Utils#TOKEN_TYPE_ACCESS_TOKEN}.
+ * @return A new builder for creating {@code StsTokenExchangeRequest} instances.
+ */
public static Builder newBuilder(String subjectToken, String subjectTokenType) {
return new Builder(subjectToken, subjectTokenType);
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeResponse.java b/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeResponse.java
index 90a94e16d..62275778a 100644
--- a/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeResponse.java
+++ b/oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeResponse.java
@@ -40,10 +40,18 @@
import javax.annotation.Nullable;
/**
- * Defines an OAuth 2.0 token exchange successful response. Based on
- * https://tools.ietf.org/html/rfc8693#section-2.2.1.
+ * Represents a successful OAuth 2.0 token exchange response from the Google Security Token Service
+ * (STS), as defined in RFC 8693,
+ * Section 2.2.1.
+ *
+ * This class provides access to the exchanged access token, issued token type, token type,
+ * expiration time, refresh token (optional), scopes (optional), and the access boundary session key
+ * (optional).
+ *
+ * Instances are immutable. Use {@link #newBuilder(String, String, String)} to create an
+ * instance.
*/
-final class StsTokenExchangeResponse {
+public final class StsTokenExchangeResponse {
private final AccessToken accessToken;
private final String issuedTokenType;
private final String tokenType;
@@ -51,6 +59,7 @@ final class StsTokenExchangeResponse {
@Nullable private final Long expiresInSeconds;
@Nullable private final String refreshToken;
@Nullable private final Liststring available_resource = 1;
+ *
+ * @return The availableResource.
+ */
+ java.lang.String getAvailableResource();
+ /**
+ * string available_resource = 1;
+ *
+ * @return The bytes for availableResource.
+ */
+ com.google.protobuf.ByteString getAvailableResourceBytes();
+
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @return A list containing the availablePermissions.
+ */
+ java.util.Listrepeated string available_permissions = 2;
+ *
+ * @return The count of availablePermissions.
+ */
+ int getAvailablePermissionsCount();
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index of the element to return.
+ * @return The availablePermissions at the given index.
+ */
+ java.lang.String getAvailablePermissions(int index);
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index of the value to return.
+ * @return The bytes of the availablePermissions at the given index.
+ */
+ com.google.protobuf.ByteString getAvailablePermissionsBytes(int index);
+
+ /**
+ * .cel.expr.Expr compiled_availability_condition = 4;
+ *
+ * @return Whether the compiledAvailabilityCondition field is set.
+ */
+ boolean hasCompiledAvailabilityCondition();
+ /**
+ * .cel.expr.Expr compiled_availability_condition = 4;
+ *
+ * @return The compiledAvailabilityCondition.
+ */
+ dev.cel.expr.Expr getCompiledAvailabilityCondition();
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ dev.cel.expr.ExprOrBuilder getCompiledAvailabilityConditionOrBuilder();
+ }
+ /**
+ * Protobuf type {@code
+ * com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule}
+ */
+ public static final class ClientSideAccessBoundaryRule
+ extends com.google.protobuf.GeneratedMessageV3
+ implements
+ // @@protoc_insertion_point(message_implements:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule)
+ ClientSideAccessBoundaryRuleOrBuilder {
+ private static final long serialVersionUID = 0L;
+ // Use ClientSideAccessBoundaryRule.newBuilder() to construct.
+ private ClientSideAccessBoundaryRule(
+ com.google.protobuf.GeneratedMessageV3.Builder> builder) {
+ super(builder);
+ }
+
+ private ClientSideAccessBoundaryRule() {
+ availableResource_ = "";
+ availablePermissions_ = com.google.protobuf.LazyStringArrayList.emptyList();
+ }
+
+ @java.lang.Override
+ @SuppressWarnings({"unused"})
+ protected java.lang.Object newInstance(UnusedPrivateParameter unused) {
+ return new ClientSideAccessBoundaryRule();
+ }
+
+ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+ return com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .internal_static_com_google_auth_credentialaccessboundary_proto_ClientSideAccessBoundaryRule_descriptor;
+ }
+
+ @java.lang.Override
+ protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .internal_static_com_google_auth_credentialaccessboundary_proto_ClientSideAccessBoundaryRule_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.class,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder.class);
+ }
+
+ private int bitField0_;
+ public static final int AVAILABLE_RESOURCE_FIELD_NUMBER = 1;
+
+ @SuppressWarnings("serial")
+ private volatile java.lang.Object availableResource_ = "";
+ /**
+ * string available_resource = 1;
+ *
+ * @return The availableResource.
+ */
+ @java.lang.Override
+ public java.lang.String getAvailableResource() {
+ java.lang.Object ref = availableResource_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ availableResource_ = s;
+ return s;
+ }
+ }
+ /**
+ * string available_resource = 1;
+ *
+ * @return The bytes for availableResource.
+ */
+ @java.lang.Override
+ public com.google.protobuf.ByteString getAvailableResourceBytes() {
+ java.lang.Object ref = availableResource_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref);
+ availableResource_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
+ public static final int AVAILABLE_PERMISSIONS_FIELD_NUMBER = 2;
+
+ @SuppressWarnings("serial")
+ private com.google.protobuf.LazyStringArrayList availablePermissions_ =
+ com.google.protobuf.LazyStringArrayList.emptyList();
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @return A list containing the availablePermissions.
+ */
+ public com.google.protobuf.ProtocolStringList getAvailablePermissionsList() {
+ return availablePermissions_;
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @return The count of availablePermissions.
+ */
+ public int getAvailablePermissionsCount() {
+ return availablePermissions_.size();
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index of the element to return.
+ * @return The availablePermissions at the given index.
+ */
+ public java.lang.String getAvailablePermissions(int index) {
+ return availablePermissions_.get(index);
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index of the value to return.
+ * @return The bytes of the availablePermissions at the given index.
+ */
+ public com.google.protobuf.ByteString getAvailablePermissionsBytes(int index) {
+ return availablePermissions_.getByteString(index);
+ }
+
+ public static final int COMPILED_AVAILABILITY_CONDITION_FIELD_NUMBER = 4;
+ private dev.cel.expr.Expr compiledAvailabilityCondition_;
+ /**
+ * .cel.expr.Expr compiled_availability_condition = 4;
+ *
+ * @return Whether the compiledAvailabilityCondition field is set.
+ */
+ @java.lang.Override
+ public boolean hasCompiledAvailabilityCondition() {
+ return ((bitField0_ & 0x00000001) != 0);
+ }
+ /**
+ * .cel.expr.Expr compiled_availability_condition = 4;
+ *
+ * @return The compiledAvailabilityCondition.
+ */
+ @java.lang.Override
+ public dev.cel.expr.Expr getCompiledAvailabilityCondition() {
+ return compiledAvailabilityCondition_ == null
+ ? dev.cel.expr.Expr.getDefaultInstance()
+ : compiledAvailabilityCondition_;
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ @java.lang.Override
+ public dev.cel.expr.ExprOrBuilder getCompiledAvailabilityConditionOrBuilder() {
+ return compiledAvailabilityCondition_ == null
+ ? dev.cel.expr.Expr.getDefaultInstance()
+ : compiledAvailabilityCondition_;
+ }
+
+ private byte memoizedIsInitialized = -1;
+
+ @java.lang.Override
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized == 1) return true;
+ if (isInitialized == 0) return false;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ @java.lang.Override
+ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+ if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(availableResource_)) {
+ com.google.protobuf.GeneratedMessageV3.writeString(output, 1, availableResource_);
+ }
+ for (int i = 0; i < availablePermissions_.size(); i++) {
+ com.google.protobuf.GeneratedMessageV3.writeString(
+ output, 2, availablePermissions_.getRaw(i));
+ }
+ if (((bitField0_ & 0x00000001) != 0)) {
+ output.writeMessage(4, getCompiledAvailabilityCondition());
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ @java.lang.Override
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(availableResource_)) {
+ size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, availableResource_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < availablePermissions_.size(); i++) {
+ dataSize += computeStringSizeNoTag(availablePermissions_.getRaw(i));
+ }
+ size += dataSize;
+ size += 1 * getAvailablePermissionsList().size();
+ }
+ if (((bitField0_ & 0x00000001) != 0)) {
+ size +=
+ com.google.protobuf.CodedOutputStream.computeMessageSize(
+ 4, getCompiledAvailabilityCondition());
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSize = size;
+ return size;
+ }
+
+ @java.lang.Override
+ public boolean equals(final java.lang.Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj
+ instanceof
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule)) {
+ return super.equals(obj);
+ }
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ other =
+ (com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule)
+ obj;
+
+ if (!getAvailableResource().equals(other.getAvailableResource())) return false;
+ if (!getAvailablePermissionsList().equals(other.getAvailablePermissionsList())) return false;
+ if (hasCompiledAvailabilityCondition() != other.hasCompiledAvailabilityCondition())
+ return false;
+ if (hasCompiledAvailabilityCondition()) {
+ if (!getCompiledAvailabilityCondition().equals(other.getCompiledAvailabilityCondition()))
+ return false;
+ }
+ if (!getUnknownFields().equals(other.getUnknownFields())) return false;
+ return true;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ if (memoizedHashCode != 0) {
+ return memoizedHashCode;
+ }
+ int hash = 41;
+ hash = (19 * hash) + getDescriptor().hashCode();
+ hash = (37 * hash) + AVAILABLE_RESOURCE_FIELD_NUMBER;
+ hash = (53 * hash) + getAvailableResource().hashCode();
+ if (getAvailablePermissionsCount() > 0) {
+ hash = (37 * hash) + AVAILABLE_PERMISSIONS_FIELD_NUMBER;
+ hash = (53 * hash) + getAvailablePermissionsList().hashCode();
+ }
+ if (hasCompiledAvailabilityCondition()) {
+ hash = (37 * hash) + COMPILED_AVAILABILITY_CONDITION_FIELD_NUMBER;
+ hash = (53 * hash) + getCompiledAvailabilityCondition().hashCode();
+ }
+ hash = (29 * hash) + getUnknownFields().hashCode();
+ memoizedHashCode = hash;
+ return hash;
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(java.nio.ByteBuffer data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(
+ java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(java.io.InputStream input) throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(
+ java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(
+ PARSER, input, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseDelimitedFrom(
+ java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(
+ PARSER, input, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(com.google.protobuf.CodedInputStream input) throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(
+ PARSER, input, extensionRegistry);
+ }
+
+ @java.lang.Override
+ public Builder newBuilderForType() {
+ return newBuilder();
+ }
+
+ public static Builder newBuilder() {
+ return DEFAULT_INSTANCE.toBuilder();
+ }
+
+ public static Builder newBuilder(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ prototype) {
+ return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+ }
+
+ @java.lang.Override
+ public Builder toBuilder() {
+ return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this);
+ }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code
+ * com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule}
+ */
+ public static final class Builder
+ extends com.google.protobuf.GeneratedMessageV3.Builderstring available_resource = 1;
+ *
+ * @return The availableResource.
+ */
+ public java.lang.String getAvailableResource() {
+ java.lang.Object ref = availableResource_;
+ if (!(ref instanceof java.lang.String)) {
+ com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ availableResource_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * string available_resource = 1;
+ *
+ * @return The bytes for availableResource.
+ */
+ public com.google.protobuf.ByteString getAvailableResourceBytes() {
+ java.lang.Object ref = availableResource_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref);
+ availableResource_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * string available_resource = 1;
+ *
+ * @param value The availableResource to set.
+ * @return This builder for chaining.
+ */
+ public Builder setAvailableResource(java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ availableResource_ = value;
+ bitField0_ |= 0x00000001;
+ onChanged();
+ return this;
+ }
+ /**
+ * string available_resource = 1;
+ *
+ * @return This builder for chaining.
+ */
+ public Builder clearAvailableResource() {
+ availableResource_ = getDefaultInstance().getAvailableResource();
+ bitField0_ = (bitField0_ & ~0x00000001);
+ onChanged();
+ return this;
+ }
+ /**
+ * string available_resource = 1;
+ *
+ * @param value The bytes for availableResource to set.
+ * @return This builder for chaining.
+ */
+ public Builder setAvailableResourceBytes(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ checkByteStringIsUtf8(value);
+ availableResource_ = value;
+ bitField0_ |= 0x00000001;
+ onChanged();
+ return this;
+ }
+
+ private com.google.protobuf.LazyStringArrayList availablePermissions_ =
+ com.google.protobuf.LazyStringArrayList.emptyList();
+
+ private void ensureAvailablePermissionsIsMutable() {
+ if (!availablePermissions_.isModifiable()) {
+ availablePermissions_ =
+ new com.google.protobuf.LazyStringArrayList(availablePermissions_);
+ }
+ bitField0_ |= 0x00000002;
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @return A list containing the availablePermissions.
+ */
+ public com.google.protobuf.ProtocolStringList getAvailablePermissionsList() {
+ availablePermissions_.makeImmutable();
+ return availablePermissions_;
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @return The count of availablePermissions.
+ */
+ public int getAvailablePermissionsCount() {
+ return availablePermissions_.size();
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index of the element to return.
+ * @return The availablePermissions at the given index.
+ */
+ public java.lang.String getAvailablePermissions(int index) {
+ return availablePermissions_.get(index);
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index of the value to return.
+ * @return The bytes of the availablePermissions at the given index.
+ */
+ public com.google.protobuf.ByteString getAvailablePermissionsBytes(int index) {
+ return availablePermissions_.getByteString(index);
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param index The index to set the value at.
+ * @param value The availablePermissions to set.
+ * @return This builder for chaining.
+ */
+ public Builder setAvailablePermissions(int index, java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureAvailablePermissionsIsMutable();
+ availablePermissions_.set(index, value);
+ bitField0_ |= 0x00000002;
+ onChanged();
+ return this;
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param value The availablePermissions to add.
+ * @return This builder for chaining.
+ */
+ public Builder addAvailablePermissions(java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureAvailablePermissionsIsMutable();
+ availablePermissions_.add(value);
+ bitField0_ |= 0x00000002;
+ onChanged();
+ return this;
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param values The availablePermissions to add.
+ * @return This builder for chaining.
+ */
+ public Builder addAllAvailablePermissions(java.lang.Iterablerepeated string available_permissions = 2;
+ *
+ * @return This builder for chaining.
+ */
+ public Builder clearAvailablePermissions() {
+ availablePermissions_ = com.google.protobuf.LazyStringArrayList.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000002);
+ ;
+ onChanged();
+ return this;
+ }
+ /**
+ * repeated string available_permissions = 2;
+ *
+ * @param value The bytes of the availablePermissions to add.
+ * @return This builder for chaining.
+ */
+ public Builder addAvailablePermissionsBytes(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ checkByteStringIsUtf8(value);
+ ensureAvailablePermissionsIsMutable();
+ availablePermissions_.add(value);
+ bitField0_ |= 0x00000002;
+ onChanged();
+ return this;
+ }
+
+ private dev.cel.expr.Expr compiledAvailabilityCondition_;
+ private com.google.protobuf.SingleFieldBuilderV3<
+ dev.cel.expr.Expr, dev.cel.expr.Expr.Builder, dev.cel.expr.ExprOrBuilder>
+ compiledAvailabilityConditionBuilder_;
+ /**
+ * .cel.expr.Expr compiled_availability_condition = 4;
+ *
+ * @return Whether the compiledAvailabilityCondition field is set.
+ */
+ public boolean hasCompiledAvailabilityCondition() {
+ return ((bitField0_ & 0x00000004) != 0);
+ }
+ /**
+ * .cel.expr.Expr compiled_availability_condition = 4;
+ *
+ * @return The compiledAvailabilityCondition.
+ */
+ public dev.cel.expr.Expr getCompiledAvailabilityCondition() {
+ if (compiledAvailabilityConditionBuilder_ == null) {
+ return compiledAvailabilityCondition_ == null
+ ? dev.cel.expr.Expr.getDefaultInstance()
+ : compiledAvailabilityCondition_;
+ } else {
+ return compiledAvailabilityConditionBuilder_.getMessage();
+ }
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ public Builder setCompiledAvailabilityCondition(dev.cel.expr.Expr value) {
+ if (compiledAvailabilityConditionBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ compiledAvailabilityCondition_ = value;
+ } else {
+ compiledAvailabilityConditionBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000004;
+ onChanged();
+ return this;
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ public Builder setCompiledAvailabilityCondition(dev.cel.expr.Expr.Builder builderForValue) {
+ if (compiledAvailabilityConditionBuilder_ == null) {
+ compiledAvailabilityCondition_ = builderForValue.build();
+ } else {
+ compiledAvailabilityConditionBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000004;
+ onChanged();
+ return this;
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ public Builder mergeCompiledAvailabilityCondition(dev.cel.expr.Expr value) {
+ if (compiledAvailabilityConditionBuilder_ == null) {
+ if (((bitField0_ & 0x00000004) != 0)
+ && compiledAvailabilityCondition_ != null
+ && compiledAvailabilityCondition_ != dev.cel.expr.Expr.getDefaultInstance()) {
+ getCompiledAvailabilityConditionBuilder().mergeFrom(value);
+ } else {
+ compiledAvailabilityCondition_ = value;
+ }
+ } else {
+ compiledAvailabilityConditionBuilder_.mergeFrom(value);
+ }
+ if (compiledAvailabilityCondition_ != null) {
+ bitField0_ |= 0x00000004;
+ onChanged();
+ }
+ return this;
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ public Builder clearCompiledAvailabilityCondition() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ compiledAvailabilityCondition_ = null;
+ if (compiledAvailabilityConditionBuilder_ != null) {
+ compiledAvailabilityConditionBuilder_.dispose();
+ compiledAvailabilityConditionBuilder_ = null;
+ }
+ onChanged();
+ return this;
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ public dev.cel.expr.Expr.Builder getCompiledAvailabilityConditionBuilder() {
+ bitField0_ |= 0x00000004;
+ onChanged();
+ return getCompiledAvailabilityConditionFieldBuilder().getBuilder();
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ public dev.cel.expr.ExprOrBuilder getCompiledAvailabilityConditionOrBuilder() {
+ if (compiledAvailabilityConditionBuilder_ != null) {
+ return compiledAvailabilityConditionBuilder_.getMessageOrBuilder();
+ } else {
+ return compiledAvailabilityCondition_ == null
+ ? dev.cel.expr.Expr.getDefaultInstance()
+ : compiledAvailabilityCondition_;
+ }
+ }
+ /** .cel.expr.Expr compiled_availability_condition = 4; */
+ private com.google.protobuf.SingleFieldBuilderV3<
+ dev.cel.expr.Expr, dev.cel.expr.Expr.Builder, dev.cel.expr.ExprOrBuilder>
+ getCompiledAvailabilityConditionFieldBuilder() {
+ if (compiledAvailabilityConditionBuilder_ == null) {
+ compiledAvailabilityConditionBuilder_ =
+ new com.google.protobuf.SingleFieldBuilderV3<
+ dev.cel.expr.Expr, dev.cel.expr.Expr.Builder, dev.cel.expr.ExprOrBuilder>(
+ getCompiledAvailabilityCondition(), getParentForChildren(), isClean());
+ compiledAvailabilityCondition_ = null;
+ }
+ return compiledAvailabilityConditionBuilder_;
+ }
+
+ @java.lang.Override
+ public final Builder setUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.setUnknownFields(unknownFields);
+ }
+
+ @java.lang.Override
+ public final Builder mergeUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.mergeUnknownFields(unknownFields);
+ }
+
+ // @@protoc_insertion_point(builder_scope:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule)
+ }
+
+ // @@protoc_insertion_point(class_scope:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule)
+ private static final com.google.auth.credentialaccessboundary.protobuf
+ .ClientSideAccessBoundaryProto.ClientSideAccessBoundaryRule
+ DEFAULT_INSTANCE;
+
+ static {
+ DEFAULT_INSTANCE =
+ new com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule();
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ getDefaultInstance() {
+ return DEFAULT_INSTANCE;
+ }
+
+ private static final com.google.protobuf.Parser
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ java.util.List<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule>
+ getAccessBoundaryRulesList();
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ getAccessBoundaryRules(int index);
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ int getAccessBoundaryRulesCount();
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ java.util.List<
+ ? extends
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder>
+ getAccessBoundaryRulesOrBuilderList();
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder
+ getAccessBoundaryRulesOrBuilder(int index);
+ }
+ /**
+ * Protobuf type {@code com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundary}
+ */
+ public static final class ClientSideAccessBoundary extends com.google.protobuf.GeneratedMessageV3
+ implements
+ // @@protoc_insertion_point(message_implements:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundary)
+ ClientSideAccessBoundaryOrBuilder {
+ private static final long serialVersionUID = 0L;
+ // Use ClientSideAccessBoundary.newBuilder() to construct.
+ private ClientSideAccessBoundary(com.google.protobuf.GeneratedMessageV3.Builder> builder) {
+ super(builder);
+ }
+
+ private ClientSideAccessBoundary() {
+ accessBoundaryRules_ = java.util.Collections.emptyList();
+ }
+
+ @java.lang.Override
+ @SuppressWarnings({"unused"})
+ protected java.lang.Object newInstance(UnusedPrivateParameter unused) {
+ return new ClientSideAccessBoundary();
+ }
+
+ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+ return com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .internal_static_com_google_auth_credentialaccessboundary_proto_ClientSideAccessBoundary_descriptor;
+ }
+
+ @java.lang.Override
+ protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .internal_static_com_google_auth_credentialaccessboundary_proto_ClientSideAccessBoundary_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary.class,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary.Builder.class);
+ }
+
+ public static final int ACCESS_BOUNDARY_RULES_FIELD_NUMBER = 1;
+
+ @SuppressWarnings("serial")
+ private java.util.List<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule>
+ accessBoundaryRules_;
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ @java.lang.Override
+ public java.util.List<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule>
+ getAccessBoundaryRulesList() {
+ return accessBoundaryRules_;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ @java.lang.Override
+ public java.util.List<
+ ? extends
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder>
+ getAccessBoundaryRulesOrBuilderList() {
+ return accessBoundaryRules_;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ @java.lang.Override
+ public int getAccessBoundaryRulesCount() {
+ return accessBoundaryRules_.size();
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ @java.lang.Override
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ getAccessBoundaryRules(int index) {
+ return accessBoundaryRules_.get(index);
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ @java.lang.Override
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder
+ getAccessBoundaryRulesOrBuilder(int index) {
+ return accessBoundaryRules_.get(index);
+ }
+
+ private byte memoizedIsInitialized = -1;
+
+ @java.lang.Override
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized == 1) return true;
+ if (isInitialized == 0) return false;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ @java.lang.Override
+ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+ for (int i = 0; i < accessBoundaryRules_.size(); i++) {
+ output.writeMessage(1, accessBoundaryRules_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ @java.lang.Override
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ for (int i = 0; i < accessBoundaryRules_.size(); i++) {
+ size +=
+ com.google.protobuf.CodedOutputStream.computeMessageSize(
+ 1, accessBoundaryRules_.get(i));
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSize = size;
+ return size;
+ }
+
+ @java.lang.Override
+ public boolean equals(final java.lang.Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj
+ instanceof
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary)) {
+ return super.equals(obj);
+ }
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ other =
+ (com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary)
+ obj;
+
+ if (!getAccessBoundaryRulesList().equals(other.getAccessBoundaryRulesList())) return false;
+ if (!getUnknownFields().equals(other.getUnknownFields())) return false;
+ return true;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ if (memoizedHashCode != 0) {
+ return memoizedHashCode;
+ }
+ int hash = 41;
+ hash = (19 * hash) + getDescriptor().hashCode();
+ if (getAccessBoundaryRulesCount() > 0) {
+ hash = (37 * hash) + ACCESS_BOUNDARY_RULES_FIELD_NUMBER;
+ hash = (53 * hash) + getAccessBoundaryRulesList().hashCode();
+ }
+ hash = (29 * hash) + getUnknownFields().hashCode();
+ memoizedHashCode = hash;
+ return hash;
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(java.nio.ByteBuffer data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(
+ java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(java.io.InputStream input) throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(
+ java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(
+ PARSER, input, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseDelimitedFrom(
+ java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(
+ PARSER, input, extensionRegistry);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(com.google.protobuf.CodedInputStream input) throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3.parseWithIOException(
+ PARSER, input, extensionRegistry);
+ }
+
+ @java.lang.Override
+ public Builder newBuilderForType() {
+ return newBuilder();
+ }
+
+ public static Builder newBuilder() {
+ return DEFAULT_INSTANCE.toBuilder();
+ }
+
+ public static Builder newBuilder(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ prototype) {
+ return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+ }
+
+ @java.lang.Override
+ public Builder toBuilder() {
+ return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this);
+ }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundary}
+ */
+ public static final class Builder
+ extends com.google.protobuf.GeneratedMessageV3.Builder
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public java.util.List<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule>
+ getAccessBoundaryRulesList() {
+ if (accessBoundaryRulesBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(accessBoundaryRules_);
+ } else {
+ return accessBoundaryRulesBuilder_.getMessageList();
+ }
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public int getAccessBoundaryRulesCount() {
+ if (accessBoundaryRulesBuilder_ == null) {
+ return accessBoundaryRules_.size();
+ } else {
+ return accessBoundaryRulesBuilder_.getCount();
+ }
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ getAccessBoundaryRules(int index) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ return accessBoundaryRules_.get(index);
+ } else {
+ return accessBoundaryRulesBuilder_.getMessage(index);
+ }
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder setAccessBoundaryRules(
+ int index,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ value) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.set(index, value);
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder setAccessBoundaryRules(
+ int index,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder
+ builderForValue) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder addAccessBoundaryRules(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ value) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.add(value);
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder addAccessBoundaryRules(
+ int index,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule
+ value) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.add(index, value);
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder addAccessBoundaryRules(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder
+ builderForValue) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.add(builderForValue.build());
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder addAccessBoundaryRules(
+ int index,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder
+ builderForValue) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder addAllAccessBoundaryRules(
+ java.lang.Iterable<
+ ? extends
+ com.google.auth.credentialaccessboundary.protobuf
+ .ClientSideAccessBoundaryProto.ClientSideAccessBoundaryRule>
+ values) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ ensureAccessBoundaryRulesIsMutable();
+ com.google.protobuf.AbstractMessageLite.Builder.addAll(values, accessBoundaryRules_);
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder clearAccessBoundaryRules() {
+ if (accessBoundaryRulesBuilder_ == null) {
+ accessBoundaryRules_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000001);
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public Builder removeAccessBoundaryRules(int index) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ ensureAccessBoundaryRulesIsMutable();
+ accessBoundaryRules_.remove(index);
+ onChanged();
+ } else {
+ accessBoundaryRulesBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder
+ getAccessBoundaryRulesBuilder(int index) {
+ return getAccessBoundaryRulesFieldBuilder().getBuilder(index);
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder
+ getAccessBoundaryRulesOrBuilder(int index) {
+ if (accessBoundaryRulesBuilder_ == null) {
+ return accessBoundaryRules_.get(index);
+ } else {
+ return accessBoundaryRulesBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public java.util.List<
+ ? extends
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder>
+ getAccessBoundaryRulesOrBuilderList() {
+ if (accessBoundaryRulesBuilder_ != null) {
+ return accessBoundaryRulesBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(accessBoundaryRules_);
+ }
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder
+ addAccessBoundaryRulesBuilder() {
+ return getAccessBoundaryRulesFieldBuilder()
+ .addBuilder(
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.getDefaultInstance());
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder
+ addAccessBoundaryRulesBuilder(int index) {
+ return getAccessBoundaryRulesFieldBuilder()
+ .addBuilder(
+ index,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.getDefaultInstance());
+ }
+ /**
+ *
+ * repeated .com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundaryRule access_boundary_rules = 1;
+ *
+ */
+ public java.util.List<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder>
+ getAccessBoundaryRulesBuilderList() {
+ return getAccessBoundaryRulesFieldBuilder().getBuilderList();
+ }
+
+ private com.google.protobuf.RepeatedFieldBuilderV3<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder>
+ getAccessBoundaryRulesFieldBuilder() {
+ if (accessBoundaryRulesBuilder_ == null) {
+ accessBoundaryRulesBuilder_ =
+ new com.google.protobuf.RepeatedFieldBuilderV3<
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRule.Builder,
+ com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundaryRuleOrBuilder>(
+ accessBoundaryRules_,
+ ((bitField0_ & 0x00000001) != 0),
+ getParentForChildren(),
+ isClean());
+ accessBoundaryRules_ = null;
+ }
+ return accessBoundaryRulesBuilder_;
+ }
+
+ @java.lang.Override
+ public final Builder setUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.setUnknownFields(unknownFields);
+ }
+
+ @java.lang.Override
+ public final Builder mergeUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.mergeUnknownFields(unknownFields);
+ }
+
+ // @@protoc_insertion_point(builder_scope:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundary)
+ }
+
+ // @@protoc_insertion_point(class_scope:com.google.auth.credentialaccessboundary.proto.ClientSideAccessBoundary)
+ private static final com.google.auth.credentialaccessboundary.protobuf
+ .ClientSideAccessBoundaryProto.ClientSideAccessBoundary
+ DEFAULT_INSTANCE;
+
+ static {
+ DEFAULT_INSTANCE =
+ new com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary();
+ }
+
+ public static com.google.auth.credentialaccessboundary.protobuf.ClientSideAccessBoundaryProto
+ .ClientSideAccessBoundary
+ getDefaultInstance() {
+ return DEFAULT_INSTANCE;
+ }
+
+ private static final com.google.protobuf.Parser> scopeSequence = new ArrayDeque<>();
private final Queue