feat(automation): add durable runner and signed approval recovery

This commit is contained in:
cesnimda
2026-10-29 14:33:50 +01:00
parent 4da3939547
commit 607ee1853e
29 changed files with 29694 additions and 7 deletions
+25
View File
@@ -0,0 +1,25 @@
#Requires -Version 7.2
# Disposable test key only. Production signing uses the owner's nonexportable certificate.
param([ValidateSet('Setup','Sign')][string]$Action, [string]$Root, [string]$RequestPath, [string]$ApprovalPath)
$ErrorActionPreference = 'Stop'
$rsa = [Security.Cryptography.RSA]::Create(2048)
try {
if ($Action -eq 'Setup') {
$request = [Security.Cryptography.X509Certificates.CertificateRequest]::new('CN=DISPOSABLE SYNTHETIC ONLY', $rsa,
[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)
$cert = $request.CreateSelfSigned([DateTimeOffset]::UtcNow.AddMinutes(-1),[DateTimeOffset]::UtcNow.AddHours(2))
[IO.File]::WriteAllBytes((Join-Path $Root 'owner.cer'),$cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert))
[IO.File]::WriteAllText((Join-Path $Root 'synthetic-private.pem'),$rsa.ExportPkcs8PrivateKeyPem())
$cert.Dispose()
} else {
$rsa.ImportFromPem([IO.File]::ReadAllText((Join-Path $Root 'synthetic-private.pem')))
$hash = [Convert]::ToHexString([Security.Cryptography.SHA256]::HashData([IO.File]::ReadAllBytes($RequestPath))).ToLowerInvariant()
$payload = @{requestSha256=$hash;approved=$true;ownerSid='OWNER';decision='Synthetic owner approves exact request';disposition='Approve';
issuedUtc=[DateTimeOffset]::UtcNow.ToString('o');expiresUtc=[DateTimeOffset]::UtcNow.AddHours(1).ToString('o')} | ConvertTo-Json -Compress
$bytes = [Text.Encoding]::UTF8.GetBytes($payload)
$signature = $rsa.SignData($bytes,[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)
[IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($ApprovalPath)) | Out-Null
@{payloadBase64=[Convert]::ToBase64String($bytes);signatureBase64=[Convert]::ToBase64String($signature)} |
ConvertTo-Json -Compress | Set-Content -LiteralPath $ApprovalPath -Encoding utf8NoBOM
}
} finally { $rsa.Dispose() }