This page explains how to create short-lived credentials for service accounts to impersonate their identities.
Service accounts can use short-lived credentials to authenticate calls to Google Cloud APIs and other 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.
Supported credential types include 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. Some example scenarios include the following:
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, a service administrator can impersonate a service account to call Google Cloud APIs by creating an OAuth 2.0 access token belonging to that service account. 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 a service 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 service running on Google Cloud can authenticate itself to another service deployed on a third-party cloud provider, such as a data pipeline job. If the target service is configured with OIDC, the authentication will succeed.
Before you begin
- 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.
Granting required permissions
There are two different flows that allow a caller to create short-lived credentials for a service account. Each flow requires the appropriate permissions:
- Direct request: The caller is authenticated as either a Google account or a service account and makes a direct request to create short-lived credentials. Two identities are involved in this flow: the caller, and the service account for whom the credential is created.
Delegated request: Like the direct request flow, the caller is authenticated as either a Google account or a service account, but instead the request is delegated to one or more service accounts in a delegation chain. In this flow, multiple service accounts act as intermediaries between the original caller and the service account for whom the credential is created. Each service account in the delegation chain must have the required permissions to pass along the request.
This flow is useful for scenarios where a project contains tiers of limited-privilege service accounts, each of which has been configured to perform a specific or limited function on certain resources. For example, one service account is only granted permissions for Cloud Storage resources, another is only granted permissions for Compute Engine resources, and so on. To successfully delegate a request across service accounts, each must be listed in the delegation chain.
Direct request permissions
As described in Granting required permissions on this page, a direct request involves only two identities: the caller, and the service account for whom 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 grant 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 a service account being treated like a resource as opposed to
an identity: sa-1
must be granted the permission to
issue credentials for sa-2
. For more information about
treating service accounts as an identity or a resource, see
Service account permissions.
The following steps use the REST API to grant the required permissions, however
you can also use the Cloud Console or the
gcloud
command-line tool.
API
First, read the IAM policy for
sa-2
:
The
serviceAccounts.getIamPolicy
method gets a service account's IAM policy.
Before using any of the request data below, make the following replacements:
project-id
: Your Google Cloud project ID.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 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 policy:
The
serviceAccounts.setIamPolicy
method sets an updated IAM policy for the service account.
Before using any of the request data below, make the following replacements:
project-id
: Your Google Cloud project ID.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 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 policy.
Delegated request permissions
As described in Granting required permissions on this page, a delegated request involves more than two identities: the caller, one or more service accounts in a delegation chain, and finally the service account. 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
), an intermediary service account that will delegate the initial request tosa-3
. - Service Account 3 (
sa-3
), the limited-privilege account for whom the credential is created.
To allow delegation, each account must grant the Service Account Token Creator
role (roles/iam.serviceAccountTokenCreator
) to the previous account in the
chain.
In this particular example, sa-1
must be granted the
Service Account Token Creator role (roles/iam.serviceAccountTokenCreator
) on
sa-2
. This is an example of a service account being
treated like a resource as opposed to an identity: sa-1
must be granted the permission to delegate access for
sa-2
. For more information about treating service
accounts as an identity or a resource, see
Service account permissions.
In this example flow, there is only one intermediary service account. To delegate access through more than one service account, you must also assign this role to any other service account in the chain.
Next, sa-2
must also be granted the Service Account
Token Creator role (roles/iam.serviceAccountTokenCreator
) on
sa-3
. This allows sa-2
to create
short-lived credentials for sa-3
.
The following steps use the REST API to grant the required permissions, however
you can also use the Cloud Console or the
gcloud
command-line tool.
API
First, get the IAM policy for
sa-2
(the intermediary service account):
The
serviceAccounts.getIamPolicy
method gets a service account's IAM policy.
Before using any of the request data below, make the following replacements:
project-id
: Your Google Cloud project ID.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 granted a role to the service account, the response
contains only an etag
value. Include that etag
value in the next step.
Next, modify the 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" ] } ] }
Then, write the updated policy for sa-2
:
The
serviceAccounts.setIamPolicy
method sets an updated IAM policy for the service account.
Before using any of the request data below, make the following replacements:
project-id
: Your Google Cloud project ID.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 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 policy.
Now, get the IAM policy for sa-3
(the service account for whom the credential is created):
The
serviceAccounts.getIamPolicy
method gets a service account's IAM policy.
Before using any of the request data below, make the following replacements:
project-id
: Your Google Cloud project ID.sa-3
: The name of Service Account 3.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-3@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 policy to grant sa-2
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-2@project-id.iam.gserviceaccount.com" ] } ] }
Finally, write the updated policy:
The
serviceAccounts.setIamPolicy
method sets an updated IAM policy for the service account.
Before using any of the request data below, make the following replacements:
project-id
: Your Google Cloud project ID.sa-3
: The name of Service Account 3.-
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 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-2@project-id.iam.gserviceaccount.com" ] } ] }
HTTP method and URL:
POST https://iam.googleapis.com/v1/projects/project-id/serviceAccounts/sa-3@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 policy.
Requesting short-lived credentials
After you have granted the appropriate permissions for each identity, you can request short-lived credentials belonging to the desired service account. The following credential types are supported:
- OAuth 2.0 access tokens
- OpenID Connect ID tokens
- Self-signed JSON Web Tokens (JWTs)
- Self-signed binary objects (blobs)
To understand how to specify a delegation chain for these requests, see the Specifying a delegation chain section on this page.
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 below, 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.delegates
: If you are using a delegated request flow, see Specifying a delegation chain on this page. If you are using a direct request flow with no delegation, omit thedelegates
field in the request body.scopes
: The OAuth 2.0 scopes for the request. The following scopes are valid when calling thegenerateAccessToken
API:"https://www.googleapis.com/auth/iam"
"https://www.googleapis.com/auth/cloud-platform"
-
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:
{ "delegates": [ delegates ], "scope": [ scopes ], "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 below, 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.delegates
: If you are using a delegated request flow, see Specifying a delegation chain on this page. If you are using a direct request flow with no delegation, omit thedelegates
field in the request body.
HTTP method and URL:
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-name@project-id.iam.gserviceaccount.com:generateIdToken
Request JSON body:
{ "delegates": [ delegates ], "audience": "sa-name@project-id.iam.gserviceaccount.com", "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 below, 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.delegates
: If you are using a delegated request flow, see Specifying a delegation chain on this page. If you are using a direct request flow with no delegation, omit thedelegates
field in the request body.-
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, theexp
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:
{ "delegates": [ delegates ], "payload": "jwt-payload" }
To send your request, expand one of these options:
If 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 below, 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.delegates
: If you are using a delegated request flow, see Specifying a delegation chain on this page. If you are using a direct request flow with no delegation, omit thedelegates
field in the request body.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:
{ "delegates": [ delegates ], "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" }
Specifying a delegation chain
When using a delegated request flow to create short-lived service account credentials, the request body for each API must specify the service account delegation chain in the correct order and in the following format:
projects/-/serviceAccounts/account-email-or-unique-id
For example, in a delegation chain that flows from sa-1
(caller) to sa-2
(delegated) to
sa-3
(delegated) to sa-4
, the
delegates[]
field would contain sa-2
and
sa-3
in the following order:
{ "delegates": [ "projects/-/serviceAccounts/sa-2@project-id.iam.gserviceaccount.com", "projects/-/serviceAccounts/sa-3@project-id.iam.gserviceaccount.com" ] }
The caller and the service account for whom the credential is created are not included in the delegation chain.