Skip to content

Instantly share code, notes, and snippets.

@olekhy
Forked from ryu1kn/README.md
Created February 23, 2023 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olekhy/05dfa339eb1af356ba8c602acaa286ea to your computer and use it in GitHub Desktop.
Save olekhy/05dfa339eb1af356ba8c602acaa286ea to your computer and use it in GitHub Desktop.
Getting GCP access token from a service account key JSON file

Getting GCP access token from a service account key

Use your service account's key JSON file to get an access token to call Google APIs.

Good for seeing how things work, including the creation of JWT token.

To create a JWT token, you can replace create-jwt-token.sh script with tools like step.

If you just want to get an access token for a service account, you can do the same thing with just gcloud command. cf Authorization and authentication.

Prerequisites

  • Have a GCP project and a service account.
  • The service account has a permission for the request.
    • e.g. For listing buckets, "https://www.googleapis.com/auth/devstorage.read_only"
  • The service account's key JSON file is downloaded (here, key.json).
  • Commands available: jq, openssl

Usage

Get an access token.

$ ./get-access-token.sh /path/to/key.json "https://www.googleapis.com/auth/devstorage.read_only"
ya29...

You can call a Google API with the token. Here since we've requested storage readonly, we list buckets.

$ curl "https://www.googleapis.com/storage/v1/b?project=<your_project_id>" \
    -H "Authorization: Bearer ya29..."

References

#!/bin/bash
set -euo pipefail
base64var() {
printf "$1" | base64stream
}
base64stream() {
base64 | tr '/+' '_-' | tr -d '=\n'
}
key_json_file="$1"
scope="$2"
valid_for_sec="${3:-3600}"
private_key=$(jq -r .private_key $key_json_file)
sa_email=$(jq -r .client_email $key_json_file)
header='{"alg":"RS256","typ":"JWT"}'
claim=$(cat <<EOF | jq -c .
{
"iss": "$sa_email",
"scope": "$scope",
"aud": "https://www.googleapis.com/oauth2/v4/token",
"exp": $(($(date +%s) + $valid_for_sec)),
"iat": $(date +%s)
}
EOF
)
request_body="$(base64var "$header").$(base64var "$claim")"
signature=$(openssl dgst -sha256 -sign <(echo "$private_key") <(printf "$request_body") | base64stream)
printf "$request_body.$signature"
#!/bin/bash
set -euo pipefail
key_json_file="$1"
scope="$2"
jwt_token=$(./create-jwt-token.sh "$key_json_file" "$scope")
curl -s -X POST https://www.googleapis.com/oauth2/v4/token \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode "assertion=$jwt_token" \
| jq -r .access_token
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment