Create short-lived credentials for a service account

This page explains how to impersonate a service account by creating short-lived credentials for that service account.

Some system architectures are designed around limited-privilege service accounts, which are designed to be used together. In this case, you might need to create your credentials from multiple service accounts.

About creating short-lived credentials

Service accounts can use short-lived credentials to authenticate calls to Google Cloud APIs, other Google APIs, and non-Google APIs. Short-lived credentials have a limited lifetime, with durations of just a few hours or shorter. Short-lived service account credentials are useful for scenarios where you need to grant limited access to resources for trusted service accounts. They also create less risk than long-lived credentials, such as service account keys.

Short-lived credentials can be represented as OAuth 2.0 access tokens, OpenID Connect ID tokens, self-signed JSON Web Tokens (JWTs), and self-signed binary objects (blobs). The most commonly used credential types are OAuth 2.0 access tokens and OpenID Connect (OIDC) ID tokens. You might use each type of token in the following scenarios:

  • OAuth 2.0 access token: An OAuth 2.0 access token is useful for authenticating access from a service account to Google Cloud APIs. Consider the following example use case: to get elevated permissions on a project, an administrator can create an OAuth 2.0 access token that belongs to a service account, then use that token to impersonate the service account when calling Google Cloud APIs. The token has a short lifetime so that the elevated permissions are temporary. Using short-lived tokens helps you implement the principle of least privilege across your identities and resources. It can also be useful when there is an emergency in a production environment, and an administrator needs a short-term elevated authorization for debugging.
  • OIDC ID token: An OIDC ID token is useful for authenticating the identity of a service account to services that accept OpenID Connect. Consider the following example use case: by creating an OIDC ID token belonging to a service account, a workload running on Google Cloud can authenticate itself to another workload deployed on a third-party cloud provider, such as a data pipeline job. If the target service is configured with OIDC, then authentication will succeed.

Direct request flow

When you create short-lived credentials for a service account using a direct request flow, the caller makes a direct request to create short-lived credentials. Two identities are involved in this flow: the caller, and the service account for which the credential is created.

If your system architecture is designed around tiers of limited-privilege service accounts, see Create short-lived credentials from multiple service accounts.

Before you begin

  • Enable the IAM and Service Account Credentials APIs.

    Enable the APIs

  • Understand IAM service accounts

  • If you haven't already, enable billing and the IAM API by following the steps in the Quickstart.

Creating a service account

To get started, create a new service account.

Providing required permissions

A direct request involves only two identities: the caller, and the service account for which the credential is created. In this flow, consider the following identities:

  • Service Account 1 (SA_1), the caller who issues a request for the short-lived credentials.
  • Service Account 2 (SA_2), the limited-privilege account for whom the credential is created.

To give SA_1 permissions to create short-lived credentials, grant it the Service Account Token Creator role (roles/iam.serviceAccountTokenCreator) on SA_2. This is an example of the SA_2 service account being treated as a resource: when you grant the role on SA_2, you update its allow policy the same way that you would update any other resource.

The following steps use the REST API to grant the role. However, you can also use the Google Cloud console or the gcloud CLI.

API

First, read the allow policy for SA_2:

The serviceAccounts.getIamPolicy method gets a service account's allow policy.

Before using any of the request data, make the following replacements:

  • PROJECT_ID: Your Google Cloud project ID. Project IDs are alphanumeric strings, like my-project.
  • SA_2: The name of Service Account 2.
  • POLICY_VERSION: The policy version to be returned. Requests should specify the most recent policy version, which is policy version 3. See Specifying a policy version when getting a policy for details.

HTTP method and URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com:getIamPolicy

Request JSON body:

{
  "options": {
    "requestedPolicyVersion": POLICY_VERSION
  }
}

To send your request, expand one of these options:

You should receive a JSON response similar to the following:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    }
  ]
}

If you have not assigned a role to the service account, the response contains only an etag value. Include that etag value in the next step.

Next, modify the allow policy to grant SA_1 the Service Account Token Creator role (roles/iam.serviceAccountTokenCreator).

For example, to modify the sample response from the previous step, add the following:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
      ]
    }
  ]
}

Finally, write the updated allow policy:

The serviceAccounts.setIamPolicy method sets an updated allow policy for the service account.

Before using any of the request data, make the following replacements:

  • PROJECT_ID: Your Google Cloud project ID. Project IDs are alphanumeric strings, like my-project.
  • SA_2: The name of Service Account 2.
  • POLICY: A JSON representation of the policy that you want to set. For more information about the format of a policy, see the Policy reference.

    For example, to set the allow policy shown in the previous step, replace POLICY with the following:

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/serviceAccountAdmin",
          "members": [
            "user:admin@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
          ]
        }
      ]
    }
    

HTTP method and URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com:setIamPolicy

Request JSON body:

{
  "policy": POLICY
}

To send your request, expand one of these options:

The response contains the updated allow policy.

Requesting short-lived credentials

After you have granted the appropriate roles to each identity, you can request short-lived credentials for the desired service account. The following credential types are supported:

Generating an OAuth 2.0 access token

By default, OAuth 2.0 access tokens are valid for a maximum of 1 hour (3,600 seconds). However, you can extend the maximum lifetime for these tokens to 12 hours (43,200 seconds). To do so, identify the service accounts that need an extended lifetime for tokens, then add these service accounts to an organization policy that includes the constraints/iam.allowServiceAccountCredentialLifetimeExtension list constraint. You can then specify a lifetime up to 43,200 seconds when you create a token for these service accounts.

To generate an OAuth 2.0 access token for a service account, do the following:

API

The Service Account Credentials API's serviceAccounts.generateAccessToken method generates an OAuth 2.0 access token for a service account.

Before using any of the request data, make the following replacements:

  • SA_NAME: The name of the service account that you want to create a token for.
  • PROJECT_ID: Your Google Cloud project ID. Project IDs are alphanumeric strings, like my-project.
  • LIFETIME: The amount of time until the access token expires, in seconds. For example, 300s.

    By default, the maximum token lifetime is 1 hour (3,600 seconds). To extend the maximum lifetime for these tokens to 12 hours (43,200 seconds), add the service account to an organization policy that includes the constraints/iam.allowServiceAccountCredentialLifetimeExtension list constraint.

HTTP method and URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:generateAccessToken

Request JSON body:

{
  "scope": [
    "https://www.googleapis.com/auth/cloud-platform"
  ],
  "lifetime": "LIFETIME"
}

To send your request, expand one of these options:

If the generateAccessToken request was successful, the response body contains an OAuth 2.0 access token and an expiration time. The accessToken can then be used to authenticate a request on behalf of the service account until the expireTime has been reached:

{
  "accessToken": "eyJ0eXAi...NiJ9",
  "expireTime": "2020-04-07T15:01:23.045123456Z"
}

Generating OpenID Connect ID tokens

OpenID Connect ID tokens are valid for 1 hour (3,600 seconds). To generate an ID token for a service account, do the following:

API

The Service Account Credentials API's serviceAccounts.generateIdToken method generates an OpenID Connect ID token for a service account.

Before using any of the request data, make the following replacements:

  • SA_NAME: The name of the service account that you want to create a token for.
  • PROJECT_ID: Your Google Cloud project ID. Project IDs are alphanumeric strings, like my-project.
  • AUDIENCE_NAME: The audience for the token, usually the URL of the application or service that the token will be used to access.

HTTP method and URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:generateIdToken

Request JSON body:

{
  "audience": "AUDIENCE_NAME",
  "includeEmail": "true"
}

To send your request, expand one of these options:

If the generateId request was successful, the response body contains an ID token that is valid for 1 hour. The token can then be used to authenticate a request on behalf of the service account:

{
  "token": "eyJ0eXAi...NiJ9"
}

Creating a self-signed JSON Web Token (JWT)

Self-signed JSON Web Tokens (JWTs) are useful in a variety of scenarios, such as:

  • Authenticating a call to a Google API as described in Google's Authentication Guide.
  • Securely communicating between Google Cloud or non-Google services, such as App Engine applications. In this scenario, one application can sign a token that can be verified by another application for authentication purposes.
  • Treating a service account as an identity provider by signing a JWT that contains arbitrary claims about a user, account, or device.

To generate a self-signed JWT for a service account, do the following:

API

The Service Account Credentials API's serviceAccounts.signJwt method signs a JWT using a service account's system-managed private key.

Before using any of the request data, make the following replacements:

  • SA_NAME: The name of the service account that you want to create a token for.
  • PROJECT_ID: Your Google Cloud project ID. Project IDs are alphanumeric strings, like my-project.
  • JWT_PAYLOAD: The JWT payload to sign, which is a JSON object that contains a JWT Claims Set. Include the claims that are necessary for your desired use case and to meet the validation requirements for the service you are calling. If you are calling a Google API, see Google's Authentication Guide for claim requirements.

    The exp (expiration time) claim must be no more than 12 hours in the future. If you are calling a Google API, the exp claim must be set no more than 1 hour in the future.

    The following example payload contains claims to call a Google API, where EXP is an integer timestamp representing the expiration time:

    { \"iss\": \"SA_NAME@PROJECT_ID.iam.gserviceaccount.com\", \"sub\": \"SA_NAME@PROJECT_ID.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/\", \"iat\": 1529350000, \"exp\": EXP }

HTTP method and URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:signJwt

Request JSON body:

{
  "payload": "JWT_PAYLOAD"
}

To send your request, expand one of these options:

If the signJwt request was successful, the response body contains a signed JWT and the signing key ID that was used to sign the JWT. You can use the signedJwt value as a bearer token to directly authenticate a request on behalf of the service account. The token is valid up to the expiration time specified in the request:

{
  "keyId": "42ba1e...fc0a",
  "signedJwt": "eyJ0eXAi...NiJ9"
}

Creating a self-signed blob

Self-signed blobs are useful in scenarios when you need to securely transmit arbitrary binary data, usually for authentication purposes. For example, if you want to use a custom protocol/token type (not JWT), you can include that data in a signed blob for use by a downstream service.

To generate a self-signed blob for a service account, do the following:

API

The Service Account Credentials API's serviceAccounts.signBlob method signs a blob using a service account's system-managed private key.

Before using any of the request data, make the following replacements:

  • SA_NAME: The name of the service account that you want to create a token for.
  • PROJECT_ID: Your Google Cloud project ID. Project IDs are alphanumeric strings, like my-project.
  • BLOB_PAYLOAD: A base64-encoded string of bytes. For example, VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu.

HTTP method and URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:signBlob

Request JSON body:

{
  "payload": "BLOB_PAYLOAD"
}

To send your request, expand one of these options:

If the signBlob request was successful, the response body contains a signed blob and the signing key ID that was used to sign the blob. You can use the signedBlob value as a bearer token to directly authenticate a request on behalf of the service account. The token is valid until the service account's system-managed private key expires. This key's ID is the value of the keyId field in the response.

{
  "keyId": "42ba1e...fc0a",
  "signedBlob": "eyJ0eXAi...NiJ9"
}