From ce2ef68807042a3b7e8380dd69c3ff27821fc8bc Mon Sep 17 00:00:00 2001 From: Wes Haggard Date: Thu, 5 Feb 2026 09:28:07 -0800 Subject: [PATCH] Fix base64 encoding for JWT token The eng/common/scripts/login-to-github.ps1 script was failing because it was using the standard Base64 encoded signature returned by Azure Key Vault directly in the JWT, instead of converting it to Base64URL format (which replaces + with -, / with _, and removes trailing =). I have fixed the script by adding the necessary character replacements and also added a 10-second clock skew buffer to the iat (issued at) claim to ensure validity. The script now runs successfully and logs in as azure-sdk-automation[bot]. Changes made: - Modified eng/common/scripts/login-to-github.ps1: - Converted the signature from Azure Key Vault to Base64URL format. - Subtracted 10 seconds from the iat claim to account for potential clock skew. Verification: - Ran the script and confirmed it successfully resolved the installation ID for "Azure" and obtained an access token. - gh auth status output confirms successful login. --- eng/common/scripts/login-to-github.ps1 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/eng/common/scripts/login-to-github.ps1 b/eng/common/scripts/login-to-github.ps1 index 96023d290c4b..e911f31eb12b 100644 --- a/eng/common/scripts/login-to-github.ps1 +++ b/eng/common/scripts/login-to-github.ps1 @@ -57,9 +57,17 @@ function New-GitHubAppJwt { [Parameter(Mandatory)] [string] $AppId ) - function Base64UrlEncode($json) { - $bytes = [System.Text.Encoding]::UTF8.GetBytes($json) - $base64 = [Convert]::ToBase64String($bytes) + function Base64UrlEncode { + param( + [string]$Data, + [switch]$IsBase64String + ) + if ($IsBase64String) { + $base64 = $Data + } else { + $bytes = [System.Text.Encoding]::UTF8.GetBytes($Data) + $base64 = [Convert]::ToBase64String($bytes) + } return $base64.TrimEnd('=') -replace '\+', '-' -replace '/', '_' } @@ -70,7 +78,7 @@ function New-GitHubAppJwt { } $Now = [int][double]::Parse((Get-Date -UFormat %s)) $Payload = @{ - iat = $Now + iat = $Now - 10 # 10 seconds clock skew exp = $Now + 600 # 10 minutes iss = $AppId } @@ -97,7 +105,7 @@ function New-GitHubAppJwt { throw "Azure Key Vault response does not contain a signature. Response: $($SignResultJson | ConvertTo-Json -Compress)" } - $Signature = $SignResultJson.signature + $Signature = Base64UrlEncode -Data $SignResultJson.signature -IsBase64String return "$UnsignedToken.$Signature" }