cc2abc91d6
Playwright Tests / test (push) Waiting to run
Integrate OCORE/OCORE_web-based secret management using Azure Key Vault and DPAPI cache. Update appsettings.json to remove plaintext secrets and list managed keys. Register secret management in Program.cs. Update .gitignore for secret files. Add documentation for naming conventions and migration, plus a PowerShell script for initial secret upload. Centralizes and secures secret handling across the app.
137 lines
5.0 KiB
PowerShell
137 lines
5.0 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Migrates Fuchs Intranet secrets to Azure Key Vault "pcwkeys".
|
|
|
|
.DESCRIPTION
|
|
Reads secret values from a JSON file and uploads them to Key Vault
|
|
under the "fuchs--" prefix convention used by the OCORE SecretManagement library.
|
|
|
|
Secret naming: fuchs--{ConfigSection}--{ConfigKey}
|
|
e.g. "fuchs--ConnectionStrings--ocms_ConnectionString"
|
|
|
|
The JSON file must have the format:
|
|
{
|
|
"fuchs--ConnectionStrings--ocms_ConnectionString": "actual-value",
|
|
...
|
|
}
|
|
|
|
.NOTES
|
|
Run once as part of the initial Key Vault migration.
|
|
NEVER commit the secrets JSON file - it is listed in .gitignore.
|
|
Requires: Az PowerShell module (Install-Module Az -Scope CurrentUser)
|
|
Requires: Key Vault Secrets Officer role (or legacy Access Policy: Set + Get + List)
|
|
|
|
.EXAMPLE
|
|
.\migrate-fuchs-secrets-to-keyvault.ps1 -SecretsFile .\Scripts\secrets.json
|
|
.\migrate-fuchs-secrets-to-keyvault.ps1 -SecretsFile .\Scripts\secrets.json -WhatIf
|
|
#>
|
|
|
|
[CmdletBinding(SupportsShouldProcess)]
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[string] $SecretsFile,
|
|
|
|
[string] $VaultName = "pcwkeys"
|
|
)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. Login check
|
|
# ---------------------------------------------------------------------------
|
|
$ctx = Get-AzContext -ErrorAction SilentlyContinue
|
|
if (-not $ctx) {
|
|
Write-Host "Not logged in - running Connect-AzAccount..." -ForegroundColor Yellow
|
|
Connect-AzAccount
|
|
}
|
|
else {
|
|
Write-Host "Using Azure account: $($ctx.Account.Id)" -ForegroundColor Cyan
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. Load secrets from JSON file
|
|
# ---------------------------------------------------------------------------
|
|
if (-not (Test-Path $SecretsFile)) {
|
|
Write-Host ""
|
|
Write-Host "ERROR: Secrets file not found: $SecretsFile" -ForegroundColor Red
|
|
Write-Host "Create it from the template: Scripts\secrets.json" -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
|
|
try {
|
|
$json = Get-Content $SecretsFile -Raw -Encoding UTF8 -ErrorAction Stop
|
|
$parsed = $json | ConvertFrom-Json -ErrorAction Stop
|
|
$secrets = [ordered]@{}
|
|
$parsed.PSObject.Properties | ForEach-Object { $secrets[$_.Name] = $_.Value }
|
|
}
|
|
catch {
|
|
Write-Host ""
|
|
Write-Host "ERROR: Failed to parse $SecretsFile - $($_.Exception.Message)" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Loaded $($secrets.Count) secrets from: $SecretsFile" -ForegroundColor Cyan
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. Validate - abort if any value is still empty
|
|
# ---------------------------------------------------------------------------
|
|
$empty = $secrets.Keys | Where-Object { [string]::IsNullOrWhiteSpace($secrets[$_]) }
|
|
if ($empty) {
|
|
Write-Host ""
|
|
Write-Host "ERROR: The following secrets have no value set:" -ForegroundColor Red
|
|
$empty | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
|
|
Write-Host ""
|
|
Write-Host "Fill in the values in secrets.json, then run again." -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. Write secrets to Key Vault
|
|
# ---------------------------------------------------------------------------
|
|
$total = $secrets.Count
|
|
$done = 0
|
|
$failed = @()
|
|
|
|
Write-Host ""
|
|
Write-Host "Migrating $total secrets to Key Vault '$VaultName'..." -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
foreach ($name in $secrets.Keys) {
|
|
$done++
|
|
$pct = [int](($done / $total) * 100)
|
|
Write-Progress -Activity "Uploading secrets to $VaultName" -Status "$name" -PercentComplete $pct
|
|
|
|
if ($PSCmdlet.ShouldProcess($VaultName, "Set secret '$name'")) {
|
|
try {
|
|
$secureValue = ConvertTo-SecureString $secrets[$name] -AsPlainText -Force
|
|
$null = Set-AzKeyVaultSecret -VaultName $VaultName -Name $name -SecretValue $secureValue
|
|
Write-Host " [OK] [$done/$total] $name" -ForegroundColor Green
|
|
}
|
|
catch {
|
|
Write-Host " [FAIL] [$done/$total] $name - $($_.Exception.Message)" -ForegroundColor Red
|
|
$failed += $name
|
|
}
|
|
}
|
|
else {
|
|
Write-Host " [WhatIf] Would set: $name" -ForegroundColor DarkCyan
|
|
}
|
|
}
|
|
|
|
Write-Progress -Activity "Uploading secrets" -Completed
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 5. Summary
|
|
# ---------------------------------------------------------------------------
|
|
Write-Host ""
|
|
if ($failed.Count -eq 0) {
|
|
Write-Host "Migration complete - $done/$total secrets written." -ForegroundColor Green
|
|
}
|
|
else {
|
|
Write-Host "Migration finished with $($failed.Count) error(s):" -ForegroundColor Yellow
|
|
$failed | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Next steps:" -ForegroundColor Cyan
|
|
Write-Host " 1. Verify appsettings.json has VaultUri set to https://pcwkeys.vault.azure.net/"
|
|
Write-Host " 2. Start the app and confirm '[OCORE.Secrets:fuchs] Sync OK' appears in logs"
|
|
Write-Host " 3. Clear the secret values from secrets.json after a successful run"
|