Add Azure Key Vault + DPAPI secret management
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.
This commit is contained in:
2026-05-03 16:24:38 +02:00
parent c617e9ae3b
commit cc2abc91d6
6 changed files with 1116 additions and 9 deletions
@@ -0,0 +1,136 @@
<#
.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"