Skip to content

Instantly share code, notes, and snippets.

@AndrewSav
Last active February 28, 2025 09:13
Show Gist options
  • Save AndrewSav/13a1c5dbbc37c287ab5d138f89f538d0 to your computer and use it in GitHub Desktop.
Save AndrewSav/13a1c5dbbc37c287ab5d138f89f538d0 to your computer and use it in GitHub Desktop.
Get access token from Google Service Account credentials file
[CmdletBinding()]
Param(
# https://console.cloud.google.com/iam-admin/serviceaccounts
[Parameter(Mandatory,Position=0,HelpMessage='Enter path to Google Service Account credentials json file')][string]$serviceCredentialsJsonPath,
# https://developers.google.com/identity/protocols/oauth2/scopes
[Parameter(Mandatory,Position=1,HelpMessage='Enter required Google API scopes')][string[]]$scopes,
[Parameter(Position=3,HelpMessage='Enter token duration in seconds')][int]$duration=3540
)
Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"
function base64urlbytes ($Object) {
([String]([System.Convert]::ToBase64String($Object))).TrimEnd('=').Replace('+','-').Replace('/','_')
}
function base64url ($Object) {
base64urlbytes ([System.Text.Encoding]::UTF8.GetBytes($Object))
}
$creds = Get-Content $serviceCredentialsJsonPath | ConvertFrom-Json
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.ImportFromPem($creds.private_key)
$rawheader = [Ordered]@{
alg = "RS256"
typ = "JWT"
} | ConvertTo-Json -Compress
$header = base64url $rawheader
[int]$createDate = Get-Date (Get-Date).ToUniversalTime() -UFormat "%s"
$expiryDate = $createDate + $duration
$rawclaims = [Ordered]@{
iss = "$($creds.client_email)"
sub = "$($creds.client_email)"
scope = "$($Scopes -join " ")"
aud = "https://www.googleapis.com/oauth2/v4/token"
exp = "$expiryDate"
iat = "$createDate"
} | ConvertTo-Json
$claims = base64url $rawclaims
$sig = base64urlbytes ($rsa.SignData([System.Text.Encoding]::UTF8.GetBytes($header + "." + $claims),"SHA256"))
$jwt = $header + "." + $claims + "." + $sig
$fields = [Ordered]@{
grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
assertion = $jwt
}
$response = Invoke-WebRequest -Uri "https://www.googleapis.com/oauth2/v4/token" -Method Post -Body $fields -ContentType "application/x-www-form-urlencoded"
($response | ConvertFrom-Json).access_token
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment