Obtaining short-lived credentials with identity federation

Stay organized with collections Save and categorize content based on your preferences.

This guide describes how you can use a workload identity pool and provider to obtain short-lived credentials by following this process:

  1. Obtain a credential from the trusted identity provider.
  2. Exchange the credential for a token from the Security Token Service.
  3. 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

  1. Enable the IAM, Security Token Service, and Service Account Credentials APIs.

    Enable the APIs

  2. Federate with an external identity provider by creating a workload identity pool and provider.

  3. Create a service account that you want external identities to impersonate.

  4. 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.subject attribute.
  • For a group of external identities, write an attribute condition that checks the google.groups attribute or a custom attribute attribute.NAME.
  • For all external identities in the workload identity pool, you do not use an attribute condition.

Console

  1. In the Google Cloud console, go to the Workload Identity Pools page.

    Go to Workload Identity Pools

  2. Find the workload identity pool you want to update and click on it.

  3. Click Grant access.

  4. In the Service account drop-down list, select the service account that the external identities will impersonate.

  5. 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 to subject and Attribute value to the value of the sub claim 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.

  6. Click Save.

  7. Click Dismiss.

gcloud

  1. 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 pool
    • POOL_ID: pool ID of the workload identity pool
    • SUBJECT: expected value for the attribute that you've mapped to google.subject
    • GROUP: expected value for the attribute that you've mapped to google.groups
    • ATTRIBUTE_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\)
    
  2. 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 account
    • MEMBER_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 GET requests. 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 of expiration_time. The expiration_time field 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 are urn:ietf:params:oauth:token-type:id_token and urn: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_EXECUTABLES environment variable must be set to 1.

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 GET requests. 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 of expiration_time. The expiration_time field 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 be urn: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_EXECUTABLES environment variable must be set to 1.

Follow these steps to let client libraries or Terraform use workload identity federation to authenticate:

  1. Create a credential configuration file:

    Console

    Download a credential configuration file in the Google Cloud console:

    1. In the Google Cloud console, go to the Workload Identity Pools page.

      Go to Workload Identity Pools

    2. Find the workload identity pool that contains the identity provider you want to use and click on it.

    3. Select Connected service accounts.

    4. Find the service account you want to use and click Download.

    5. In the Configure your application dialog, select the provider that contains the external identities that will impersonate the service account.

    6. 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).

    7. 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.json
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to

    If you are using AWS IMDSv2, an additional flag --enable-imdsv2 needs to be added to the gcloud iam workload-identity-pools create-cred-config command:

    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.json
    

    Azure

    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.json
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • APPLICATION_ID_URI: application ID URI of the Azure application
    • FILEPATH: file to save configuration to

    OIDC

    To use file-sourced credentials, use the --credential-source-file flag:

    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
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to
    • TOKEN_FILEPATH: path where OIDC ID tokens are stored
    • SOURCE_TYPE: format of the OIDC ID token file, set to text (default) or json
    • FIELD_NAME: field in the text file that contains the token (if SOURCE_TYPE is json)

    To use URL-sourced credentials, use the --credential-source-url flag:

    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
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to
    • TOKEN_URL: URL to retrieve OIDC ID token from
    • KEY_n, VALUE_n: custom headers to include in HTTP request to TOKEN_URL
    • SOURCE_TYPE: format of the OIDC ID token file, set to text (default) or json
    • FIELD_NAME: field in the text file that contains the token (if SOURCE_TYPE is json)

    To use Executable-sourced credentials, use the --executable-command flag:

    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_FILE
    

    Replace the following values:

    • PROJECT_NUMBER: the project number of the project that contains the workload identity pool
    • POOL_ID: the ID of the workload identity pool
    • PROVIDER_ID: the ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: the email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: the file to save configuration to
    • EXECUTABLE_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=text
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to
    • TOKEN_FILEPATH: path to temporary file containing the AD FS token

    SAML

    To use file-sourced credentials, use the --credential-source-file flag:

    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:saml2
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to
    • TOKEN_FILEPATH: path where SAML assertions are stored
    • SOURCE_TYPE: format of the SAML assertion file, set to text (default) or json
    • FIELD_NAME: field in the text file that contains the assertion (if SOURCE_TYPE is json)

    To use URL-sourced credentials, use the --credential-source-url flag:

    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:saml2
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to
    • TOKEN_URL: URL to retrieve SAML assertion from
    • KEY_n, VALUE_n: custom headers to include in HTTP request to TOKEN_URL
    • SOURCE_TYPE: format of the SAML assertion file, set to text (default) or json
    • FIELD_NAME: field in the text file that contains the assertion (if SOURCE_TYPE is json)

    To use Executable-sourced credentials, use the --executable-command flag:

    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_FILE
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_ACCOUNT_EMAIL: email address of the service account
    • SERVICE_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 the constraints/iam.allowServiceAccountCredentialLifetimeExtension constraint.
    • FILEPATH: file to save configuration to
    • EXECUTABLE_COMMAND: full command to run to retrieve the SAML assertionn
    • EXECUTABLE_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 pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_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'
    
  2. Initialize an environment variable GOOGLE_APPLICATION_CREDENTIALS and point it to the credential configuration file:

    Bash

      export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/FILEPATH.json
      
    where FILEPATH is the relative file path to the credential configuration file.

    PowerShell

      $env:GOOGLE_APPLICATION_CREDENTIALS = Resolve-Path 'FILEPATH.json'
      
    where FILEPATH is the relative file path to the credential configuration file.

    GitHub Actions YAML

    The google-github-actions/auth action automatically initializes GOOGLE_APPLICATION_CREDENTIALS.
  3. 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 ChannelCredentials object, which is created by calling grpc::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/oauth2 module.

    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/oauth2
    

    Java

    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-http artifact.

    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-http
    

    Node.js

    Client libraries for Node.js support identity federation if they use version 7.0.2 or later of the google-auth-library package.

    To check which version of this package your client library uses, run the following command in your application directory:

    npm list google-auth-library
    

    When you create a GoogleAuth object, you can specify a project ID, or you can allow GoogleAuth 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 README for the google-auth-library package.

    Python

    Client libraries for Python support identity federation if they use version 1.27.0 or later of the google-auth package.

    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-auth
    

    To specify a project ID for the authentication client, you can set the GOOGLE_CLOUD_PROJECT environment 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 the google-auth package.

    gcloud

    To authenticate using workload identity federation, use the gcloud auth login command:

    gcloud auth login --cred-file=FILEPATH.json
    

    where FILEPATH is 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
    

    FILEPATH in 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 login command:

    gcloud auth login --cred-file=FILEPATH.json
    

    where FILEPATH is 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:

  1. 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 GetCallerIdentity token. The token lets workload identity federation verify the identity without revealing the AWS secret access key.

    A GetCallerIdentity token 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 for GetCallerIdentity(), with the body of a standard GetCallerIdentity() 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 the url field; 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 a https: 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 GetCallerIdentity token. Extract the URL-encoded token for later use. It also creates a human-readable token just for your reference:

    import json
    import urllib
    
    import boto3
    from botocore.auth import SigV4Auth
    from botocore.awsrequest import AWSRequest
    
    
    def create_token_aws(project_number: str, pool_id: str, provider_id: str) -> None:
        # Prepare a GetCallerIdentity request.
        request = AWSRequest(
            method="POST",
            url="https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15",
            headers={
                "Host": "sts.amazonaws.com",
                "x-goog-cloud-target-resource": f"//iam.googleapis.com/projects/{project_number}/locations/global/workloadIdentityPools/{pool_id}/providers/{provider_id}"
            })
    
        # Set the session credentials and Sign the request.
        # get_credentials loads the required credentials as environment variables.
        # Refer:
        # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html
        SigV4Auth(boto3.Session().get_credentials(), "sts", "us-east-1").add_auth(request)
    
        # Create token from signed request.
        token = {
            "url": request.url,
            "method": request.method,
            "headers": []
        }
        for key, value in request.headers.items():
            token["headers"].append({"key": key, "value": value})
    
        # The token lets workload identity federation verify the identity without revealing the AWS secret access key.
        print("Token:\n%s" % json.dumps(token, indent=2, sort_keys=True))
        print("URL encoded token:\n%s" % urllib.parse.quote(json.dumps(token)))
    
    
    def main():
        # TODO(Developer): Replace the below credentials.
        # project_number: Google Project number (not the project id)
        project_number = "my-project-number"
        pool_id = "my-pool-id"
        provider_id = "my-provider-id"
    
        create_token_aws(project_number, pool_id, provider_id)
    
    
    if __name__ == "__main__":
        main()

    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 TOKEN is the URL encoded GetCallerIdentity token 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 jq tool. jq is 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 $SubjectToken
    

    Where APP_ID_URI is the Application ID URI of the application that you've configured for workload identity federation.

    GitHub Actions

    Use the google-github-actions/auth to 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 pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
    • SERVICE_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 TOKEN is 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_token
    

    Replace 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 -Credential with -UseDefaultCredentials to 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 ASSERTION is the base64-encoded-encoded assertion issued by your external identity provider.

  2. 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_TOKEN
    

    PowerShell

    [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 $StsToken
    

    Replace the following values:

    • PROJECT_NUMBER: project number of the project that contains the workload identity pool
    • POOL_ID: ID of the workload identity pool
    • PROVIDER_ID: ID of the workload identity pool provider
  3. Use the token from the Security Token Service to invoke the generateAccessToken method 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_TOKEN
    

    PowerShell

    $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 $AccessToken
    

    Replace SERVICE_ACCOUNT_EMAIL with 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 GetCallerIdentity token:

    • The url should be an HTTPS URI with a hostname equal to sts.amazonaws.com (or regional subdomain) and no port. Exactly the following query parameters are present:
      • action = getcalleridentity
      • version (any value)
    • The method is POST
    • Exactly the following headers are present: x-amz-date, authorization, host, x-goog-cloud-target-resource, x-amz-security-token (optional)
      • The value of x-goog-cloud-target-resource is the resource name for the workload identity pool provider.
      • The value of x-amz-date is at most 15 minutes in the past and not in the future.
  • Execute request against sts.amazonaws.com or 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-configuration to the issuer configured in the workload identity pool provider and fetch the OIDC discovery document.
    • Verify that the issuer claim 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)
    • Retrieve the JSON Web Key Set (JWKS) from the jwks_uri listed in the discovery document.
    • If a kid claim 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 no kid claim 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.
  • Header verification:

    • An alg claim must be present and be equal to either RS256 or ES256.
  • Payload verification:

    • An iss claim must be present and equal to the issuer claim 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)
    • An aud claim must be present and is equal to https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID. If alternative allowed_audiences are configured, the aud claim must instead be equal to one of those values.
    • An exp claim must be present and is in the future
    • An iat claim must be present and is in the past
    • The value of exp must be greater than the value of iat by at most 24 hours.

