xref: /aosp_15_r20/external/google-auth-library-java/README.md (revision af546375c95127f07cb26dd492629ccb2e8b1be1)
1*af546375SCole Faust# Google Auth Library
2*af546375SCole Faust
3*af546375SCole FaustOpen source authentication client library for Java.
4*af546375SCole Faust
5*af546375SCole Faust[![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges)
6*af546375SCole Faust[![Maven](https://img.shields.io/maven-central/v/com.google.auth/google-auth-library-credentials.svg)](https://img.shields.io/maven-central/v/com.google.auth/google-auth-library-credentials.svg)
7*af546375SCole Faust
8*af546375SCole Faust-  [API Documentation](https://googleapis.dev/java/google-auth-library/latest)
9*af546375SCole Faust
10*af546375SCole FaustThis project consists of 3 artifacts:
11*af546375SCole Faust
12*af546375SCole Faust- [*google-auth-library-credentials*](#google-auth-library-credentials): contains base classes and
13*af546375SCole Faustinterfaces for Google credentials
14*af546375SCole Faust- [*google-auth-library-appengine*](#google-auth-library-appengine): contains App Engine
15*af546375SCole Faustcredentials. This artifact depends on the App Engine SDK.
16*af546375SCole Faust- [*google-auth-library-oauth2-http*](#google-auth-library-oauth2-http): contains a wide variety of
17*af546375SCole Faustcredentials as well as utility methods to create them and to get Application Default Credentials
18*af546375SCole Faust
19*af546375SCole Faust**Table of contents:**
20*af546375SCole Faust
21*af546375SCole Faust
22*af546375SCole Faust* [Quickstart](#quickstart)
23*af546375SCole Faust
24*af546375SCole Faust* [google-auth-library-oauth2-http](#google-auth-library-oauth2-http)
25*af546375SCole Faust  * [Application Default Credentials](#application-default-credentials)
26*af546375SCole Faust  * [ImpersonatedCredentials](#impersonatedcredentials)
27*af546375SCole Faust  * [Workload Identity Federation](#workload-identity-federation)
28*af546375SCole Faust      * [Accessing resources from AWS](#accessing-resources-from-aws)
29*af546375SCole Faust      * [Accessing resources from Azure](#access-resources-from-microsoft-azure)
30*af546375SCole Faust      * [Accessing resources from an OIDC identity provider](#accessing-resources-from-an-oidc-identity-provider)
31*af546375SCole Faust      * [Accessing resources using Executable-sourced credentials](#using-executable-sourced-credentials-with-oidc-and-saml)
32*af546375SCole Faust      * [Configurable Token Lifetime](#configurable-token-lifetime)
33*af546375SCole Faust  * [Workforce Identity Federation](#workforce-identity-federation)
34*af546375SCole Faust      * [Accessing resources using an OIDC or SAML 2.0 identity provider](#accessing-resources-using-an-oidc-or-saml-20-identity-provider)
35*af546375SCole Faust      * [Accessing resources using external account authorized user workforce credentials](#using-external-account-authorized-user-workforce-credentials)
36*af546375SCole Faust      * [Accessing resources using Executable-sourced credentials](#using-executable-sourced-workforce-credentials-with-oidc-and-saml)
37*af546375SCole Faust  * [Downscoping with Credential Access Boundaries](#downscoping-with-credential-access-boundaries)
38*af546375SCole Faust  * [Configuring a Proxy](#configuring-a-proxy)
39*af546375SCole Faust  * [Using Credentials with google-http-client](#using-credentials-with-google-http-client)
40*af546375SCole Faust  * [Verifying JWT Tokens](#verifying-a-signature)
41*af546375SCole Faust* [google-auth-library-credentials](#google-auth-library-credentials)
42*af546375SCole Faust* [google-auth-library-appengine](#google-auth-library-appengine)
43*af546375SCole Faust* [CI Status](#ci-status)
44*af546375SCole Faust* [Contributing](#contributing)
45*af546375SCole Faust* [License](#license)
46*af546375SCole Faust
47*af546375SCole Faust
48*af546375SCole Faust## Quickstart
49*af546375SCole Faust
50*af546375SCole FaustIf you are using Maven, add this to your pom.xml file (notice that you can replace
51*af546375SCole Faust`google-auth-library-oauth2-http` with any of `google-auth-library-credentials` and
52*af546375SCole Faust`google-auth-library-appengine`, depending on your application needs):
53*af546375SCole Faust
54*af546375SCole Faust[//]: # ({x-version-update-start:google-auth-library-oauth2-http:released})
55*af546375SCole Faust
56*af546375SCole Faust```xml
57*af546375SCole Faust<dependency>
58*af546375SCole Faust  <groupId>com.google.auth</groupId>
59*af546375SCole Faust  <artifactId>google-auth-library-oauth2-http</artifactId>
60*af546375SCole Faust  <version>1.19.0</version>
61*af546375SCole Faust</dependency>
62*af546375SCole Faust```
63*af546375SCole Faust[//]: # ({x-version-update-end})
64*af546375SCole Faust
65*af546375SCole Faust
66*af546375SCole FaustIf you are using Gradle, add this to your dependencies
67*af546375SCole Faust
68*af546375SCole Faust[//]: # ({x-version-update-start:google-auth-library-oauth2-http:released})
69*af546375SCole Faust```Groovy
70*af546375SCole Faustimplementation 'com.google.auth:google-auth-library-oauth2-http:1.19.0'
71*af546375SCole Faust```
72*af546375SCole Faust[//]: # ({x-version-update-end})
73*af546375SCole Faust
74*af546375SCole FaustIf you are using SBT, add this to your dependencies
75*af546375SCole Faust
76*af546375SCole Faust[//]: # ({x-version-update-start:google-auth-library-oauth2-http:released})
77*af546375SCole Faust```Scala
78*af546375SCole FaustlibraryDependencies += "com.google.auth" % "google-auth-library-oauth2-http" % "1.19.0"
79*af546375SCole Faust```
80*af546375SCole Faust[//]: # ({x-version-update-end})
81*af546375SCole Faust
82*af546375SCole Faust## google-auth-library-oauth2-http
83*af546375SCole Faust
84*af546375SCole Faust### Application Default Credentials
85*af546375SCole Faust
86*af546375SCole FaustThis library provides an implementation of
87*af546375SCole Faust[Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials)
88*af546375SCole Faustfor Java. Application Default Credentials provide a simple way to get authorization
89*af546375SCole Faustcredentials for use in calling Google APIs.
90*af546375SCole Faust
91*af546375SCole FaustThey are best suited for cases when the call needs to have the same identity and
92*af546375SCole Faustauthorization level for the application independent of the user. This is the recommended
93*af546375SCole Faustapproach to authorize calls to Cloud APIs, particularly when you're building an application
94*af546375SCole Faustthat uses Google Cloud Platform.
95*af546375SCole Faust
96*af546375SCole FaustApplication Default Credentials also support workload identity federation to access
97*af546375SCole FaustGoogle Cloud resources from non-Google Cloud platforms including Amazon Web Services (AWS),
98*af546375SCole FaustMicrosoft Azure or any identity provider that supports OpenID Connect (OIDC). Workload
99*af546375SCole Faustidentity federation is recommended for non-Google Cloud environments as it avoids the
100*af546375SCole Faustneed to download, manage and store service account private keys locally, see:
101*af546375SCole Faust[Workload Identity Federation](#workload-identity-federation).
102*af546375SCole Faust
103*af546375SCole Faust#### Getting Application Default Credentials
104*af546375SCole Faust
105*af546375SCole FaustTo get Application Default Credentials use `GoogleCredentials.getApplicationDefault()` or
106*af546375SCole Faust`GoogleCredentials.getApplicationDefault(HttpTransportFactory)`. These methods return the
107*af546375SCole FaustApplication Default Credentials which are used to identify and authorize the whole application. The
108*af546375SCole Faustfollowing are searched (in order) to find the Application Default Credentials:
109*af546375SCole Faust
110*af546375SCole Faust1. Credentials file pointed to by the `GOOGLE_APPLICATION_CREDENTIALS` environment variable
111*af546375SCole Faust2. Credentials provided by the Google Cloud SDK `gcloud auth application-default login` command
112*af546375SCole Faust3. Google App Engine built-in credentials
113*af546375SCole Faust4. Google Cloud Shell built-in credentials
114*af546375SCole Faust5. Google Compute Engine built-in credentials
115*af546375SCole Faust   - Skip this check by setting the environment variable `NO_GCE_CHECK=true`
116*af546375SCole Faust   - Customize the GCE metadata server address by setting the environment variable `GCE_METADATA_HOST=<hostname>`
117*af546375SCole Faust
118*af546375SCole Faust#### Explicit Credential Loading
119*af546375SCole Faust
120*af546375SCole FaustTo get Credentials from a Service Account JSON key use `GoogleCredentials.fromStream(InputStream)`
121*af546375SCole Faustor `GoogleCredentials.fromStream(InputStream, HttpTransportFactory)`. Note that the credentials must
122*af546375SCole Faustbe refreshed before the access token is available.
123*af546375SCole Faust
124*af546375SCole Faust```java
125*af546375SCole FaustGoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("/path/to/credentials.json"));
126*af546375SCole Faustcredentials.refreshIfExpired();
127*af546375SCole FaustAccessToken token = credentials.getAccessToken();
128*af546375SCole Faust// OR
129*af546375SCole FaustAccessToken token = credentials.refreshAccessToken();
130*af546375SCole Faust```
131*af546375SCole Faust
132*af546375SCole Faust### ImpersonatedCredentials
133*af546375SCole Faust
134*af546375SCole FaustAllows a credentials issued to a user or service account to
135*af546375SCole Faustimpersonate another.  The source project using ImpersonatedCredentials must enable the
136*af546375SCole Faust"IAMCredentials" API.  Also, the target service account must grant the orginating principal
137*af546375SCole Faustthe "Service Account Token Creator" IAM role.
138*af546375SCole Faust
139*af546375SCole Faust```java
140*af546375SCole FaustString credPath = "/path/to/svc_account.json";
141*af546375SCole FaustServiceAccountCredentials sourceCredentials = ServiceAccountCredentials
142*af546375SCole Faust     .fromStream(new FileInputStream(credPath));
143*af546375SCole FaustsourceCredentials = (ServiceAccountCredentials) sourceCredentials
144*af546375SCole Faust    .createScoped(Arrays.asList("https://www.googleapis.com/auth/iam"));
145*af546375SCole Faust
146*af546375SCole FaustImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials,
147*af546375SCole Faust    "[email protected]", null,
148*af546375SCole Faust    Arrays.asList("https://www.googleapis.com/auth/devstorage.read_only"), 300);
149*af546375SCole Faust
150*af546375SCole FaustStorage storage_service = StorageOptions.newBuilder().setProjectId("project-id")
151*af546375SCole Faust    .setCredentials(targetCredentials).build().getService();
152*af546375SCole Faust
153*af546375SCole Faustfor (Bucket b : storage_service.list().iterateAll())
154*af546375SCole Faust    System.out.println(b);
155*af546375SCole Faust```
156*af546375SCole Faust
157*af546375SCole Faust### Workload Identity Federation
158*af546375SCole Faust
159*af546375SCole FaustUsing workload identity federation, your application can access Google Cloud resources from
160*af546375SCole FaustAmazon Web Services (AWS), Microsoft Azure, or any identity provider that supports OpenID Connect
161*af546375SCole Faust(OIDC).
162*af546375SCole Faust
163*af546375SCole FaustTraditionally, applications running outside Google Cloud have used service account keys to access
164*af546375SCole FaustGoogle Cloud resources. Using identity federation, your workload can impersonate a service account.
165*af546375SCole FaustThis lets the external workload access Google Cloud resources directly, eliminating the maintenance
166*af546375SCole Faustand security burden associated with service account keys.
167*af546375SCole Faust
168*af546375SCole Faust#### Accessing resources from AWS
169*af546375SCole Faust
170*af546375SCole FaustIn order to access Google Cloud resources from Amazon Web Services (AWS), the following requirements
171*af546375SCole Faustare needed:
172*af546375SCole Faust- A workload identity pool needs to be created.
173*af546375SCole Faust- AWS needs to be added as an identity provider in the workload identity pool (the Google [organization policy](https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers#restrict) needs to allow federation from AWS).
174*af546375SCole Faust- Permission to impersonate a service account needs to be granted to the external identity.
175*af546375SCole Faust
176*af546375SCole FaustFollow the detailed [instructions](https://cloud.google.com/iam/docs/access-resources-aws) on how to
177*af546375SCole Faustconfigure workload identity federation from AWS.
178*af546375SCole Faust
179*af546375SCole FaustAfter configuring the AWS provider to impersonate a service account, a credential configuration file
180*af546375SCole Faustneeds to be generated. Unlike service account credential files, the generated credential
181*af546375SCole Faustconfiguration file contains non-sensitive metadata to instruct the library on how to
182*af546375SCole Faustretrieve external subject tokens and exchange them for service account access tokens.
183*af546375SCole FaustThe configuration file can be generated by using the [gcloud CLI](https://cloud.google.com/sdk/).
184*af546375SCole Faust
185*af546375SCole FaustTo generate the AWS workload identity configuration, run the following command:
186*af546375SCole Faust
187*af546375SCole Faust```bash
188*af546375SCole Faust# Generate an AWS configuration file.
189*af546375SCole Faustgcloud iam workload-identity-pools create-cred-config \
190*af546375SCole Faust    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \
191*af546375SCole Faust    --service-account $SERVICE_ACCOUNT_EMAIL \
192*af546375SCole Faust    --aws \
193*af546375SCole Faust    --output-file /path/to/generated/config.json
194*af546375SCole Faust```
195*af546375SCole Faust
196*af546375SCole FaustWhere the following variables need to be substituted:
197*af546375SCole Faust- `$PROJECT_NUMBER`: The Google Cloud project number.
198*af546375SCole Faust- `$POOL_ID`: The workload identity pool ID.
199*af546375SCole Faust- `$AWS_PROVIDER_ID`: The AWS provider ID.
200*af546375SCole Faust- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate.
201*af546375SCole Faust
202*af546375SCole FaustThis generates the configuration file in the specified output file.
203*af546375SCole Faust
204*af546375SCole FaustIf you are using [AWS IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html), an additional flag `--enable-imdsv2` needs to be added to the `gcloud iam workload-identity-pools create-cred-config` command:
205*af546375SCole Faust
206*af546375SCole Faust```bash
207*af546375SCole Faustgcloud iam workload-identity-pools create-cred-config \
208*af546375SCole Faust    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \
209*af546375SCole Faust    --service-account $SERVICE_ACCOUNT_EMAIL \
210*af546375SCole Faust    --aws \
211*af546375SCole Faust    --output-file /path/to/generated/config.json \
212*af546375SCole Faust    --enable-imdsv2
213*af546375SCole Faust```
214*af546375SCole Faust
215*af546375SCole FaustYou can now [use the Auth library](#using-external-identities) to call Google Cloud
216*af546375SCole Faustresources from AWS.
217*af546375SCole Faust
218*af546375SCole Faust#### Access resources from Microsoft Azure
219*af546375SCole Faust
220*af546375SCole FaustIn order to access Google Cloud resources from Microsoft Azure, the following requirements are
221*af546375SCole Faustneeded:
222*af546375SCole Faust- A workload identity pool needs to be created.
223*af546375SCole Faust- Azure needs to be added as an identity provider in the workload identity pool (the Google [organization policy](https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers#restrict) needs to allow federation from Azure).
224*af546375SCole Faust- The Azure tenant needs to be configured for identity federation.
225*af546375SCole Faust- Permission to impersonate a service account needs to be granted to the external identity.
226*af546375SCole Faust
227*af546375SCole FaustFollow the detailed [instructions](https://cloud.google.com/iam/docs/access-resources-azure) on how
228*af546375SCole Faustto configure workload identity federation from Microsoft Azure.
229*af546375SCole Faust
230*af546375SCole FaustAfter configuring the Azure provider to impersonate a service account, a credential configuration
231*af546375SCole Faustfile needs to be generated. Unlike service account credential files, the generated credential
232*af546375SCole Faustconfiguration file contains non-sensitive metadata to instruct the library on how to
233*af546375SCole Faustretrieve external subject tokens and exchange them for service account access tokens.
234*af546375SCole FaustThe configuration file can be generated by using the [gcloud CLI](https://cloud.google.com/sdk/).
235*af546375SCole Faust
236*af546375SCole FaustTo generate the Azure workload identity configuration, run the following command:
237*af546375SCole Faust
238*af546375SCole Faust```bash
239*af546375SCole Faust# Generate an Azure configuration file.
240*af546375SCole Faustgcloud iam workload-identity-pools create-cred-config \
241*af546375SCole Faust    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AZURE_PROVIDER_ID \
242*af546375SCole Faust    --service-account $SERVICE_ACCOUNT_EMAIL \
243*af546375SCole Faust    --azure \
244*af546375SCole Faust    --output-file /path/to/generated/config.json
245*af546375SCole Faust```
246*af546375SCole Faust
247*af546375SCole FaustWhere the following variables need to be substituted:
248*af546375SCole Faust- `$PROJECT_NUMBER`: The Google Cloud project number.
249*af546375SCole Faust- `$POOL_ID`: The workload identity pool ID.
250*af546375SCole Faust- `$AZURE_PROVIDER_ID`: The Azure provider ID.
251*af546375SCole Faust- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate.
252*af546375SCole Faust
253*af546375SCole FaustThis generates the configuration file in the specified output file.
254*af546375SCole Faust
255*af546375SCole FaustYou can now [use the Auth library](#using-external-identities) to call Google Cloud
256*af546375SCole Faustresources from Azure.
257*af546375SCole Faust
258*af546375SCole Faust#### Accessing resources from an OIDC identity provider
259*af546375SCole Faust
260*af546375SCole FaustIn order to access Google Cloud resources from an identity provider that supports [OpenID Connect (OIDC)](https://openid.net/connect/), the following requirements are needed:
261*af546375SCole Faust- A workload identity pool needs to be created.
262*af546375SCole Faust- An OIDC identity provider needs to be added in the workload identity pool (the Google [organization policy](https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers#restrict) needs to allow federation from the identity provider).
263*af546375SCole Faust- Permission to impersonate a service account needs to be granted to the external identity.
264*af546375SCole Faust
265*af546375SCole FaustFollow the detailed [instructions](https://cloud.google.com/iam/docs/access-resources-oidc) on how
266*af546375SCole Faustto configure workload identity federation from an OIDC identity provider.
267*af546375SCole Faust
268*af546375SCole FaustAfter configuring the OIDC provider to impersonate a service account, a credential configuration
269*af546375SCole Faustfile needs to be generated. Unlike service account credential files, the generated credential
270*af546375SCole Faustconfiguration file contains non-sensitive metadata to instruct the library on how to
271*af546375SCole Faustretrieve external subject tokens and exchange them for service account access tokens.
272*af546375SCole FaustThe configuration file can be generated by using the [gcloud CLI](https://cloud.google.com/sdk/).
273*af546375SCole Faust
274*af546375SCole FaustFor OIDC providers, the Auth library can retrieve OIDC tokens either from a local file location
275*af546375SCole Faust(file-sourced credentials) or from a local server (URL-sourced credentials).
276*af546375SCole Faust
277*af546375SCole Faust**File-sourced credentials**
278*af546375SCole FaustFor file-sourced credentials, a background process needs to be continuously refreshing the file
279*af546375SCole Faustlocation with a new OIDC token prior to expiration. For tokens with one hour lifetimes, the token
280*af546375SCole Faustneeds to be updated in the file every hour. The token can be stored directly as plain text or in
281*af546375SCole FaustJSON format.
282*af546375SCole Faust
283*af546375SCole FaustTo generate a file-sourced OIDC configuration, run the following command:
284*af546375SCole Faust
285*af546375SCole Faust```bash
286*af546375SCole Faust# Generate an OIDC configuration file for file-sourced credentials.
287*af546375SCole Faustgcloud iam workload-identity-pools create-cred-config \
288*af546375SCole Faust    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$OIDC_PROVIDER_ID \
289*af546375SCole Faust    --service-account $SERVICE_ACCOUNT_EMAIL \
290*af546375SCole Faust    --credential-source-file $PATH_TO_OIDC_ID_TOKEN \
291*af546375SCole Faust    # Optional arguments for file types. Default is "text":
292*af546375SCole Faust    # --credential-source-type "json" \
293*af546375SCole Faust    # Optional argument for the field that contains the OIDC credential.
294*af546375SCole Faust    # This is required for json.
295*af546375SCole Faust    # --credential-source-field-name "id_token" \
296*af546375SCole Faust    --output-file /path/to/generated/config.json
297*af546375SCole Faust```
298*af546375SCole Faust
299*af546375SCole FaustWhere the following variables need to be substituted:
300*af546375SCole Faust- `$PROJECT_NUMBER`: The Google Cloud project number.
301*af546375SCole Faust- `$POOL_ID`: The workload identity pool ID.
302*af546375SCole Faust- `$OIDC_PROVIDER_ID`: The OIDC provider ID.
303*af546375SCole Faust- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate.
304*af546375SCole Faust- `$PATH_TO_OIDC_ID_TOKEN`: The file path used to retrieve the OIDC token.
305*af546375SCole Faust
306*af546375SCole FaustThis generates the configuration file in the specified output file.
307*af546375SCole Faust
308*af546375SCole Faust**URL-sourced credentials**
309*af546375SCole FaustFor URL-sourced credentials, a local server needs to host a GET endpoint to return the OIDC token.
310*af546375SCole FaustThe response can be in plain text or JSON. Additional required request headers can also be
311*af546375SCole Faustspecified.
312*af546375SCole Faust
313*af546375SCole FaustTo generate a URL-sourced OIDC workload identity configuration, run the following command:
314*af546375SCole Faust
315*af546375SCole Faust```bash
316*af546375SCole Faust# Generate an OIDC configuration file for URL-sourced credentials.
317*af546375SCole Faustgcloud iam workload-identity-pools create-cred-config \
318*af546375SCole Faust    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$OIDC_PROVIDER_ID \
319*af546375SCole Faust    --service-account $SERVICE_ACCOUNT_EMAIL \
320*af546375SCole Faust    --credential-source-url $URL_TO_GET_OIDC_TOKEN \
321*af546375SCole Faust    --credential-source-headers $HEADER_KEY=$HEADER_VALUE \
322*af546375SCole Faust    # Optional arguments for file types. Default is "text":
323*af546375SCole Faust    # --credential-source-type "json" \
324*af546375SCole Faust    # Optional argument for the field that contains the OIDC credential.
325*af546375SCole Faust    # This is required for json.
326*af546375SCole Faust    # --credential-source-field-name "id_token" \
327*af546375SCole Faust    --output-file /path/to/generated/config.json
328*af546375SCole Faust```
329*af546375SCole Faust
330*af546375SCole FaustWhere the following variables need to be substituted:
331*af546375SCole Faust- `$PROJECT_NUMBER`: The Google Cloud project number.
332*af546375SCole Faust- `$POOL_ID`: The workload identity pool ID.
333*af546375SCole Faust- `$OIDC_PROVIDER_ID`: The OIDC provider ID.
334*af546375SCole Faust- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate.
335*af546375SCole Faust- `$URL_TO_GET_OIDC_TOKEN`: The URL of the local server endpoint to call to retrieve the OIDC token.
336*af546375SCole Faust- `$HEADER_KEY` and `$HEADER_VALUE`: The additional header key/value pairs to pass along the GET
337*af546375SCole Faustrequest to `$URL_TO_GET_OIDC_TOKEN`, e.g. `Metadata-Flavor=Google`.
338*af546375SCole Faust
339*af546375SCole FaustYou can now [use the Auth library](#using-external-identities) to call Google Cloud
340*af546375SCole Faustresources from an OIDC provider.
341*af546375SCole Faust
342*af546375SCole Faust#### Using Executable-sourced credentials with OIDC and SAML
343*af546375SCole Faust
344*af546375SCole Faust**Executable-sourced credentials**
345*af546375SCole FaustFor executable-sourced credentials, a local executable is used to retrieve the 3rd party token.
346*af546375SCole FaustThe executable must handle providing a valid, unexpired OIDC ID token or SAML assertion in JSON format
347*af546375SCole Faustto stdout.
348*af546375SCole Faust
349*af546375SCole FaustTo use executable-sourced credentials, the `GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES`
350*af546375SCole Faustenvironment variable must be set to `1`.
351*af546375SCole Faust
352*af546375SCole FaustTo generate an executable-sourced workload identity configuration, run the following command:
353*af546375SCole Faust
354*af546375SCole Faust```bash
355*af546375SCole Faust# Generate a configuration file for executable-sourced credentials.
356*af546375SCole Faustgcloud iam workload-identity-pools create-cred-config \
357*af546375SCole Faust    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID \
358*af546375SCole Faust    --service-account=$SERVICE_ACCOUNT_EMAIL \
359*af546375SCole Faust    --subject-token-type=$SUBJECT_TOKEN_TYPE \
360*af546375SCole Faust    # The absolute path for the program, including arguments.
361*af546375SCole Faust    # e.g. --executable-command="/path/to/command --foo=bar"
362*af546375SCole Faust    --executable-command=$EXECUTABLE_COMMAND \
363*af546375SCole Faust    # Optional argument for the executable timeout. Defaults to 30s.
364*af546375SCole Faust    # --executable-timeout-millis=$EXECUTABLE_TIMEOUT \
365*af546375SCole Faust    # Optional argument for the absolute path to the executable output file.
366*af546375SCole Faust    # See below on how this argument impacts the library behaviour.
367*af546375SCole Faust    # --executable-output-file=$EXECUTABLE_OUTPUT_FILE \
368*af546375SCole Faust    --output-file /path/to/generated/config.json
369*af546375SCole Faust```
370*af546375SCole FaustWhere the following variables need to be substituted:
371*af546375SCole Faust- `$PROJECT_NUMBER`: The Google Cloud project number.
372*af546375SCole Faust- `$POOL_ID`: The workload identity pool ID.
373*af546375SCole Faust- `$PROVIDER_ID`: The OIDC or SAML provider ID.
374*af546375SCole Faust- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate.
375*af546375SCole Faust- `$SUBJECT_TOKEN_TYPE`: The subject token type.
376*af546375SCole Faust- `$EXECUTABLE_COMMAND`: The full command to run, including arguments. Must be an absolute path to the program.
377*af546375SCole Faust
378*af546375SCole FaustThe `--executable-timeout-millis` flag is optional. This is the duration for which
379*af546375SCole Faustthe auth library will wait for the executable to finish, in milliseconds.
380*af546375SCole FaustDefaults to 30 seconds when not provided. The maximum allowed value is 2 minutes.
381*af546375SCole FaustThe minimum is 5 seconds.
382*af546375SCole Faust
383*af546375SCole FaustThe `--executable-output-file` flag is optional. If provided, the file path must
384*af546375SCole Faustpoint to the 3PI credential response generated by the executable. This is useful
385*af546375SCole Faustfor caching the credentials. By specifying this path, the Auth libraries will first
386*af546375SCole Faustcheck for its existence before running the executable. By caching the executable JSON
387*af546375SCole Faustresponse to this file, it improves performance as it avoids the need to run the executable
388*af546375SCole Faustuntil the cached credentials in the output file are expired. The executable must
389*af546375SCole Fausthandle writing to this file - the auth libraries will only attempt to read from
390*af546375SCole Faustthis location. The format of contents in the file should match the JSON format
391*af546375SCole Faustexpected by the executable shown below.
392*af546375SCole Faust
393*af546375SCole FaustTo retrieve the 3rd party token, the library will call the executable
394*af546375SCole Faustusing the command specified. The executable's output must adhere to the response format
395*af546375SCole Faustspecified below. It must output the response to stdout.
396*af546375SCole Faust
397*af546375SCole FaustA sample successful executable OIDC response:
398*af546375SCole Faust```json
399*af546375SCole Faust{
400*af546375SCole Faust  "version": 1,
401*af546375SCole Faust  "success": true,
402*af546375SCole Faust  "token_type": "urn:ietf:params:oauth:token-type:id_token",
403*af546375SCole Faust  "id_token": "HEADER.PAYLOAD.SIGNATURE",
404*af546375SCole Faust  "expiration_time": 1620499962
405*af546375SCole Faust}
406*af546375SCole Faust```
407*af546375SCole Faust
408*af546375SCole FaustA sample successful executable SAML response:
409*af546375SCole Faust```json
410*af546375SCole Faust{
411*af546375SCole Faust  "version": 1,
412*af546375SCole Faust  "success": true,
413*af546375SCole Faust  "token_type": "urn:ietf:params:oauth:token-type:saml2",
414*af546375SCole Faust  "saml_response": "...",
415*af546375SCole Faust  "expiration_time": 1620499962
416*af546375SCole Faust}
417*af546375SCole Faust```
418*af546375SCole FaustA sample executable error response:
419*af546375SCole Faust```json
420*af546375SCole Faust{
421*af546375SCole Faust  "version": 1,
422*af546375SCole Faust  "success": false,
423*af546375SCole Faust  "code": "401",
424*af546375SCole Faust  "message": "Caller not authorized."
425*af546375SCole Faust}
426*af546375SCole Faust```
427*af546375SCole FaustThese are all required fields for an error response. The code and message
428*af546375SCole Faustfields will be used by the library as part of the thrown exception.
429*af546375SCole Faust
430*af546375SCole FaustFor successful responses, the `expiration_time` field is only required
431*af546375SCole Faustwhen an output file is specified in the credential configuration.
432*af546375SCole Faust
433*af546375SCole FaustResponse format fields summary:
434*af546375SCole Faust  * `version`: The version of the JSON output. Currently only version 1 is supported.
435*af546375SCole Faust  * `success`: When true, the response must contain the 3rd party token and token type. The response must also contain
436*af546375SCole Faust    the expiration_time field if an output file was specified in the credential configuration. The executable must also
437*af546375SCole Faust    exit with exit code 0. When false, the response must contain the error code and message fields and exit with a
438*af546375SCole Faust    non-zero value.
439*af546375SCole Faust  * `token_type`: The 3rd party subject token type. Must be *urn:ietf:params:oauth:token-type:jwt*,
440*af546375SCole Faust     *urn:ietf:params:oauth:token-type:id_token*, or *urn:ietf:params:oauth:token-type:saml2*.
441*af546375SCole Faust  * `id_token`: The 3rd party OIDC token.
442*af546375SCole Faust  * `saml_response`: The 3rd party SAML response.
443*af546375SCole Faust  * `expiration_time`: The 3rd party subject token expiration time in seconds (unix epoch time).
444*af546375SCole Faust  * `code`: The error code string.
445*af546375SCole Faust  * `message`: The error message.
446*af546375SCole Faust
447*af546375SCole FaustAll response types must include both the `version` and `success` fields.
448*af546375SCole Faust * Successful responses must include the `token_type` and one of
449*af546375SCole Faust   `id_token` or `saml_response`. The `expiration_time` field must also be present if an output file was specified in
450*af546375SCole Faust    the credential configuration.
451*af546375SCole Faust * Error responses must include both the `code` and `message` fields.
452*af546375SCole Faust
453*af546375SCole FaustThe library will populate the following environment variables when the executable is run:
454*af546375SCole Faust  * `GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE`: The audience field from the credential configuration. Always present.
455*af546375SCole Faust  * `GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE`: This expected subject token type. Always present.
456*af546375SCole Faust  * `GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL`: The service account email. Only present when service account impersonation is used.
457*af546375SCole Faust  * `GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE`: The output file location from the credential configuration. Only present when specified in the credential configuration.
458*af546375SCole Faust
459*af546375SCole FaustThese environment variables can be used by the executable to avoid hard-coding these values.
460*af546375SCole Faust
461*af546375SCole Faust##### Security considerations
462*af546375SCole FaustThe following security practices are highly recommended:
463*af546375SCole Faust  * Access to the script should be restricted as it will be displaying credentials to stdout. This ensures that rogue processes do not gain access to the script.
464*af546375SCole Faust  * The configuration file should not be modifiable. Write access should be restricted to avoid processes modifying the executable command portion.
465*af546375SCole Faust
466*af546375SCole FaustGiven the complexity of using executable-sourced credentials, it is recommended to use
467*af546375SCole Faustthe existing supported mechanisms (file-sourced/URL-sourced) for providing 3rd party
468*af546375SCole Faustcredentials unless they do not meet your specific requirements.
469*af546375SCole Faust
470*af546375SCole FaustYou can now [use the Auth library](#using-external-identities) to call Google Cloud
471*af546375SCole Faustresources from an OIDC or SAML provider.
472*af546375SCole Faust
473*af546375SCole Faust#### Configurable Token Lifetime
474*af546375SCole FaustWhen creating a credential configuration with workload identity federation using service account impersonation, you can provide an optional argument to configure the service account access token lifetime.
475*af546375SCole Faust
476*af546375SCole FaustTo generate the configuration with configurable token lifetime, run the following command (this example uses an AWS configuration, but the token lifetime can be configured for all workload identity federation providers):
477*af546375SCole Faust  ```bash
478*af546375SCole Faust  # Generate an AWS configuration file with configurable token lifetime.
479*af546375SCole Faust  gcloud iam workload-identity-pools create-cred-config \
480*af546375SCole Faust      projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \
481*af546375SCole Faust      --service-account $SERVICE_ACCOUNT_EMAIL \
482*af546375SCole Faust      --aws \
483*af546375SCole Faust      --output-file /path/to/generated/config.json \
484*af546375SCole Faust      --service-account-token-lifetime-seconds $TOKEN_LIFETIME
485*af546375SCole Faust  ```
486*af546375SCole Faust
487*af546375SCole FaustWhere the following variables need to be substituted:
488*af546375SCole Faust- `$PROJECT_NUMBER`: The Google Cloud project number.
489*af546375SCole Faust- `$POOL_ID`: The workload identity pool ID.
490*af546375SCole Faust- `$AWS_PROVIDER_ID`: The AWS provider ID.
491*af546375SCole Faust- `$SERVICE_ACCOUNT_EMAIL`: The email of the service account to impersonate.
492*af546375SCole Faust- `$TOKEN_LIFETIME`: The desired lifetime duration of the service account access token in seconds.
493*af546375SCole Faust
494*af546375SCole FaustThe `service-account-token-lifetime-seconds` flag is optional. If not provided, this defaults to one hour.
495*af546375SCole FaustThe minimum allowed value is 600 (10 minutes) and the maximum allowed value is 43200 (12 hours).
496*af546375SCole FaustIf a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces the `constraints/iam.allowServiceAccountCredentialLifetimeExtension` constraint.
497*af546375SCole Faust
498*af546375SCole FaustNote that configuring a short lifetime (e.g. 10 minutes) will result in the library initiating the entire token exchange flow every 10 minutes, which will call the 3rd party token provider even if the 3rd party token is not expired.
499*af546375SCole Faust
500*af546375SCole Faust###  Workforce Identity Federation
501*af546375SCole Faust
502*af546375SCole Faust[Workforce identity federation](https://cloud.google.com/iam/docs/workforce-identity-federation) lets you use an
503*af546375SCole Faustexternal identity provider (IdP) to authenticate and authorize a workforce—a group of users, such as employees,
504*af546375SCole Faustpartners, and contractors—using IAM, so that the users can access Google Cloud services. Workforce identity federation
505*af546375SCole Faustextends Google Cloud's identity capabilities to support syncless, attribute-based single sign on.
506*af546375SCole Faust
507*af546375SCole FaustWith workforce identity federation, your workforce can access Google Cloud resources using an external
508*af546375SCole Faustidentity provider (IdP) that supports OpenID Connect (OIDC) or SAML 2.0 such as Azure Active Directory (Azure AD),
509*af546375SCole FaustActive Directory Federation Services (AD FS), Okta, and others.
510*af546375SCole Faust
511*af546375SCole Faust#### Accessing resources using an OIDC or SAML 2.0 identity provider
512*af546375SCole Faust
513*af546375SCole FaustIn order to access Google Cloud resources from an identity provider that supports [OpenID Connect (OIDC)](https://openid.net/connect/),
514*af546375SCole Faustthe following requirements are needed:
515*af546375SCole Faust- A workforce identity pool needs to be created.
516*af546375SCole Faust- An OIDC or SAML 2.0 identity provider needs to be added in the workforce pool.
517*af546375SCole Faust
518*af546375SCole FaustFollow the detailed [instructions](https://cloud.google.com/iam/docs/configuring-workforce-identity-federation) on how
519*af546375SCole Faustto configure workforce identity federation.
520*af546375SCole Faust
521*af546375SCole FaustAfter configuring an OIDC or SAML 2.0 provider, a credential configuration
522*af546375SCole Faustfile needs to be generated. The generated credential configuration file contains non-sensitive metadata to instruct the
523*af546375SCole Faustlibrary on how to retrieve external subject tokens and exchange them for GCP access tokens.
524*af546375SCole FaustThe configuration file can be generated by using the [gcloud CLI](https://cloud.google.com/sdk/).
525*af546375SCole Faust
526*af546375SCole FaustThe Auth library can retrieve external subject tokens from a local file location
527*af546375SCole Faust(file-sourced credentials), from a local server (URL-sourced credentials) or by calling an executable
528*af546375SCole Faust(executable-sourced credentials).
529*af546375SCole Faust
530*af546375SCole Faust**File-sourced credentials**
531*af546375SCole FaustFor file-sourced credentials, a background process needs to be continuously refreshing the file
532*af546375SCole Faustlocation with a new subject token prior to expiration. For tokens with one hour lifetimes, the token
533*af546375SCole Faustneeds to be updated in the file every hour. The token can be stored directly as plain text or in
534*af546375SCole FaustJSON format.
535*af546375SCole Faust
536*af546375SCole FaustTo generate a file-sourced OIDC configuration, run the following command:
537*af546375SCole Faust
538*af546375SCole Faust```bash
539*af546375SCole Faust# Generate an OIDC configuration file for file-sourced credentials.
540*af546375SCole Faustgcloud iam workforce-pools create-cred-config \
541*af546375SCole Faust    locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID \
542*af546375SCole Faust    --subject-token-type=urn:ietf:params:oauth:token-type:id_token \
543*af546375SCole Faust    --credential-source-file=$PATH_TO_OIDC_ID_TOKEN \
544*af546375SCole Faust    --workforce-pool-user-project=$WORKFORCE_POOL_USER_PROJECT \
545*af546375SCole Faust    # Optional arguments for file types. Default is "text":
546*af546375SCole Faust    # --credential-source-type "json" \
547*af546375SCole Faust    # Optional argument for the field that contains the OIDC credential.
548*af546375SCole Faust    # This is required for json.
549*af546375SCole Faust    # --credential-source-field-name "id_token" \
550*af546375SCole Faust    --output-file=/path/to/generated/config.json
551*af546375SCole Faust```
552*af546375SCole FaustWhere the following variables need to be substituted:
553*af546375SCole Faust- `$WORKFORCE_POOL_ID`: The workforce pool ID.
554*af546375SCole Faust- `$PROVIDER_ID`: The provider ID.
555*af546375SCole Faust- `$PATH_TO_OIDC_ID_TOKEN`: The file path used to retrieve the OIDC token.
556*af546375SCole Faust- `$WORKFORCE_POOL_USER_PROJECT`: The project number associated with the [workforce pools user project](https://cloud.google.com/iam/docs/workforce-identity-federation#workforce-pools-user-project).
557*af546375SCole Faust
558*af546375SCole FaustTo generate a file-sourced SAML configuration, run the following command:
559*af546375SCole Faust
560*af546375SCole Faust```bash
561*af546375SCole Faust# Generate a SAML configuration file for file-sourced credentials.
562*af546375SCole Faustgcloud iam workforce-pools create-cred-config \
563*af546375SCole Faust    locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID \
564*af546375SCole Faust    --credential-source-file=$PATH_TO_SAML_ASSERTION \
565*af546375SCole Faust    --subject-token-type=urn:ietf:params:oauth:token-type:saml2 \
566*af546375SCole Faust    --workforce-pool-user-project=$WORKFORCE_POOL_USER_PROJECT \
567*af546375SCole Faust    --output-file=/path/to/generated/config.json
568*af546375SCole Faust```
569*af546375SCole Faust
570*af546375SCole FaustWhere the following variables need to be substituted:
571*af546375SCole Faust- `$WORKFORCE_POOL_ID`: The workforce pool ID.
572*af546375SCole Faust- `$PROVIDER_ID`: The provider ID.
573*af546375SCole Faust- `$PATH_TO_SAML_ASSERTION`: The file path used to retrieve the base64-encoded SAML assertion.
574*af546375SCole Faust- `$WORKFORCE_POOL_USER_PROJECT`: The project number associated with the [workforce pools user project](https://cloud.google.com/iam/docs/workforce-identity-federation#workforce-pools-user-project).
575*af546375SCole Faust
576*af546375SCole FaustThese commands generate the configuration file in the specified output file.
577*af546375SCole Faust
578*af546375SCole Faust**URL-sourced credentials**
579*af546375SCole FaustFor URL-sourced credentials, a local server needs to host a GET endpoint to return the OIDC token.
580*af546375SCole FaustThe response can be in plain text or JSON. Additional required request headers can also be
581*af546375SCole Faustspecified.
582*af546375SCole Faust
583*af546375SCole FaustTo generate a URL-sourced OIDC workforce identity configuration, run the following command:
584*af546375SCole Faust
585*af546375SCole Faust```bash
586*af546375SCole Faust# Generate an OIDC configuration file for URL-sourced credentials.
587*af546375SCole Faustgcloud iam workforce-pools create-cred-config \
588*af546375SCole Faust    locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID \
589*af546375SCole Faust    --subject-token-type=urn:ietf:params:oauth:token-type:id_token \
590*af546375SCole Faust    --credential-source-url=$URL_TO_RETURN_OIDC_ID_TOKEN \
591*af546375SCole Faust    --credential-source-headers $HEADER_KEY=$HEADER_VALUE \
592*af546375SCole Faust    --workforce-pool-user-project=$WORKFORCE_POOL_USER_PROJECT \
593*af546375SCole Faust    --output-file=/path/to/generated/config.json
594*af546375SCole Faust```
595*af546375SCole Faust
596*af546375SCole FaustWhere the following variables need to be substituted:
597*af546375SCole Faust- `$WORKFORCE_POOL_ID`: The workforce pool ID.
598*af546375SCole Faust- `$PROVIDER_ID`: The provider ID.
599*af546375SCole Faust- `$URL_TO_RETURN_OIDC_ID_TOKEN`: The URL of the local server endpoint.
600*af546375SCole Faust- `$HEADER_KEY` and `$HEADER_VALUE`: The additional header key/value pairs to pass along the GET request to
601*af546375SCole Faust  `$URL_TO_GET_OIDC_TOKEN`, e.g. `Metadata-Flavor=Google`.
602*af546375SCole Faust- `$WORKFORCE_POOL_USER_PROJECT`: The project number associated with the [workforce pools user project](https://cloud.google.com/iam/docs/workforce-identity-federation#workforce-pools-user-project).
603*af546375SCole Faust
604*af546375SCole FaustTo generate a URL-sourced SAML configuration, run the following command:
605*af546375SCole Faust
606*af546375SCole Faust```bash
607*af546375SCole Faust# Generate a SAML configuration file for file-sourced credentials.
608*af546375SCole Faustgcloud iam workforce-pools create-cred-config \
609*af546375SCole Faust    locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID \
610*af546375SCole Faust    --subject-token-type=urn:ietf:params:oauth:token-type:saml2 \
611*af546375SCole Faust    --credential-source-url=$URL_TO_GET_SAML_ASSERTION \
612*af546375SCole Faust    --credential-source-headers $HEADER_KEY=$HEADER_VALUE \
613*af546375SCole Faust    --workforce-pool-user-project=$WORKFORCE_POOL_USER_PROJECT \
614*af546375SCole Faust    --output-file=/path/to/generated/config.json
615*af546375SCole Faust```
616*af546375SCole Faust
617*af546375SCole FaustThese commands generate the configuration file in the specified output file.
618*af546375SCole Faust
619*af546375SCole FaustWhere the following variables need to be substituted:
620*af546375SCole Faust- `$WORKFORCE_POOL_ID`: The workforce pool ID.
621*af546375SCole Faust- `$PROVIDER_ID`: The provider ID.
622*af546375SCole Faust- `$URL_TO_GET_SAML_ASSERTION`: The URL of the local server endpoint.
623*af546375SCole Faust- `$HEADER_KEY` and `$HEADER_VALUE`: The additional header key/value pairs to pass along the GET request to
624*af546375SCole Faust  `$URL_TO_GET_SAML_ASSERTION`, e.g. `Metadata-Flavor=Google`.
625*af546375SCole Faust- `$WORKFORCE_POOL_USER_PROJECT`: The project number associated with the [workforce pools user project](https://cloud.google.com/iam/docs/workforce-identity-federation#workforce-pools-user-project).
626*af546375SCole Faust
627*af546375SCole Faust#### Using external account authorized user workforce credentials
628*af546375SCole Faust
629*af546375SCole Faust[External account authorized user credentials](https://cloud.google.com/iam/docs/workforce-obtaining-short-lived-credentials#browser-based-sign-in) allow you to sign in with a web browser to an external identity provider account via the
630*af546375SCole Faustgcloud CLI and create a configuration for the auth library to use.
631*af546375SCole Faust
632*af546375SCole FaustTo generate an external account authorized user workforce identity configuration, run the following command:
633*af546375SCole Faust
634*af546375SCole Faust```bash
635*af546375SCole Faustgcloud auth application-default login --login-config=$LOGIN_CONFIG
636*af546375SCole Faust```
637*af546375SCole Faust
638*af546375SCole FaustWhere the following variable needs to be substituted:
639*af546375SCole Faust- `$LOGIN_CONFIG`: The login config file generated with the cloud console or
640*af546375SCole Faust  [gcloud iam workforce-pools create-login-config](https://cloud.google.com/sdk/gcloud/reference/iam/workforce-pools/create-login-config)
641*af546375SCole Faust
642*af546375SCole FaustThis will open a browser flow for you to sign in via the configured third party identity provider
643*af546375SCole Faustand then will store the external account authorized user configuration at the well known ADC location.
644*af546375SCole FaustThe auth library will then use the provided refresh token from the configuration to generate and refresh
645*af546375SCole Faustan access token to call Google Cloud services.
646*af546375SCole Faust
647*af546375SCole FaustNote that the default lifetime of the refresh token is one hour, after which a new configuration will need to be generated from the gcloud CLI.
648*af546375SCole FaustThe lifetime can be modified by changing the [session duration of the workforce pool](https://cloud.google.com/iam/docs/reference/rest/v1/locations.workforcePools), and can be set as high as 12 hours.
649*af546375SCole Faust
650*af546375SCole Faust#### Using Executable-sourced workforce credentials with OIDC and SAML
651*af546375SCole Faust
652*af546375SCole Faust**Executable-sourced credentials**
653*af546375SCole FaustFor executable-sourced credentials, a local executable is used to retrieve the 3rd party token.
654*af546375SCole FaustThe executable must handle providing a valid, unexpired OIDC ID token or SAML assertion in JSON format
655*af546375SCole Faustto stdout.
656*af546375SCole Faust
657*af546375SCole FaustTo use executable-sourced credentials, the `GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES`
658*af546375SCole Faustenvironment variable must be set to `1`.
659*af546375SCole Faust
660*af546375SCole FaustTo generate an executable-sourced workforce identity configuration, run the following command:
661*af546375SCole Faust
662*af546375SCole Faust```bash
663*af546375SCole Faust# Generate a configuration file for executable-sourced credentials.
664*af546375SCole Faustgcloud iam workforce-pools create-cred-config \
665*af546375SCole Faust    locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID \
666*af546375SCole Faust    --subject-token-type=$SUBJECT_TOKEN_TYPE \
667*af546375SCole Faust    # The absolute path for the program, including arguments.
668*af546375SCole Faust    # e.g. --executable-command="/path/to/command --foo=bar"
669*af546375SCole Faust    --executable-command=$EXECUTABLE_COMMAND \
670*af546375SCole Faust    # Optional argument for the executable timeout. Defaults to 30s.
671*af546375SCole Faust    # --executable-timeout-millis=$EXECUTABLE_TIMEOUT \
672*af546375SCole Faust    # Optional argument for the absolute path to the executable output file.
673*af546375SCole Faust    # See below on how this argument impacts the library behaviour.
674*af546375SCole Faust    # --executable-output-file=$EXECUTABLE_OUTPUT_FILE \
675*af546375SCole Faust    --workforce-pool-user-project=$WORKFORCE_POOL_USER_PROJECT \
676*af546375SCole Faust    --output-file /path/to/generated/config.json
677*af546375SCole Faust```
678*af546375SCole FaustWhere the following variables need to be substituted:
679*af546375SCole Faust- `$WORKFORCE_POOL_ID`: The workforce pool ID.
680*af546375SCole Faust- `$PROVIDER_ID`: The provider ID.
681*af546375SCole Faust- `$SUBJECT_TOKEN_TYPE`: The subject token type.
682*af546375SCole Faust- `$EXECUTABLE_COMMAND`: The full command to run, including arguments. Must be an absolute path to the program.
683*af546375SCole Faust- `$WORKFORCE_POOL_USER_PROJECT`: The project number associated with the [workforce pools user project](https://cloud.google.com/iam/docs/workforce-identity-federation#workforce-pools-user-project).
684*af546375SCole Faust
685*af546375SCole FaustThe `--executable-timeout-millis` flag is optional. This is the duration for which
686*af546375SCole Faustthe auth library will wait for the executable to finish, in milliseconds.
687*af546375SCole FaustDefaults to 30 seconds when not provided. The maximum allowed value is 2 minutes.
688*af546375SCole FaustThe minimum is 5 seconds.
689*af546375SCole Faust
690*af546375SCole FaustThe `--executable-output-file` flag is optional. If provided, the file path must
691*af546375SCole Faustpoint to the 3rd party credential response generated by the executable. This is useful
692*af546375SCole Faustfor caching the credentials. By specifying this path, the Auth libraries will first
693*af546375SCole Faustcheck for its existence before running the executable. By caching the executable JSON
694*af546375SCole Faustresponse to this file, it improves performance as it avoids the need to run the executable
695*af546375SCole Faustuntil the cached credentials in the output file are expired. The executable must
696*af546375SCole Fausthandle writing to this file - the auth libraries will only attempt to read from
697*af546375SCole Faustthis location. The format of contents in the file should match the JSON format
698*af546375SCole Faustexpected by the executable shown below.
699*af546375SCole Faust
700*af546375SCole FaustTo retrieve the 3rd party token, the library will call the executable
701*af546375SCole Faustusing the command specified. The executable's output must adhere to the response format
702*af546375SCole Faustspecified below. It must output the response to stdout.
703*af546375SCole Faust
704*af546375SCole FaustRefer to the [using executable-sourced credentials with Workload Identity Federation](#using-executable-sourced-credentials-with-oidc-and-saml)
705*af546375SCole Faustabove for the executable response specification.
706*af546375SCole Faust
707*af546375SCole Faust##### Security considerations
708*af546375SCole FaustThe following security practices are highly recommended:
709*af546375SCole Faust* Access to the script should be restricted as it will be displaying credentials to stdout. This ensures that rogue processes do not gain access to the script.
710*af546375SCole Faust* The configuration file should not be modifiable. Write access should be restricted to avoid processes modifying the executable command portion.
711*af546375SCole Faust
712*af546375SCole FaustGiven the complexity of using executable-sourced credentials, it is recommended to use
713*af546375SCole Faustthe existing supported mechanisms (file-sourced/URL-sourced) for providing 3rd party
714*af546375SCole Faustcredentials unless they do not meet your specific requirements.
715*af546375SCole Faust
716*af546375SCole FaustYou can now [use the Auth library](#using-external-identities) to call Google Cloud
717*af546375SCole Faustresources from an OIDC or SAML provider.
718*af546375SCole Faust
719*af546375SCole Faust### Using External Identities
720*af546375SCole Faust
721*af546375SCole FaustExternal identities can be used with `Application Default Credentials`. In order to use external identities with
722*af546375SCole FaustApplication Default Credentials, you need to generate the JSON credentials configuration file for your external identity
723*af546375SCole Faustas described above. Once generated, store the path to this file in the`GOOGLE_APPLICATION_CREDENTIALS` environment variable.
724*af546375SCole Faust
725*af546375SCole Faust```bash
726*af546375SCole Faustexport GOOGLE_APPLICATION_CREDENTIALS=/path/to/config.json
727*af546375SCole Faust```
728*af546375SCole Faust
729*af546375SCole FaustThe library can now choose the right type of client and initialize credentials from the context
730*af546375SCole Faustprovided in the configuration file.
731*af546375SCole Faust
732*af546375SCole Faust```java
733*af546375SCole FaustGoogleCredentials googleCredentials = GoogleCredentials.getApplicationDefault();
734*af546375SCole Faust
735*af546375SCole FaustString projectId = "your-project-id";
736*af546375SCole FaustString url = "https://storage.googleapis.com/storage/v1/b?project=" + projectId;
737*af546375SCole Faust
738*af546375SCole FaustHttpCredentialsAdapter credentialsAdapter = new HttpCredentialsAdapter(googleCredentials);
739*af546375SCole FaustHttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory(credentialsAdapter);
740*af546375SCole FaustHttpRequest request = requestFactory.buildGetRequest(new GenericUrl(url));
741*af546375SCole Faust
742*af546375SCole FaustJsonObjectParser parser = new JsonObjectParser(GsonFactory.getDefaultInstance());
743*af546375SCole Faustrequest.setParser(parser);
744*af546375SCole Faust
745*af546375SCole FaustHttpResponse response = request.execute();
746*af546375SCole FaustSystem.out.println(response.parseAsString());
747*af546375SCole Faust```
748*af546375SCole Faust
749*af546375SCole FaustYou can also explicitly initialize external account clients using the generated configuration file.
750*af546375SCole Faust
751*af546375SCole Faust```java
752*af546375SCole FaustExternalAccountCredentials credentials =
753*af546375SCole Faust    ExternalAccountCredentials.fromStream(new FileInputStream("/path/to/credentials.json"));
754*af546375SCole Faust```
755*af546375SCole Faust
756*af546375SCole Faust##### Security Considerations
757*af546375SCole FaustNote that this library does not perform any validation on the token_url, token_info_url,
758*af546375SCole Faustor service_account_impersonation_url fields of the credential configuration.
759*af546375SCole FaustIt is not recommended to use a credential configuration that you did not
760*af546375SCole Faustgenerate with the gcloud CLI unless you verify that the URL fields point to a
761*af546375SCole Faustgoogleapis.com domain.
762*af546375SCole Faust
763*af546375SCole Faust### Downscoping with Credential Access Boundaries
764*af546375SCole Faust
765*af546375SCole Faust[Downscoping with Credential Access Boundaries](https://cloud.google.com/iam/docs/downscoping-short-lived-credentials)
766*af546375SCole Faustenables the ability to downscope, or restrict, the Identity and Access Management (IAM) permissions
767*af546375SCole Faustthat a short-lived credential can use for Cloud Storage.
768*af546375SCole Faust
769*af546375SCole FaustThe `DownscopedCredentials` class can be used to produce a downscoped access token from a
770*af546375SCole Faust`CredentialAccessBoundary` and a source credential. The Credential Access Boundary specifies which
771*af546375SCole Faustresources the newly created credential can access, as well as an upper bound on the permissions that
772*af546375SCole Faustare available on each resource. Using downscoped credentials ensures tokens in flight always have
773*af546375SCole Faustthe least privileges (Principle of Least Privilege).
774*af546375SCole Faust
775*af546375SCole FaustThe snippet below shows how to initialize a CredentialAccessBoundary with one AccessBoundaryRule
776*af546375SCole Faustwhich specifies that the downscoped token will have readonly access to objects starting with
777*af546375SCole Faust"customer-a" in bucket "bucket-123":
778*af546375SCole Faust```java
779*af546375SCole Faust// Create the AccessBoundaryRule.
780*af546375SCole FaustString availableResource = "//storage.googleapis.com/projects/_/buckets/bucket-123";
781*af546375SCole FaustString availablePermission = "inRole:roles/storage.objectViewer";
782*af546375SCole FaustString expression =  "resource.name.startsWith('projects/_/buckets/bucket-123/objects/customer-a')";
783*af546375SCole Faust
784*af546375SCole FaustCredentialAccessBoundary.AccessBoundaryRule rule =
785*af546375SCole Faust    CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
786*af546375SCole Faust        .setAvailableResource(availableResource)
787*af546375SCole Faust        .addAvailablePermission(availablePermission)
788*af546375SCole Faust        .setAvailabilityCondition(
789*af546375SCole Faust        CredentialAccessBoundary.AccessBoundaryRule.AvailabilityCondition.newBuilder().setExpression(expression).build())
790*af546375SCole Faust        .build();
791*af546375SCole Faust
792*af546375SCole Faust// Create the CredentialAccessBoundary with the rule.
793*af546375SCole FaustCredentialAccessBoundary credentialAccessBoundary =
794*af546375SCole Faust        CredentialAccessBoundary.newBuilder().addRule(rule).build();
795*af546375SCole Faust```
796*af546375SCole Faust
797*af546375SCole FaustThe common pattern of usage is to have a token broker with elevated access generate these downscoped
798*af546375SCole Faustcredentials from higher access source credentials and pass the downscoped short-lived access tokens
799*af546375SCole Faustto a token consumer via some secure authenticated channel for limited access to Google Cloud Storage
800*af546375SCole Faustresources.
801*af546375SCole Faust
802*af546375SCole FaustUsing the CredentialAccessBoundary created above in the Token Broker:
803*af546375SCole Faust```java
804*af546375SCole Faust// Retrieve the source credentials from ADC.
805*af546375SCole FaustGoogleCredentials sourceCredentials = GoogleCredentials.getApplicationDefault()
806*af546375SCole Faust        .createScoped("https://www.googleapis.com/auth/cloud-platform");
807*af546375SCole Faust
808*af546375SCole Faust// Initialize the DownscopedCredentials class.
809*af546375SCole FaustDownscopedCredentials downscopedCredentials =
810*af546375SCole Faust    DownscopedCredentials.newBuilder()
811*af546375SCole Faust        .setSourceCredential(credentials)
812*af546375SCole Faust        .setCredentialAccessBoundary(credentialAccessBoundary)
813*af546375SCole Faust        .build();
814*af546375SCole Faust
815*af546375SCole Faust// Retrieve the downscoped access token.
816*af546375SCole Faust// This will need to be passed to the Token Consumer.
817*af546375SCole FaustAccessToken downscopedAccessToken = downscopedCredentials.refreshAccessToken();
818*af546375SCole Faust```
819*af546375SCole Faust
820*af546375SCole FaustA token broker can be set up on a server in a private network. Various workloads
821*af546375SCole Faust(token consumers) in the same network will send authenticated requests to that broker for downscoped
822*af546375SCole Fausttokens to access or modify specific google cloud storage buckets.
823*af546375SCole Faust
824*af546375SCole FaustThe broker will instantiate downscoped credentials instances that can be used to generate short
825*af546375SCole Faustlived downscoped access tokens which will be passed to the token consumer.
826*af546375SCole Faust
827*af546375SCole FaustPutting it all together:
828*af546375SCole Faust```java
829*af546375SCole Faust// Retrieve the source credentials from ADC.
830*af546375SCole FaustGoogleCredentials sourceCredentials = GoogleCredentials.getApplicationDefault()
831*af546375SCole Faust        .createScoped("https://www.googleapis.com/auth/cloud-platform");
832*af546375SCole Faust
833*af546375SCole Faust// Create an Access Boundary Rule which will restrict the downscoped token to having readonly
834*af546375SCole Faust// access to objects starting with "customer-a" in bucket "bucket-123".
835*af546375SCole FaustString availableResource = "//storage.googleapis.com/projects/_/buckets/bucket-123";
836*af546375SCole FaustString availablePermission = "inRole:roles/storage.objectViewer";
837*af546375SCole FaustString expression =  "resource.name.startsWith('projects/_/buckets/bucket-123/objects/customer-a')";
838*af546375SCole Faust
839*af546375SCole FaustCredentialAccessBoundary.AccessBoundaryRule rule =
840*af546375SCole Faust    CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
841*af546375SCole Faust        .setAvailableResource(availableResource)
842*af546375SCole Faust        .addAvailablePermission(availablePermission)
843*af546375SCole Faust        .setAvailabilityCondition(
844*af546375SCole Faust            new AvailabilityCondition(expression, /* title= */ null, /* description= */ null))
845*af546375SCole Faust        .build();
846*af546375SCole Faust
847*af546375SCole Faust// Initialize the DownscopedCredentials class.
848*af546375SCole FaustDownscopedCredentials downscopedCredentials =
849*af546375SCole Faust    DownscopedCredentials.newBuilder()
850*af546375SCole Faust        .setSourceCredential(credentials)
851*af546375SCole Faust        .setCredentialAccessBoundary(CredentialAccessBoundary.newBuilder().addRule(rule).build())
852*af546375SCole Faust        .build();
853*af546375SCole Faust
854*af546375SCole Faust// Retrieve the downscoped access token.
855*af546375SCole Faust// This will need to be passed to the Token Consumer.
856*af546375SCole FaustAccessToken downscopedAccessToken = downscopedCredentials.refreshAccessToken();
857*af546375SCole Faust```
858*af546375SCole Faust
859*af546375SCole FaustThese downscoped access tokens can be used by the Token Consumer via `OAuth2Credentials` or
860*af546375SCole Faust`OAuth2CredentialsWithRefresh`. This credential can then be used to initialize a storage client
861*af546375SCole Faustinstance to access Google Cloud Storage resources with restricted access.
862*af546375SCole Faust
863*af546375SCole Faust```java
864*af546375SCole Faust// You can pass an `OAuth2RefreshHandler` to `OAuth2CredentialsWithRefresh` which will allow the
865*af546375SCole Faust// library to seamlessly handle downscoped token refreshes on expiration.
866*af546375SCole FaustOAuth2CredentialsWithRefresh.OAuth2RefreshHandler handler =
867*af546375SCole Faust        new OAuth2CredentialsWithRefresh.OAuth2RefreshHandler() {
868*af546375SCole Faust    @Override
869*af546375SCole Faust    public AccessToken refreshAccessToken() {
870*af546375SCole Faust      // Add the logic here that retrieves the token from your Token Broker.
871*af546375SCole Faust      return accessToken;
872*af546375SCole Faust    }
873*af546375SCole Faust};
874*af546375SCole Faust
875*af546375SCole Faust// Downscoped token retrieved from token broker.
876*af546375SCole FaustAccessToken downscopedToken = handler.refreshAccessToken();
877*af546375SCole Faust
878*af546375SCole Faust// Build the OAuth2CredentialsWithRefresh from the downscoped token and pass a refresh handler
879*af546375SCole Faust// to handle token expiration. Passing the original downscoped token or the expiry here is optional,
880*af546375SCole Faust// as the refresh_handler will generate the downscoped token on demand.
881*af546375SCole FaustOAuth2CredentialsWithRefresh credentials =
882*af546375SCole Faust    OAuth2CredentialsWithRefresh.newBuilder()
883*af546375SCole Faust        .setAccessToken(downscopedToken)
884*af546375SCole Faust        .setRefreshHandler(handler)
885*af546375SCole Faust        .build();
886*af546375SCole Faust
887*af546375SCole Faust// Use the credentials with the Cloud Storage SDK.
888*af546375SCole FaustStorageOptions options = StorageOptions.newBuilder().setCredentials(credentials).build();
889*af546375SCole FaustStorage storage = options.getService();
890*af546375SCole Faust
891*af546375SCole Faust// Call GCS APIs.
892*af546375SCole Faust// Since we passed the downscoped credential, we will have have limited readonly access to objects
893*af546375SCole Faust// starting with "customer-a" in bucket "bucket-123".
894*af546375SCole Fauststorage.get(...)
895*af546375SCole Faust```
896*af546375SCole Faust
897*af546375SCole FaustNote: Only Cloud Storage supports Credential Access Boundaries. Other Google Cloud services do not
898*af546375SCole Faustsupport this feature.
899*af546375SCole Faust
900*af546375SCole Faust## Configuring a Proxy
901*af546375SCole Faust
902*af546375SCole FaustFor HTTP clients, a basic proxy can be configured by using `http.proxyHost` and related system properties as documented
903*af546375SCole Faustby [Java Networking and Proxies](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html).
904*af546375SCole Faust
905*af546375SCole FaustFor a more custom proxy (e.g. for an authenticated proxy), provide a custom
906*af546375SCole Faust[`HttpTransportFactory`][http-transport-factory] to [`GoogleCredentials`][google-credentials]:
907*af546375SCole Faust
908*af546375SCole Faust```java
909*af546375SCole Faustimport com.google.api.client.http.HttpTransport;
910*af546375SCole Faustimport com.google.api.client.http.apache.v2.ApacheHttpTransport;
911*af546375SCole Faustimport com.google.auth.http.HttpTransportFactory;
912*af546375SCole Faustimport com.google.auth.oauth2.GoogleCredentials;
913*af546375SCole Faustimport org.apache.http.HttpHost;
914*af546375SCole Faustimport org.apache.http.auth.AuthScope;
915*af546375SCole Faustimport org.apache.http.auth.UsernamePasswordCredentials;
916*af546375SCole Faustimport org.apache.http.client.CredentialsProvider;
917*af546375SCole Faustimport org.apache.http.client.HttpClient;
918*af546375SCole Faustimport org.apache.http.conn.routing.HttpRoutePlanner;
919*af546375SCole Faustimport org.apache.http.impl.client.BasicCredentialsProvider;
920*af546375SCole Faustimport org.apache.http.impl.client.ProxyAuthenticationStrategy;
921*af546375SCole Faustimport org.apache.http.impl.conn.DefaultProxyRoutePlanner;
922*af546375SCole Faust
923*af546375SCole Faustimport java.io.IOException;
924*af546375SCole Faust
925*af546375SCole Faustpublic class ProxyExample {
926*af546375SCole Faust  public GoogleCredentials getCredentials() throws IOException {
927*af546375SCole Faust    HttpTransportFactory httpTransportFactory = getHttpTransportFactory(
928*af546375SCole Faust        "some-host", 8080, "some-username", "some-password"
929*af546375SCole Faust    );
930*af546375SCole Faust
931*af546375SCole Faust    return GoogleCredentials.getApplicationDefault(httpTransportFactory);
932*af546375SCole Faust  }
933*af546375SCole Faust
934*af546375SCole Faust  public HttpTransportFactory getHttpTransportFactory(String proxyHost, int proxyPort, String proxyUsername, String proxyPassword) {
935*af546375SCole Faust    HttpHost proxyHostDetails = new HttpHost(proxyHost, proxyPort);
936*af546375SCole Faust    HttpRoutePlanner httpRoutePlanner = new DefaultProxyRoutePlanner(proxyHostDetails);
937*af546375SCole Faust
938*af546375SCole Faust    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
939*af546375SCole Faust    credentialsProvider.setCredentials(
940*af546375SCole Faust        new AuthScope(proxyHostDetails.getHostName(), proxyHostDetails.getPort()),
941*af546375SCole Faust        new UsernamePasswordCredentials(proxyUsername, proxyPassword)
942*af546375SCole Faust    );
943*af546375SCole Faust
944*af546375SCole Faust    HttpClient httpClient = ApacheHttpTransport.newDefaultHttpClientBuilder()
945*af546375SCole Faust        .setRoutePlanner(httpRoutePlanner)
946*af546375SCole Faust        .setProxyAuthenticationStrategy(ProxyAuthenticationStrategy.INSTANCE)
947*af546375SCole Faust        .setDefaultCredentialsProvider(credentialsProvider)
948*af546375SCole Faust        .build();
949*af546375SCole Faust
950*af546375SCole Faust    final HttpTransport httpTransport = new ApacheHttpTransport(httpClient);
951*af546375SCole Faust    return new HttpTransportFactory() {
952*af546375SCole Faust      @Override
953*af546375SCole Faust      public HttpTransport create() {
954*af546375SCole Faust        return httpTransport;
955*af546375SCole Faust      }
956*af546375SCole Faust    };
957*af546375SCole Faust  }
958*af546375SCole Faust}
959*af546375SCole Faust```
960*af546375SCole Faust
961*af546375SCole FaustThe above example requires `com.google.http-client:google-http-client-apache-v2`.
962*af546375SCole Faust
963*af546375SCole Faust## Using Credentials with `google-http-client`
964*af546375SCole Faust
965*af546375SCole FaustCredentials provided by [com.google.auth:google-auth-library-oauth2-http](
966*af546375SCole Fausthttps://search.maven.org/artifact/com.google.auth/google-auth-library-oauth2-http)
967*af546375SCole Faustcan be used with Google's [HTTP-based clients][apiary-clients].
968*af546375SCole FaustWe provide a [`HttpCredentialsAdapter`][http-credentials-adapter] which can be used
969*af546375SCole Faustas an [`HttpRequestInitializer`][http-request-initializer], the last argument for
970*af546375SCole Fausttheir builders.
971*af546375SCole Faust
972*af546375SCole Faust```java
973*af546375SCole Faustimport com.google.api.client.http.HttpRequestInitializer;
974*af546375SCole Faustimport com.google.api.services.bigquery.Bigquery;
975*af546375SCole Faustimport com.google.auth.http.HttpCredentialsAdapter;
976*af546375SCole Faustimport com.google.auth.oauth2.GoogleCredentials;
977*af546375SCole Faust
978*af546375SCole FaustGoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
979*af546375SCole FaustHttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
980*af546375SCole Faust
981*af546375SCole FaustBigquery bq = new Bigquery.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
982*af546375SCole Faust    .setApplicationName(APPLICATION_NAME)
983*af546375SCole Faust    .build();
984*af546375SCole Faust```
985*af546375SCole Faust
986*af546375SCole Faust## Verifying JWT Tokens (Beta)
987*af546375SCole Faust
988*af546375SCole FaustTo verify a JWT token, use the [`TokenVerifier`][token-verifier] class.
989*af546375SCole Faust
990*af546375SCole Faust### Verifying a Signature
991*af546375SCole Faust
992*af546375SCole FaustTo verify a signature, use the default [`TokenVerifier`][token-verifier]:
993*af546375SCole Faust
994*af546375SCole Faust```java
995*af546375SCole Faustimport com.google.api.client.json.webtoken.JsonWebSignature;
996*af546375SCole Faustimport com.google.auth.oauth2.TokenVerifier;
997*af546375SCole Faust
998*af546375SCole FaustTokenVerifier tokenVerifier = TokenVerifier.newBuilder().build();
999*af546375SCole Fausttry {
1000*af546375SCole Faust  JsonWebSignature jsonWebSignature = tokenVerifier.verify(tokenString);
1001*af546375SCole Faust  // optionally verify additional claims
1002*af546375SCole Faust  if (!"expected-value".equals(jsonWebSignature.getPayload().get("additional-claim"))) {
1003*af546375SCole Faust    // handle custom verification error
1004*af546375SCole Faust  }
1005*af546375SCole Faust} catch (TokenVerifier.VerificationException e) {
1006*af546375SCole Faust  // invalid token
1007*af546375SCole Faust}
1008*af546375SCole Faust```
1009*af546375SCole Faust
1010*af546375SCole Faust### Customizing the TokenVerifier
1011*af546375SCole Faust
1012*af546375SCole FaustTo customize a [`TokenVerifier`][token-verifier], instantiate it via its builder:
1013*af546375SCole Faust
1014*af546375SCole Faust```java
1015*af546375SCole Faustimport com.google.api.client.json.webtoken.JsonWebSignature;
1016*af546375SCole Faustimport com.google.auth.oauth2.TokenVerifier;
1017*af546375SCole Faust
1018*af546375SCole FaustTokenVerifier tokenVerifier = TokenVerifier.newBuilder()
1019*af546375SCole Faust  .setAudience("audience-to-verify")
1020*af546375SCole Faust  .setIssuer("issuer-to-verify")
1021*af546375SCole Faust  .build();
1022*af546375SCole Fausttry {
1023*af546375SCole Faust  JsonWebSignature jsonWebSignature = tokenVerifier.verify(tokenString);
1024*af546375SCole Faust  // optionally verify additional claims
1025*af546375SCole Faust  if (!"expected-value".equals(jsonWebSignature.getPayload().get("additional-claim"))) {
1026*af546375SCole Faust    // handle custom verification error
1027*af546375SCole Faust  }
1028*af546375SCole Faust} catch (TokenVerifier.VerificationException e) {
1029*af546375SCole Faust  // invalid token
1030*af546375SCole Faust}
1031*af546375SCole Faust```
1032*af546375SCole Faust
1033*af546375SCole FaustFor more options, see the [`TokenVerifier.Builder`][token-verifier-builder] documentation.
1034*af546375SCole Faust
1035*af546375SCole Faust
1036*af546375SCole Faust## google-auth-library-credentials
1037*af546375SCole Faust
1038*af546375SCole FaustThis artifact contains base classes and interfaces for Google credentials:
1039*af546375SCole Faust- `Credentials`: base class for an authorized identity. Implementations of this class can be used to
1040*af546375SCole Faust  authorize your application
1041*af546375SCole Faust- `RequestMetadataCallback`: interface for the callback that receives the result of the asynchronous
1042*af546375SCole Faust  `Credentials.getRequestMetadata(URI, Executor, RequestMetadataCallback)`
1043*af546375SCole Faust- `ServiceAccountSigner`: interface for a service account signer. Implementations of this class are
1044*af546375SCole Faust  capable of signing byte arrays using the credentials associated to a Google Service Account
1045*af546375SCole Faust
1046*af546375SCole Faust## google-auth-library-appengine
1047*af546375SCole Faust
1048*af546375SCole FaustThis artifact depends on the App Engine SDK (`appengine-api-1.0-sdk`) and should be used only by
1049*af546375SCole Faustapplications running on App Engine environments that use urlfetch. The `AppEngineCredentials` class
1050*af546375SCole Faustallows you to authorize your App Engine application given an instance of
1051*af546375SCole Faust[AppIdentityService][appengine-app-identity-service].
1052*af546375SCole Faust
1053*af546375SCole FaustUsage:
1054*af546375SCole Faust
1055*af546375SCole Faust```java
1056*af546375SCole Faustimport com.google.appengine.api.appidentity.AppIdentityService;
1057*af546375SCole Faustimport com.google.appengine.api.appidentity.AppIdentityServiceFactory;
1058*af546375SCole Faustimport com.google.auth.Credentials;
1059*af546375SCole Faustimport com.google.auth.appengine.AppEngineCredentials;
1060*af546375SCole Faust
1061*af546375SCole FaustAppIdentityService appIdentityService = AppIdentityServiceFactory.getAppIdentityService();
1062*af546375SCole Faust
1063*af546375SCole FaustCredentials credentials =
1064*af546375SCole Faust    AppEngineCredentials.newBuilder()
1065*af546375SCole Faust        .setScopes(...)
1066*af546375SCole Faust        .setAppIdentityService(appIdentityService)
1067*af546375SCole Faust        .build();
1068*af546375SCole Faust```
1069*af546375SCole Faust
1070*af546375SCole Faust**Important: `com.google.auth.appengine.AppEngineCredentials` is a separate class from
1071*af546375SCole Faust`com.google.auth.oauth2.AppEngineCredentials`.**
1072*af546375SCole Faust
1073*af546375SCole Faust## CI Status
1074*af546375SCole Faust
1075*af546375SCole FaustJava Version | Status
1076*af546375SCole Faust------------ | ------
1077*af546375SCole FaustJava 8 | [![Kokoro CI](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8.svg)](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8.html)
1078*af546375SCole FaustJava 8 OSX | [![Kokoro CI](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8-osx.svg)](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8-osx.html)
1079*af546375SCole FaustJava 8 Windows | [![Kokoro CI](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8-win.svg)](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8-win.html)
1080*af546375SCole FaustJava 11 | [![Kokoro CI](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java11.svg)](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java11.html)
1081*af546375SCole Faust
1082*af546375SCole Faust## Contributing
1083*af546375SCole Faust
1084*af546375SCole FaustContributions to this library are always welcome and highly encouraged.
1085*af546375SCole Faust
1086*af546375SCole FaustSee [CONTRIBUTING](CONTRIBUTING.md) documentation for more information on how to get started.
1087*af546375SCole Faust
1088*af546375SCole FaustPlease note that this project is released with a Contributor Code of Conduct. By participating in
1089*af546375SCole Faustthis project you agree to abide by its terms. See [Code of Conduct](CODE_OF_CONDUCT.md) for more
1090*af546375SCole Faustinformation.
1091*af546375SCole Faust
1092*af546375SCole Faust## Running the Tests
1093*af546375SCole Faust
1094*af546375SCole FaustTo run the tests you will need:
1095*af546375SCole Faust
1096*af546375SCole Faust* Maven 3+
1097*af546375SCole Faust
1098*af546375SCole Faust```bash
1099*af546375SCole Faust$ mvn test
1100*af546375SCole Faust```
1101*af546375SCole Faust
1102*af546375SCole Faust## License
1103*af546375SCole Faust
1104*af546375SCole FaustBSD 3-Clause - See [LICENSE](LICENSE) for more information.
1105*af546375SCole Faust
1106*af546375SCole Faust[appengine-sdk-versions]: https://search.maven.org/search?q=g:com.google.appengine%20AND%20a:appengine-api-1.0-sdk&core=gav
1107*af546375SCole Faust[appengine-sdk-install]: https://github.com/googleapis/google-auth-library-java/blob/main/README.md#google-auth-library-appengine
1108*af546375SCole Faust[appengine-app-identity-service]: https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/appidentity/AppIdentityService
1109*af546375SCole Faust[apiary-clients]: https://search.maven.org/search?q=g:com.google.apis
1110*af546375SCole Faust[http-credentials-adapter]: https://googleapis.dev/java/google-auth-library/latest/index.html?com/google/auth/http/HttpCredentialsAdapter.html
1111*af546375SCole Faust[http-request-initializer]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/http/HttpRequestInitializer.html
1112*af546375SCole Faust[token-verifier]: https://googleapis.dev/java/google-auth-library/latest/index.html?com/google/auth/oauth2/TokenVerifier.html
1113*af546375SCole Faust[token-verifier-builder]: https://googleapis.dev/java/google-auth-library/latest/index.html?com/google/auth/oauth2/TokenVerifier.Builder.html
1114*af546375SCole Faust[http-transport-factory]: https://googleapis.dev/java/google-auth-library/latest/index.html?com/google/auth/http/HttpTransportFactory.html
1115*af546375SCole Faust[google-credentials]: https://googleapis.dev/java/google-auth-library/latest/index.html?com/google/auth/oauth2/GoogleCredentials.html
1116