The constraints/iam.allowServiceAccountCredentialLifetimeExtension
GCP Org Policy constraint is advertized as:
You can create an OAuth 2.0 access token that provides short-lived credentials for a service account.
By default, the maximum lifetime of an access token is 1 hour (3,600 seconds). However, you can extend the maximum lifetime to 12 hours.
With this, you can run a token-broker which dishes out short-lived credentials that can be optionally downscoped (for Cloud Storage
atleast).
These tokens can then be handed to a long running process that does not by itself have a refreshable token but is “given” one for a task that may run upto 12h
.
Great..soo..how do i get one of these tokens?
Well, currently its only available by using the iamcredentials.generateAccessToken() API for an allow-listed serviceAccount and then within that api request by specifying the lifetime
parameter.
This example here walk you through a simple scenario and demos the extended token lifetime
First setup a service account:
export GCLOUD_USER=`gcloud config get-value core/account`
export PROJECT_ID=`gcloud config get-value core/project`
export PROJECT_NUMBER=`gcloud projects describe $PROJECT_ID --format='value(projectNumber)'`
gcloud iam service-accounts create long-lived
gcloud iam service-accounts add-iam-policy-binding long-lived@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.serviceAccountTokenCreator \
--member "user:$GCLOUD_USER"
then set the requisite Org policy:
Use the iam api to request a token of 3600s
:
$ date -u
Thu Mar 17 11:04:06 AM EDT 2022
$ curl -s -H "Authorization: Bearer `gcloud auth print-access-token`" \
-X POST -H "Content-Type: application/json" \
-d '{"scope": ["https://www.googleapis.com/auth/cloud-platform"], "lifetime": "3600s"}' \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/long-lived@$PROJECT_ID.iam.gserviceaccount.com:generateAccessToken" | jq -r '.expireTime'
2022-03-17T16:04:10Z
Now ask for much longer 43200s
$ curl -s -H "Authorization: Bearer `gcloud auth print-access-token`" \
-X POST -H "Content-Type: application/json" \
-d '{"scope": ["https://www.googleapis.com/auth/cloud-platform"], "lifetime": "43200s"}' \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/long-lived@$PROJECT_ID.iam.gserviceaccount.com:generateAccessToken" \
| jq -r '.expireTime'
2022-03-18T03:04:13Z
# if you extracted the actual accessToken from the request and used it against the oauth2 tokeinfo, you'll see the extended
# `expires_in` value
$ curl -s "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN"
{
"issued_to": "103266848859123965085",
"audience": "103266848859123965085",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"expires_in": 43161,
"access_type": "online"
}
done…now you have a long lived access_token
The iam.serviceAccountTokenCreator
role includes concentric set of permission (see Concentric IAMCredentials Permissions: The secret life of signBlob. If you just need to generate an access_token
or an id_token
, consider generating a custom role with that specific capability.
You can’t really revoke the long lived token but what you can do is go scorched-earth and disable the service account outright.
gcloud iam service-accounts disable long-lived@$PROJECT_ID.iam.gserviceaccount.com
# which will immediately invalidate the token too
$ curl -s "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN"
{
"error": "invalid_token",
"error_description": "Invalid Value"
}
note, this was also a requested feature in GCP Vault Secrets: Support 12h lifetime Access_Token but as of now, the vaultprovider
This site supports webmentions. Send me a mention via this form.