SAML

  • Base64-decode and unmarshal the SAML credential into either a Response or Assertion object.
  • If the SAML credential is unmarshalled into a Response object, verify the following:

    • The response StatusCode is equal to urn:oasis:names:tc:SAML:2.0:status:Success.
    • Exactly one Assertion is present.
    • At least one of the Response or the Assertion is 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 Response is signed, the Response's Issuer must be present and equal to the SAML identity provider's Entity ID configured in the workload identity pool provider. Also verify that the Format is either omitted or is equal to urn:oasis:names:tc:SAML:2.0:nameid-format:entity.
  • If the SAML credential is unmarshalled into an Assertion object, verify the following:

    • The Assertion is 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.
  • Regardless of whether the SAML credential was unmarshalled into a Response or Assertion object, verify the Assertion contains the following attributes:

    • An Issuer must be present and is equal to the SAML identity provider's Entity ID configured in the workload identity pool provider. The Format of Issuer is either omitted or has a value equal to urn:oasis:names:tc:SAML:2.0:nameid-format:entity.
    • An IssueInstant must be present and is less than 1 hour in the past.
    • A Subject must be present and contain the following attributes:
      • A NameID must be present.
      • Exactly one SubjectConfirmation must be present and have a Method equal to urn:oasis:names:tc:SAML:2.0:cm:bearer. A NotOnOrAfter must be present in the SubjectConfirmationData and is in the future.
      • A NotBefore is not present.
    • A Conditions must be present and contain the following attributes:
      • If a NotBefore is present, it must be in the past.
      • If a NotOnOrAfter is present, it must be in the future.
      • At least one AudienceRestriction must be present. All AudienceRestrictions must contain an Audience equal to the workload identity pool provider's resource name.
    • At least one AuthnStatement must be present.
    • If any SessionNotOnOrAfters are present, they all must be in the future.

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