Skip to content

Instantly share code, notes, and snippets.

@nschairer
Forked from ryu1kn/README.md
Last active January 15, 2024 13:23
Show Gist options
  • Save nschairer/1fb8ccfe7bd0c05281d819a17db475a8 to your computer and use it in GitHub Desktop.
Save nschairer/1fb8ccfe7bd0c05281d819a17db475a8 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
}
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": "https://www.googleapis.com/auth/drive",
"aud": "https://oauth2.googleapis.com/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")
access_token=$(curl -s -X POST https://oauth2.googleapis.com/token \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode "assertion=$jwt_token" \
| jq -r .access_token)
#####Use token for google drive -- this request should list files
curl 'https://www.googleapis.com/upload/drive/v3/files' \
-H "Authorization: Bearer $access_token"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment