1*af546375SCole Faust# Google Auth Library 2*af546375SCole Faust 3*af546375SCole FaustOpen source authentication client library for Java. 4*af546375SCole Faust 5*af546375SCole Faust[](http://github.com/badges/stability-badges) 6*af546375SCole Faust[](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 | [](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8.html) 1078*af546375SCole FaustJava 8 OSX | [](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8-osx.html) 1079*af546375SCole FaustJava 8 Windows | [](http://storage.googleapis.com/cloud-devrel-public/java/badges/google-auth-library-java/java8-win.html) 1080*af546375SCole FaustJava 11 | [](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