mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 20:53:06 +00:00
e4a5a6654d
Every storage write against autopilotmonitoreu -- build-counter CAS, agent ZIP and MSI, version manifests, customer bootstrap scripts, the AdminConfiguration hash oracle -- now rides on the existing federated credential (subject repo:.../ref:refs/heads/main) instead of a long-lived SAS in repo secrets. The REST calls themselves are unchanged: '?<sas>' became an Authorization header, so the ETag-CAS of the counters, Content-MD5 and the no-cache contract survive verbatim. That is also why this is not a rewrite onto 'az storage blob upload' -- it cannot express If-Match, and two concurrent builds could then mint the same build number. .github/scripts/Get-StorageAuthHeaders.ps1 is the single place that knows the resource id, the az invocation and the service version. x-ms-version is mandatory for Entra-authorized requests (>= 2017-11-09) and for any Table request without a SAS; 2021-08-06 was verified live against both the blob and the table endpoint of this account. azure/login added to build-agent, build-msi, publish-scripts (plus id-token: write) and deploy-web; deploy-backend and deploy-mcp already had it. Publish-BootstrapScripts.ps1 -DryRun acquires NO token: the PR gate runs it without any Azure login, and that must stay true. The AdminConfiguration merge lost its "secret not configured" skip branch -- a failure there now surfaces instead of silently leaving the hash oracle pointing at an older build. AZURE_BLOB_AGENT_SAS_TOKEN, AZURE_BLOB_VERSIONS_SAS_TOKEN and AZURE_TABLE_ADMIN_SAS_TOKEN are retired once the first runs are green. AZURE_BLOB_AGENT_LEGACY_SAS_TOKEN stays: that account lives in the pre-migration tenant, where this principal has no identity -- it dies with the mirror, not before. Requires on the SP: Storage Blob Data Contributor on the containers 'agent' and 'versions', Storage Table Data Contributor on the table 'AdminConfiguration'. Granted 2026-09-08.
52 lines
2.4 KiB
PowerShell
52 lines
2.4 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Returns the request headers that authorize an Azure Storage REST call with Microsoft Entra.
|
|
|
|
.DESCRIPTION
|
|
One place for the storage OAuth contract shared by every publisher in this repo -- the
|
|
agent ZIP and MSI, the customer bootstrap scripts, the version manifests and the build
|
|
counters. Resource id, the az invocation, the service version and the failure message
|
|
live here so they cannot drift between call sites.
|
|
|
|
Identity comes from whatever `az login` established: the federated GitHub OIDC principal
|
|
in CI (azure/login, subject repo:okieselbach/AutopilotMonitor:ref:refs/heads/main), the
|
|
operator's own account for the local build. No secret is read, stored or passed around.
|
|
|
|
x-ms-version is MANDATORY here, not decoration: Entra-authorized requests are rejected
|
|
below 2017-11-09, and Table requests without a SAS must carry the header at all. 2021-08-06
|
|
is old enough to be deployed in every region and new enough for everything we send.
|
|
|
|
Callers merge the result into their own headers -- `$auth + @{ ... }` yields a new
|
|
hashtable per request, so nothing is shared across uploads:
|
|
|
|
$auth = & "$PSScriptRoot/Get-StorageAuthHeaders.ps1"
|
|
Invoke-RestMethod -Uri $url -Method Put -Headers ($auth + @{ 'x-ms-blob-type' = 'BlockBlob' }) -Body $bytes
|
|
|
|
Acquire once per step and reuse: every call shells out to az (~1s) and the token is valid
|
|
for the lifetime of a job.
|
|
|
|
.OUTPUTS
|
|
[hashtable] Authorization + x-ms-version.
|
|
#>
|
|
[CmdletBinding()]
|
|
param()
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# The data-plane resource, not management.azure.com -- a management token is accepted by
|
|
# neither the blob nor the table endpoint.
|
|
$token = az account get-access-token --resource https://storage.azure.com --query accessToken -o tsv 2>$null
|
|
|
|
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($token)) {
|
|
throw ('Could not acquire an Azure Storage token. In CI this means the azure/login step ' +
|
|
'is missing or its federated credential does not cover this ref; locally, run ' +
|
|
'`az login`. A token alone is not enough: the principal also needs Storage Blob ' +
|
|
'Data Contributor on the container it writes, and Storage Table Data Contributor ' +
|
|
'on the table -- a missing role shows up later as HTTP 403 AuthorizationPermissionMismatch.')
|
|
}
|
|
|
|
return @{
|
|
'Authorization' = "Bearer $token"
|
|
'x-ms-version' = '2021-08-06'
|
|
}
|