This guide describes how you can use a workload identity pool and provider to obtain short-lived credentials by following this process:
- Obtain a credential from the trusted identity provider.
- Exchange the credential for a token from the Security Token Service.
- Use the token from the Security Token Service to impersonate a service account and obtain a short-lived Google access token.
Using the short-lived Google access tokens, you can then access any Google Cloud resources that the service account has been granted access to.
Before you begin
Enable the IAM, Security Token Service, and Service Account Credentials APIs.
Federate with an external identity provider by creating a workload identity pool and provider.
Create a service account that you want external identities to impersonate.
Grant the service account access to resources that you want external identities to access.
Granting external identities permission to impersonate a service account
To allow external identities to impersonate a service account, you have to grant
them the Workload Identity User role (roles/iam.workloadIdentityUser) on the
service account. You can grant the role to a specific external identity, or to
multiple external identities:
- For a specific external identity, write an attribute condition that checks
the
google.subjectattribute. - For a group of external identities, write an attribute condition that checks
the
google.groupsattribute or a custom attributeattribute.NAME. - For all external identities in the workload identity pool, you do not use an attribute condition.
Console
In the Google Cloud console, go to the Workload Identity Pools page.
Find the workload identity pool you want to update and click on it.
Click Grant access.
In the Service account drop-down list, select the service account that the external identities will impersonate.
Choose which identities in the pool can impersonate the service account:
To allow only specific identities of the workload identity pool to impersonate the service account, select Only identities matching the filter.
In the Attribute name drop-down list, select the attribute that you want to filter on.
In the Attribute value field, enter the expected value of the attribute.
For example, if you use an attribute mapping
google.subject=assertion.sub, set Attribute name tosubjectand Attribute value to the value of thesubclaim in tokens issued by your external identity provider.To allow all external identities of the workload identity pool to impersonate the service account, select All identities in the pool.
Click Save.
Click Dismiss.
gcloud
Create an identifier for the external identities:
A specific external identity:
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT
A group of external identities:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP
All external identities that have a certain attribute:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE
All external identities in a workload identity pool:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*
Replace the following values:
PROJECT_NUMBER: Project number of the project that contains the workload identity poolPOOL_ID: pool ID of the workload identity poolSUBJECT: expected value for the attribute that you've mapped togoogle.subjectGROUP: expected value for the attribute that you've mapped togoogle.groupsATTRIBUTE_NAME: name of a custom attribute in your attribute mapping
To obtain the project number of your current project, you can use the following command:
gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\)
Grant the Workload Identity User role (
roles/iam.workloadIdentityUser) to the service account:gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \ --role=roles/iam.workloadIdentityUser \ --member="MEMBER_ID"Replace the following values:
SERVICE_ACCOUNT_EMAIL: email address of the service accountMEMBER_ID: member identifier that you identified in the previous step
Authenticating by using client libraries, the gcloud CLI, or Terraform
The Cloud Client Libraries, the gcloud CLI, and Terraform, can automatically obtain external credentials, and use these credentials to impersonate a service account. To let libraries and tools complete this process, you have to provide a credential configuration file. This file defines the following:
- Where to obtain external credentials from
- Which workload identity pool and provider to use
- Which service account to impersonate
The way credential configuration files are used by the client libraries depends on your external identity provider:
AWS
The client libraries automatically obtain temporary credentials from the EC2 instance metadata.
Azure
The client libraries automatically obtain access tokens from the Azure Instance Metadata Service (IMDS).
GitHub Actions
Because the parameters required to obtain a GitHub ID token vary for each workflow execution, you can't use a static credential configuration file in a GitHub Actions workflow.
Use the google-github-actions/auth
action to automatically generate a credential configuration file during
workflow execution. Client libraries and tools such as terraform can then
use this credential configuration file to automatically obtain Google credentials.
OIDC
The client libraries obtain credentials from a local file, an HTTP URL, or a local executable:
- File-sourced credentials: tokens are loaded from a file. Another process must refresh this file with a new OIDC token before the old token expires. For example, if the token has a lifetime of 1 hour, you must refresh the file before it is 1 hour old.
- URL-sourced credentials: tokens are loaded from a local server with an
endpoint that responds to HTTP
GETrequests. The response must be an OIDC ID token, either in plain text or in JSON format. Executable-sourced credentials: tokens are loaded from a local executable. The executable must handle providing a valid, unexpired OIDC ID token in JSON format to stdout:
{ "version": 1, "success": true, "token_type": "urn:ietf:params:oauth:token-type:id_token", "id_token": "HEADER.PAYLOAD.SIGNATURE", "expiration_time": 1620499962 }These fields are required for a successful response, with the exception ofexpiration_time. Theexpiration_timefield is only required when an output file has been specified in the credential configuration.If an error occurs, it must be surfaced by the executable in the following JSON format to stdout:
{ "version": 1, "success": false, "code": "401", "message": "Caller not authorized." }These fields are all required for an error response. The code and message fields will be used by the client libraries when raising the appropriate error.Response format fields summary:
version: the version of the JSON output. Currently only version 1 is supported.success: the status of the response. When true, the response must contain the 3rd party token, token type, and expiration. The executable must also exit with exit code 0. When false, the response must contain the error code and message fields and exit with a non-zero value.token_type: the 3rd party subject token type. Supported values areurn:ietf:params:oauth:token-type:id_tokenandurn:ietf:params:oauth:token-type:jwt.id_token: the 3rd party OIDC token.expiration_time: the OIDC token expiration time in seconds (unix epoch time).code: the error code string.message: the error message.
The client libraries will populate the following environment variables when the executable is run:
GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE: the audience field from the credential configuration. Always present.GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE: the expected subject token type. Always present.GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL: the service account email. Only present when service account impersonation is used.GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE: the output file location from the credential configuration. Only present when specified in the credential configuration.
These environment variables can be used by the executable to avoid hardcoding these values.
To enable this credential sourcing method with the client libraries, the
GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLESenvironment variable must be set to1.
OIDC (AD FS)
The client libraries can obtain credentials from a local file or an HTTP URL, but don't support Integrated Windows Authentication (IWA) directly. To obtain an access token for the logged-on user and store it to a local file, use the following PowerShell command:
(Invoke-RestMethod `
-Uri "https://ADFS_DOMAIN/adfs/oauth2/token/" `
-Method POST `
-Body @{
client_id = 'CLIENT_ID'
grant_type = 'client_credentials'
scope = 'openid'
resource = 'RELYING_PARTY_ID'
use_windows_client_authentication = 'true'
} `
-UseDefaultCredentials).access_token | Out-File -Encoding ASCII TOKEN_FILEPATH
Replace the following values:
ADFS_DOMAIN: public domain name of the AD FS server of farm.CLIENT_ID: client ID of the application registration in AD FS.RELYING_PARTY_ID: relying party identifier that you used when creating a Web API application for the workload identity pool in AD FS.TOKEN_FILEPATH: path to a temporary file to save the AD FS token in. Make sure the file is stored in a location where only authorized users can read the contents of the file.
Because the short-lived Google credentials are only valid for a limited time (1 hour by default), you must periodically re-run this command.
SAML
The client libraries obtain credentials from a local file, an HTTP URL, or a local executable:
- File-sourced credentials: assertions are loaded from a file. Another process must refresh this file with a new base64-encoded SAML assertion before the old assertion expires. For example, if the assertion has a lifetime of 1 hour, you must refresh the file before it is 1 hour old.
- URL-sourced credentials: assertions are loaded from a local server
with an endpoint that responds to HTTP
GETrequests. The response must be either a base64-encoded SAML assertion or JSON containing a base64-encoded SAML assertion. Executable-sourced credentials: assertions are loaded from a local executable. The executable must handle providing a valid, unexpired SAML assertion in JSON format to stdout:
{ "version": 1, "success": true, "token_type": "urn:ietf:params:oauth:token-type:saml2", "saml_response": "...", "expiration_time": 1620499962 }These fields are required for a successful response, with the exception ofexpiration_time. Theexpiration_timefield is only required when an output file has been specified in the credential configuration.If an error occurs, it must be surfaced by the executable in the following JSON format to stdout:
{ "version": 1, "success": false, "code": "401", "message": "Caller not authorized." }These fields are all required for an error response. The code and message fields will be used by the client libraries when raising the appropriate error.Response format fields summary:
version: the version of the JSON output. Currently only version 1 is supported.success: the status of the response. When true, the response must contain the 3rd party token, token type, and expiration. The executable must also exit with exit code 0. When false, the response must contain the error code and message fields and exit with a non-zero value.token_type: the 3rd party subject token type. Must beurn:ietf:params:oauth:token-type:saml2.saml_response: the 3rd party SAML response.expiration_time: the 3rd party SAML response expiration time in seconds (unix epoch time).code: the error code string.message: the error message.
The client libraries will populate the following environment variables when the executable is run: *
GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE: the audience field from the credential configuration. Always present. *GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE: the expected subject token type. Always present. *GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL: the service account email. Only present when service account impersonation is used. *GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE: the output file location from the credential configuration. Only present when specified in the credential configuration.These environment variables can be used by the executable to avoid hardcoding these values.
To enable this credential sourcing method with the client libraries, the
GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLESenvironment variable must be set to1.
Follow these steps to let client libraries or Terraform use workload identity federation to authenticate:
Create a credential configuration file:
Console
Download a credential configuration file in the Google Cloud console:
In the Google Cloud console, go to the Workload Identity Pools page.
Find the workload identity pool that contains the identity provider you want to use and click on it.
Select Connected service accounts.
Find the service account you want to use and click Download.
In the Configure your application dialog, select the provider that contains the external identities that will impersonate the service account.
Provide the following additional settings:
AWS
No additional settings required.
Azure
Resource path: application ID URI of the Azure application
OIDC
OIDC token path: local file path or URL to obtain credentials from.
Format type: format of the file or URL response where the ID token is retrieved from.
Subject token field name: field in the response that contains the token (if format type is
json).SAML
SAML assertion path: local file path or URL to obtain credentials from.
Format type: format of the file or URL response where the assertion is retrieved from.
Assertion field name: field in the response that contains the assertion (if format type is
json).Select Download config to download the credential configuration file, then click Dismiss.
gcloud
Create a credential configuration file by using
gcloud iam workload-identity-pools create-cred-config:AWS
Create a credential configuration file that lets the library obtain an access token from EC2 instance metadata:
gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --aws \ --output-file=FILEPATH.jsonReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration to
If you are using AWS IMDSv2, an additional flag
--enable-imdsv2needs to be added to thegcloud iam workload-identity-pools create-cred-configcommand:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --aws \ --enable-imdsv2 \ --output-file=FILEPATH.jsonAzure
Create a credential configuration file that lets the library obtain an access token from the Azure Instance Metadata Service (IMDS):
gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --azure \ --app-id-uri APPLICATION_ID_URI \ --output-file=FILEPATH.jsonReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.APPLICATION_ID_URI: application ID URI of the Azure applicationFILEPATH: file to save configuration to
OIDC
To use file-sourced credentials, use the
--credential-source-fileflag:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --credential-source-file=TOKEN_FILEPATH \ --credential-source-type=SOURCE_TYPE \ --credential-source-field-name=FIELD_NAMEReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration toTOKEN_FILEPATH: path where OIDC ID tokens are storedSOURCE_TYPE: format of the OIDC ID token file, set totext(default) orjsonFIELD_NAME: field in the text file that contains the token (ifSOURCE_TYPEisjson)
To use URL-sourced credentials, use the
--credential-source-urlflag:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --credential-source-url="TOKEN_URL" \ --credential-source-headers="KEY_1=VALUE_1,KEY_2=VALUE_2" \ --credential-source-type=SOURCE_TYPE \ --credential-source-field-name=FIELD_NAMEReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration toTOKEN_URL: URL to retrieve OIDC ID token fromKEY_n,VALUE_n: custom headers to include in HTTP request toTOKEN_URLSOURCE_TYPE: format of the OIDC ID token file, set totext(default) orjsonFIELD_NAME: field in the text file that contains the token (ifSOURCE_TYPEisjson)
To use Executable-sourced credentials, use the
--executable-commandflag:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --executable-command=EXECUTABLE_COMMAND \ --executable-timeout-millis=EXECUTABLE_TIMEOUT \ --executable-output-file=EXECUTABLE_OUTPUT_FILEReplace the following values:
PROJECT_NUMBER: the project number of the project that contains the workload identity poolPOOL_ID: the ID of the workload identity poolPROVIDER_ID: the ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: the email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: the file to save configuration toEXECUTABLE_COMMAND: the full command, including arguments, to run to retrieve the OIDC ID token (e.g. --executable-command="/path/to/command --foo=bar")EXECUTABLE_TIMEOUT: the optional duration in milliseconds to wait for the executable to run (defaults to 30s)EXECUTABLE_OUTPUT_FILE: this file path points to the 3PI credentials generated by the executable. This is useful for caching the credentials. By specifying this path, the Auth libraries will first check for its existence before running the executable.
OIDC (AD FS)
Create a credential configuration file that lets the library read the AD FS access token from the temporary file:
gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --credential-source-file=TOKEN_FILEPATH \ --credential-source-type=textReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration toTOKEN_FILEPATH: path to temporary file containing the AD FS token
SAML
To use file-sourced credentials, use the
--credential-source-fileflag:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --credential-source-file=TOKEN_FILEPATH \ --credential-source-type=SOURCE_TYPE \ --credential-source-field-name=FIELD_NAME \ --subject-token-type=urn:ietf:params:oauth:token-type:saml2Replace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration toTOKEN_FILEPATH: path where SAML assertions are storedSOURCE_TYPE: format of the SAML assertion file, set totext(default) orjsonFIELD_NAME: field in the text file that contains the assertion (ifSOURCE_TYPEisjson)
To use URL-sourced credentials, use the
--credential-source-urlflag:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --credential-source-url="TOKEN_URL" \ --credential-source-headers="KEY_1=VALUE_1,KEY_2=VALUE_2" \ --credential-source-type=source_type \ --credential-source-field-name=field_name --subject-token-type=urn:ietf:params:oauth:token-type:saml2Replace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration toTOKEN_URL: URL to retrieve SAML assertion fromKEY_n,VALUE_n: custom headers to include in HTTP request toTOKEN_URLSOURCE_TYPE: format of the SAML assertion file, set totext(default) orjsonFIELD_NAME: field in the text file that contains the assertion (ifSOURCE_TYPEisjson)
To use Executable-sourced credentials, use the
--executable-commandflag:gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --service-account-token-lifetime-seconds=SERVICE_ACCOUNT_TOKEN_LIFETIME \ --output-file=FILEPATH.json \ --executable-command=EXECUTABLE_COMMAND \ --executable-timeout-millis=EXECUTABLE_TIMEOUT \ --executable-output-file=EXECUTABLE_OUTPUT_FILEReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service accountSERVICE_ACCOUNT_TOKEN_LIFETIME: the desired lifetime duration of the service account access token, in seconds; this defaults to one hour when not provided. If a lifetime greater than one hour is required, the service account must be added as an allowed value in an Organization Policy that enforces theconstraints/iam.allowServiceAccountCredentialLifetimeExtensionconstraint.FILEPATH: file to save configuration toEXECUTABLE_COMMAND: full command to run to retrieve the SAML assertionnEXECUTABLE_TIMEOUT: the optional duration in milliseconds to wait for the executable to run (defaults to 30s)EXECUTABLE_OUTPUT_FILE: the optional output file which stores the executable response
GitHub Actions
Edit your GitHub Actions YAML file and add the following:
Allow the job to fetch a GitHub ID token by adding the following configuration:
permissions: id-token: write contents: read
Add a step to create a credentials configuration file:
- id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v0.3.1' with: create_credentials_file: true workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID' service_account: 'SERVICE_ACCOUNT_EMAIL'
Replace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service account
Example:
jobs: build: # Allow the job to fetch a GitHub ID token permissions: id-token: write contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v0.3.1' with: create_credentials_file: true workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID' service_account: 'SERVICE_ACCOUNT_EMAIL'Initialize an environment variable
GOOGLE_APPLICATION_CREDENTIALSand point it to the credential configuration file:Bash
export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/FILEPATH.json
whereFILEPATHis the relative file path to the credential configuration file.PowerShell
$env:GOOGLE_APPLICATION_CREDENTIALS = Resolve-Path 'FILEPATH.json'
whereFILEPATHis the relative file path to the credential configuration file.GitHub Actions YAML
Thegoogle-github-actions/authaction automatically initializesGOOGLE_APPLICATION_CREDENTIALS.Use a client library that supports workload identity federation and can find credentials automatically:
C++
Most of the Google Cloud Client Libraries for C++ support identity federation by using a
ChannelCredentialsobject, which is created by callinggrpc::GoogleDefaultCredentials(). To initialize this credential, you must build the client libraries with version 1.36.0 or later of gRPC.The Cloud Storage Client Library for C++ uses the REST API, not gRPC, so it does not support identity federation.
Go
Client libraries for Go support identity federation if they use version v0.0.0-20210218202405-ba52d332ba99 or later of the
golang.org/x/oauth2module.To check which version of this module your client library uses, run the following commands:
cd $GOPATH/src/cloud.google.com/go go list -m golang.org/x/oauth2Java
Client libraries for Java support identity federation if they use version 0.24.0 or later of the
com.google.auth:google-auth-library-oauth2-httpartifact.To check which version of this artifact your client library uses, run the following Maven command in your application directory:
mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-httpNode.js
Client libraries for Node.js support identity federation if they use version 7.0.2 or later of the
google-auth-librarypackage.To check which version of this package your client library uses, run the following command in your application directory:
npm list google-auth-libraryWhen you create a
GoogleAuthobject, you can specify a project ID, or you can allowGoogleAuthto find the project ID automatically. To find the project ID automatically, the service account in the configuration file must have the Browser role (roles/browser), or a role with equivalent permissions, on your project. For details, see theREADMEfor thegoogle-auth-librarypackage.Python
Client libraries for Python support identity federation if they use version 1.27.0 or later of the
google-authpackage.To check which version of this package your client library uses, run the following command in the environment where the package is installed:
pip show google-authTo specify a project ID for the authentication client, you can set the
GOOGLE_CLOUD_PROJECTenvironment variable, or you can allow the client to find the project ID automatically. To find the project ID automatically, the service account in the configuration file must have the Browser role (roles/browser), or a role with equivalent permissions, on your project. For details, see the user guide for thegoogle-authpackage.gcloud
To authenticate using workload identity federation, use the
gcloud auth logincommand:gcloud auth login --cred-file=FILEPATH.json
where
FILEPATHis the file path to the credential configuration file.Support for workload identity federation in gcloud CLI is available in version 363.0.0 and later versions of the gcloud CLI.
Terraform
The Google Cloud provider supports workload identity federation if you use version 3.61.0 or later:
terraform { required_providers { google = { source = "hashicorp/google" version = "~> 3.61.0" } } }gsutil
To authenticate using workload identity federation, use one of the following methods:
When using gsutil in conjunction with gcloud, sign in as normal:
gcloud auth login --cred-file=FILEPATH.json
When using gsutil as a stand-alone command-line application, edit the .boto file to include the following section:
[Credentials] gs_external_account_file = FILEPATH
FILEPATHin both cases is the file path to the credential configuration file.Support for workload identity federation in gsutil is available in version 379.0.0 and later versions of the gcloud CLI.
bq
To authenticate using workload identity federation, use the
gcloud auth logincommand:gcloud auth login --cred-file=FILEPATH.json
where
FILEPATHis the file path to the credential configuration file.Support for workload identity federation in bq is available in version 390.0.0 and later versions of the gcloud CLI.
Authenticating by using the REST API
If you can't use the client libraries, you can follow these steps to let an external identity obtain a short-lived access token by using the REST API:
Obtain credentials from your external identity provider:
AWS
Create a JSON document that contains the information that you would normally include in a request to the AWS
GetCallerIdentity()endpoint, including a valid request signature.Workload identity federation refers to this JSON document as a
GetCallerIdentitytoken. The token lets workload identity federation verify the identity without revealing the AWS secret access key.A
GetCallerIdentitytoken looks similar to the following:{ "url": "https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15", "method": "POST", "headers": [ { "key": "Authorization", "value" : "AWS4-HMAC-SHA256 Credential=AKIASOZTBDV4D7ABCDEDF/20200228/us-east-1/sts/aws4_request, SignedHeaders=host;x-amz-date,Signature=abcedefdfedfd" }, { "key": "host", "value": "sts.amazonaws.com" }, { "key": "x-amz-date", "value": "20200228T225005Z" }, { "key": "x-goog-cloud-target-resource", "value": "//iam.googleapis.com/projects/12345678/locations/global/workloadIdentityPools/my-pool/providers/my-aws-provider" }, { "key": "x-amz-security-token", "value": "GizFWJTqYX...xJ55YoJ8E9HNU=" } ] }The token contains the following fields:
url: the URL of the AWS STS endpoint forGetCallerIdentity(), with the body of a standardGetCallerIdentity()request appended as query parameters. For example,https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15. Regional endpoints are also supported.method: the HTTP request method:POST.headers: the HTTP request headers, which must include:Authorization: the request signature.host: the hostname of theurlfield; for example,sts.amazonaws.com.x-amz-date: the time you will send the request, formatted as an ISO 8601 Basic string. This value is typically set to the current time and is used to help prevent replay attacks.x-goog-cloud-target-resource: the full resource name of the identity provider without ahttps:prefix. For example://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
x-amz-security-token: session token. Only required if you are using temporary security credentials.
The following example creates a URL-encoded
GetCallerIdentitytoken. Extract the URL-encoded token for later use. It also creates a human-readable token just for your reference:Initialize the following variables:
Bash
SUBJECT_TOKEN_TYPE="urn:ietf:params:aws:token-type:aws4_request" SUBJECT_TOKEN=TOKEN
PowerShell
$SubjectTokenType = "urn:ietf:params:aws:token-type:aws4_request" $SubjectToken = "TOKEN"
Where
TOKENis the URL encodedGetCallerIdentitytoken that was generated by the script above.Azure
Connect to an Azure VM that has an assigned managed identity and obtain an access token from the Azure Instance Metadata Service (IMDS):
Bash
SUBJECT_TOKEN_TYPE="urn:ietf:params:oauth:token-type:jwt" SUBJECT_TOKEN=$(curl \ "http://169.254.169.254/metadata/identity/oauth2/token?resource=APP_ID_URI&api-version=2018-02-01" \ -H "Metadata: true" | jq -r .access_token) echo $SUBJECT_TOKEN
This command uses the
jqtool.jqis available by default in Cloud Shell.PowerShell
$SubjectTokenType = "urn:ietf:params:oauth:token-type:jwt" $SubjectToken = (Invoke-RestMethod ` -Uri "http://169.254.169.254/metadata/identity/oauth2/token?resource=APP_ID_URI&api-version=2018-02-01" ` -Headers @{Metadata="true"}).access_token Write-Host $SubjectTokenWhere
APP_ID_URIis the Application ID URI of the application that you've configured for workload identity federation.GitHub Actions
Use the
google-github-actions/authto obtain a GitHub ID token and to exchange it against a short-lived access token:Allow the job to fetch a GitHub ID token by adding the following configuration:
permissions: id-token: write contents: read
Add a step to generate an access token and make it available in a variable
${{ steps.auth.outputs.access_token }}:- id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v0.3.1' with: token_format: 'access_token' workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID' service_account: 'SERVICE_ACCOUNT_EMAIL'
Replace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool providerSERVICE_ACCOUNT_EMAIL: email address of the service account
Example:
jobs: build: # Allow the job to fetch a GitHub ID token permissions: id-token: write contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v0.3.1' with: token_format: 'access_token' workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID' service_account: 'SERVICE_ACCOUNT_EMAIL'Skip the following steps.
OIDC
Obtain a token from your external identity provider and initialize the following variables:
Bash
SUBJECT_TOKEN_TYPE="urn:ietf:params:oauth:token-type:jwt" SUBJECT_TOKEN=TOKEN
PowerShell
$SubjectTokenType = "urn:ietf:params:oauth:token-type:jwt" $SubjectToken = "TOKEN"
Where
TOKENis the token issued by your external identity provider.OIDC (AD FS)
Use the following PowerShell commands to authenticate to AD FS by using IWA and obtain an access token:
$SubjectTokenType = "urn:ietf:params:oauth:token-type:jwt" $SubjectToken = (Invoke-RestMethod ` -Uri "https://ADFS_DOMAIN/adfs/oauth2/token/" ` -Method POST ` -Body @{ client_id = 'CLIENT_ID' grant_type = 'client_credentials' scope = 'openid' resource = 'RELYING_PARTY_ID' use_windows_client_authentication = 'true' } ` -Credential USER).access_tokenReplace the following values:
ADFS_DOMAIN: public domain name of the AD FS server or farm.CLIENT_ID: client ID of the application registration in AD FS.RELYING_PARTY_ID: relying party identifier that you used when creating a Web API application for the workload identity pool in AD FS. You only need this parameter if you use a custom relying party identifier.USER: Active Directory user to use for IWA. Alternatively, replace-Credentialwith-UseDefaultCredentialsto use your current credentials.
SAML
Obtain an assertion from your external identity provider and initialize a variable:
Bash
SUBJECT_TOKEN_TYPE="urn:ietf:params:oauth:token-type:saml2" SUBJECT_TOKEN=ASSERTION
PowerShell
$SubjectTokenType = "urn:ietf:params:oauth:token-type:saml2" $SubjectToken = "ASSERTION"
Where
ASSERTIONis the base64-encoded-encoded assertion issued by your external identity provider.Use the Security Token Service API to exchange the credential against a short-lived access token:
Bash
STS_TOKEN=$(curl -0 -X POST https://sts.googleapis.com/v1/token \ -H 'Content-Type: text/json; charset=utf-8' \ -d @- <<EOF | jq -r .access_token { "audience" : "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID", "grantType" : "urn:ietf:params:oauth:grant-type:token-exchange", "requestedTokenType" : "urn:ietf:params:oauth:token-type:access_token", "scope" : "https://www.googleapis.com/auth/cloud-platform", "subjectTokenType" : "$SUBJECT_TOKEN_TYPE", "subjectToken" : "$SUBJECT_TOKEN" } EOF ) echo $STS_TOKENPowerShell
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 $StsToken = (Invoke-RestMethod ` -Method POST ` -Uri "https://sts.googleapis.com/v1/token" ` -ContentType "application/json" ` -Body (@{ "audience" = "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID" "grantType" = "urn:ietf:params:oauth:grant-type:token-exchange" "requestedTokenType" = "urn:ietf:params:oauth:token-type:access_token" "scope" = "https://www.googleapis.com/auth/cloud-platform" "subjectTokenType" = $SubjectTokenType "subjectToken" = $SubjectToken } | ConvertTo-Json)).access_token Write-Host $StsTokenReplace the following values:
PROJECT_NUMBER: project number of the project that contains the workload identity poolPOOL_ID: ID of the workload identity poolPROVIDER_ID: ID of the workload identity pool provider
Use the token from the Security Token Service to invoke the
generateAccessTokenmethod of the IAM Service Account Credentials API to obtain an access token:Bash
ACCESS_TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken \ -H "Content-Type: text/json; charset=utf-8" \ -H "Authorization: Bearer $STS_TOKEN" \ -d @- <<EOF | jq -r .accessToken { "scope": [ "https://www.googleapis.com/auth/cloud-platform" ] } EOF ) echo $ACCESS_TOKENPowerShell
$AccessToken = (Invoke-RestMethod ` -Method POST ` -Uri "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken" ` -Headers @{ "Authorization" = "Bearer $StsToken" } ` -ContentType "application/json" ` -Body (@{ "scope" = , "https://www.googleapis.com/auth/cloud-platform" } | ConvertTo-Json)).accessToken Write-Host $AccessTokenReplace
SERVICE_ACCOUNT_EMAILwith the email address of the service account.
Verification of external credentials
The Security Token Service API uses the following steps to validate credentials issued by an external identity provider.
AWS
Verify the following fields in the
GetCallerIdentitytoken:- The
urlshould be an HTTPS URI with a hostname equal tosts.amazonaws.com(or regional subdomain) and no port. Exactly the following query parameters are present:action=getcalleridentityversion(any value)
- The
methodisPOST - Exactly the following
headersare present:x-amz-date,authorization,host,x-goog-cloud-target-resource,x-amz-security-token(optional)- The value of
x-goog-cloud-target-resourceis the resource name for the workload identity pool provider. - The value of
x-amz-dateis at most 15 minutes in the past and not in the future.
- The value of
- The
Execute request against
sts.amazonaws.comor the relevant regional subdomain and verify that the result is successful and that the AWS account ID matches the configured account ID for the workload identity pool provider.
Azure
Azure tokens are OIDC tokens and are verified in the same way as OIDC tokens.
GitHub Actions
GitHub tokens are OIDC tokens and are verified in the same way as OIDC tokens.
OIDC
OIDC tokens are verified following the OIDC specification. Specifically, the Security Token Service executes the following steps:
Discovery document and signature verification:
- Construct the discovery endpoint URI by appending
/.well-known/openid-configurationto the issuer configured in the workload identity pool provider and fetch the OIDC discovery document. - Verify that the
issuerclaim in the discovery document is equal to the issuer configured in the workload identity pool provider. STS has custom verification logic for the following issuers that do not comply with the OIDC specification:- Oracle Cloud (
https://*.identity.oraclecloud.com) - Microsoft (
https://login.microsoftonline.com/common/v2.0,https://login.microsoftonline.com/consumers/v2.0,https://login.microsoftonline.com/organizations/v2.0)
- Oracle Cloud (
- Retrieve the JSON Web Key Set (JWKS) from the jwks_uri listed in the discovery document.
- If a
kidclaim is present in the JWT header, verify the JWT signature using the key from the JWKS with the matching key ID, or reject the token if no matching key is found. If nokidclaim is present in the JWT header, attempt to verify the JWT signature using each key listed in the JWKS. The signature is accepted if any key can be used to verify the signature.
- Construct the discovery endpoint URI by appending
Header verification:
- An
algclaim must be present and be equal to eitherRS256orES256.
- An
Payload verification:
- An
issclaim must be present and equal to theissuerclaim in the discovery document. STS has custom verification logic for the following issuers that do not comply with the OIDC specification:- Oracle Cloud (
https://*.identity.oraclecloud.com) - Microsoft (
https://login.microsoftonline.com/common/v2.0,https://login.microsoftonline.com/consumers/v2.0,https://login.microsoftonline.com/organizations/v2.0)
- Oracle Cloud (
- An
audclaim must be present and is equal tohttps://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID. If alternative allowed_audiences are configured, theaudclaim must instead be equal to one of those values. - An
expclaim must be present and is in the future - An
iatclaim must be present and is in the past - The value of
expmust be greater than the value ofiatby at most 24 hours.
- An
SAML
- Base64-decode and unmarshal the SAML credential into either a
ResponseorAssertionobject. If the SAML credential is unmarshalled into a
Responseobject, verify the following:- The response StatusCode is equal to
urn:oasis:names:tc:SAML:2.0:status:Success. - Exactly one
Assertionis present. - At least one of the
Responseor theAssertionis signed. For each signature, attempt to verify the signature using each X.509 certificate configured in the workload identity pool provider. The signature is accepted if any of the certificates successfully verifies the signature. - If the
Responseis signed, theResponse'sIssuermust be present and equal to the SAML identity provider's Entity ID configured in the workload identity pool provider. Also verify that theFormatis either omitted or is equal tourn:oasis:names:tc:SAML:2.0:nameid-format:entity.
- The response StatusCode is equal to
If the SAML credential is unmarshalled into an
Assertionobject, verify the following:- The
Assertionis signed. For each signature, attempt to verify the signature using each X.509 certificate configured in the workload identity pool provider. The signature is accepted if any of the certificates successfully verifies the signature.
- The
Regardless of whether the SAML credential was unmarshalled into a
ResponseorAssertionobject, verify theAssertioncontains the following attributes:- An
Issuermust be present and is equal to the SAML identity provider's Entity ID configured in the workload identity pool provider. TheFormatofIssueris either omitted or has a value equal tourn:oasis:names:tc:SAML:2.0:nameid-format:entity. - An
IssueInstantmust be present and is less than 1 hour in the past. - A
Subjectmust be present and contain the following attributes:- A
NameIDmust be present. - Exactly one
SubjectConfirmationmust be present and have aMethodequal tourn:oasis:names:tc:SAML:2.0:cm:bearer. ANotOnOrAftermust be present in theSubjectConfirmationDataand is in the future. - A
NotBeforeis not present.
- A
- A
Conditionsmust be present and contain the following attributes:- If a
NotBeforeis present, it must be in the past. - If a
NotOnOrAfteris present, it must be in the future. - At least one
AudienceRestrictionmust be present. AllAudienceRestrictions must contain anAudienceequal to the workload identity pool provider's resource name.
- If a
- At least one
AuthnStatementmust be present. - If any
SessionNotOnOrAfters are present, they all must be in the future.
- An
In addition to the protocol-specific verification steps above, the Security Token Service API also verifies that the attribute condition is met.
What's next
- Learn how to configure workload identity federation.
- Read more about workload identity federation.
- See how you can manage workload identity pools and providers.