Workload identity federation

This document provides an overview of identity federation for external workloads. Using identity federation, you can grant on-premises or multi-cloud workloads access to Google Cloud resources, without using a service account key.

You can use identity federation with Amazon Web Services (AWS), or with any identity provider (IdP) that supports OpenID Connect (OIDC), such as Microsoft Azure, or SAML 2.0.

Why identity federation?

Traditionally, applications running outside Google Cloud can use service account keys to access Google Cloud resources. However, service account keys are powerful credentials, and can present a security risk if they are not managed correctly.

With identity federation, you can use Identity and Access Management (IAM) to grant external identities IAM roles, including the ability to impersonate service accounts. This approach eliminates the maintenance and security burden associated with service account keys.

Workload identity pools

A workload identity pool is an entity that lets you manage external identities.

In general, we recommend creating a new pool for each non-Google Cloud environment that needs to access Google Cloud resources, such as development, staging, or production environments.

Workload identity pool providers

A workload identity pool provider is an entity that describes a relationship between Google Cloud and your IdP, including the following:

  • AWS
  • Azure Active Directory
  • On-premises Active Directory Federation Services (AD FS)
  • Okta
  • Kubernetes clusters

Workload identity federation follows the OAuth 2.0 token exchange specification. You provide a credential from your IdP to the Security Token Service, which verifies the identity on the credential, and then returns a federated token in exchange.

OIDC provider with local JWKs

To federate workloads that don't have a public OIDC endpoint, you can upload OIDC JSON Web Key Sets (JWKS) directly to the pool. This is common if you have Terraform or GitHub Enterprise hosted in your own environment or you have regulatory requirements not to expose public URLs. For more information, see Manage OIDC JWKs (Optional)

Attribute mappings

The tokens issued by your external identity provider contain one or more attributes. Some identity providers refer to these attributes as claims.

Google STS tokens also contain one or more attributes, as listed in the following table:

Attribute Description
google.subject Required. A unique identifier for the user. This attribute is used in IAM principal:// role bindings and appears in Cloud Logging logs. The value must be unique and can't exceed 127 characters.
google.groups Optional. A set of groups that the identity belongs to. This attribute is used in IAM principalSet:// role bindings to grant access to all members of a group.
attribute.NAME Optional. You can define up to 50 custom attributes and use these attributes in IAM principalSet:// role bindings to grant access to all identities with a certain attribute.

An attribute mapping defines how to derive the value of the Google STS token attribute from an external token. For each Google STS token attribute, you can define an attribute mapping, formatted as follows:

TARGET_ATTRIBUTE=SOURCE_EXPRESSION

Replace the following:

  • TARGET_ATTRIBUTE is an attribute of the Google STS token
  • SOURCE_EXPRESSION is a Common Expression Language (CEL) expression that transforms one or more attributes from the tokens issued by your external identity provider

The following list provides attribute mapping examples:

  • Assign the assertion attribute sub to google.subject:

    google.subject=assertion.sub
    
  • Concatenate multiple assertion attributes:

    google.subject="myprovider::" + assertion.aud + "::" + assertion.sub
    
  • Map a GUID-valued assertion attribute workload_id to a name, and assign the result to a custom attribute named attribute.my_display_name:

    attribute.my_display_name={
      "8bb39bdb-1cc5-4447-b7db-a19e920eb111": "Workload1",
      "55d36609-9bcf-48e0-a366-a3cf19027d2a": "Workload2"
    }[assertion.workload_id]
    
  • Use CEL logical operators and functions to set a custom attribute named attribute.environment to either prod or test, depending on the identity's Amazon Resource Name (ARN):

    attribute.environment=assertion.arn.contains(":instance-profile/Production") ? "prod" : "test"
    
  • Use the extract function to populate a custom attribute aws_role with the name of the assumed role or, if no role has been assumed, with the identity's ARN.

    attribute.aws_role=assertion.arn.contains('assumed-role') ? assertion.arn.extract('{account_arn}assumed-role/') + 'assumed-role/' + assertion.arn.extract('assumed-role/{role_name}/') : assertion.arn
    
  • split function splits a string on the provided separator value. For example, to extract the attribute username from an email address attribute by splitting its value at the @ and using the first string, use the following attribute mapping:

    attribute.username=assertion.email.split("@")[0]
    

  • join function joins a list of strings on the provided separator value. For example, to populates the custom attribute department by concatenating a list of strings with . as a separator, use the following attribute mapping:

    attribute.department=assertion.department.join(".")
    

For AWS, Google provides default mappings, which cover most common scenarios. You can also supply custom mappings.

For OIDC providers, you supply the mappings. To construct the mapping, consult the provider's documentation for a list of attributes on their credentials.

For more details, see the API documentation for the attributeMapping field.

Attribute conditions

An attribute condition is a CEL expression that can check assertion attributes and target attributes. If the attribute condition evaluates to true for a given credential, the credential is accepted. Otherwise, the credential is rejected.

You can use an attribute condition to restrict which identities can authenticate using your workload identity pool.

Attribute conditions are useful in scenarios such as the following:

  • If your workload uses an identity provider that's available to the general public, you can restrict access so only the identities you choose have access to your workload identity pool.

  • If you're using an identity provider with multiple cloud platforms, you can prevent credentials intended for use with another platform from being used with Google Cloud, and vice-versa. This helps avoid the confused deputy problem.

The attribute condition for a workload identity pool provider can use the assertion keyword, which refers to a map that represents the authentication credential issued by the identity provider. You can use dot notation to access the map's values. For example, AWS credentials include an arn value, which you can access as assertion.arn. In addition, the attribute condition can use any attribute that is defined in the provider's attribute mapping.

The following example only allows requests from identities that have a specific AWS role:

attribute.aws_role == "ROLE_MAPPING"

For more details, see the API documentation for the attributeCondition field.

Service account impersonation

The token exchange flow returns a federated access token. You can use this token to impersonate a service account and obtain a short-lived OAuth 2.0 access token. The short-lived access token lets you call any Google Cloud APIs that the service account has access to.

To impersonate a service account, grant your external identity the Workload Identity User role (roles/iam.workloadIdentityUser) on a service account with the roles required by your workload. You can grant a role to all the identities in a workload identity pool, or to specific external identities based on their attributes.

The following table describes common scenarios for granting roles:

Identities Identifier format
Single identity principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT_ATTRIBUTE_VALUE
All identities in a group principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP_ID
All identities with a specific attribute value principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE

What's next