Google cloud authentication schemes are relatively confusing and I still have to take a step back and think about which credentials i’ve had and what is “in context” at the moment.
I’ve been meaning to draw the credentials you normally carry when using the gcloud cli
and when you use Application Default Credentials
.
..and all this confusion prompted me to writeup a helper script here:
Anyway, here are the pictures:
GOOGLE_APPLICATION_CREDENTIALS
env-var is set.gcloud
cli set with its own ADC setup (eg, who you logged in with gcloud auth application-default login
)gcloud cli
credentials are used for admin tasks for GCP resources. THese are the creds you use when running gcloud compute instances list
If the gcloud cli is bootstrapped as a user, its using three legged oauth (3LO
) as described here Using Oauth2 for Native app
If you bootstrap gcloud cli for admin tasks using a service account, it will ultimately use two legged oauth (2LO
): Using OAuth 2.0 for Server to Server Applications
So as a user, the login flow is pretty standard
for remote bootstrapping for a user (eg, to initialize gcloud
in a system where there is no browser), its more complicated and involves some copy+paste
and using it is same as an installed app:
Finally, if you run gcloud cli in a GCE environment, the token is derived directly from the metadata server which has access to the key (ultimately)
Incase you want to run your own metadata server for testing locally, see GCE Metadata Server Emulator
Lets “see” the credential types by hand and using the oauth2 tokeninfo
endpoint to interrogate what we have:
https://oauth2.googleapis.com/tokeninfo?id_token=$ACCESS_TOKEN
The following uses a users credential and a service account credential (JSON) file just show which credentials we’ve just bootstrapped
Assume we have the following service account file and which carries the following client_id
.
export SVC_ACCOUNT_FILE=/path/to/svcaccount.json
$ cat $SVC_ACCOUNT_FILE | jq -r '.client_id'
107846671635241723821
So lets login as a user and see some data about our token for ADC
# login as user
$ gcloud auth application-default login
curl -s https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$TOKEN | jq '.'
$ export TOKEN=`gcloud auth application-default print-access-token`
$ curl -s https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$TOKEN | jq '.'
{
"azp": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com",
"aud": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com",
"sub": "1081579130932111111",
"scope": "openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/accounts.reauth",
"exp": "1647190187",
"expires_in": "3592",
"email": "user@domain.com",
"email_verified": "true"
}
Note the email
claim…that right, its me
Now set the environment variable for ADC pointing to the service account and repeat:
$ export GOOGLE_APPLICATION_CREDENTIALS=$SVC_ACCOUNT_FILE
$ export TOKEN=`gcloud auth application-default print-access-token`
$ curl -s https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$TOKEN | jq '.'
{
"azp": "107846671635241723821",
"aud": "107846671635241723821",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"exp": "1647190437",
"expires_in": "3596",
"access_type": "online"
}
# revoke just to clar
$ gcloud auth application-default revoke
So this is different but the thing to note is the azp
, aud
fields…it matches the client_id
for our service account. Meaning ADC is now using a service account
Now compare this against gcloud CLI based usage
# [login as user]
$ gcloud auth login
$ export TOKEN=`gcloud auth print-access-token`
$ curl -s https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$TOKEN | jq '.'
{
"azp": "32555940559.apps.googleusercontent.com",
"aud": "32555940559.apps.googleusercontent.com",
"sub": "1081579130932111111",
"scope": "openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/accounts.reauth",
"exp": "1647190756",
"expires_in": "3591",
"email": "user@domain.com",
"email_verified": "true"
}
again, note the email
and sub
fields…thats me again
Lets move on to service account in gcloud cli:
## this will NOT set ADC...this only impacts gcloud cli operations (eg gcloud compute instances list)
$ gcloud auth activate-service-account --key-file=$SVC_ACCOUNT_FILE
$ export TOKEN=`gcloud auth print-access-token`
$ curl -s https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$TOKEN | jq '.'
{
"azp": "107846671635241723821",
"aud": "107846671635241723821",
"sub": "107846671635241723821",
"scope": "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/userinfo.email openid",
"exp": "1647190263",
"expires_in": "3597",
"email": "svcaccount1@mineral-minutia-820.iam.gserviceaccount.com",
"email_verified": "true",
"access_type": "online"
}
Note the credentials for gcloud now uses a service account since we asked for gcloud cli’s token gcloud auth print-access-token
This site supports webmentions. Send me a mention via this form.