# Script to store secrets in Azure Key Vault # This script reads from .env.production and stores secrets in Key Vault param( [Parameter(Mandatory=$false)] [string]$ResourceGroupName = "rg-miraclesinmotion-prod", [Parameter(Mandatory=$false)] [string]$KeyVaultName = "", [Parameter(Mandatory=$false)] [switch]$CreateKeyVault = $false ) $ErrorActionPreference = "Stop" Write-Host "🔐 Storing Secrets in Azure Key Vault" -ForegroundColor Green Write-Host "====================================" -ForegroundColor Green Write-Host "" # Check if logged in to Azure $account = az account show --output json 2>$null | ConvertFrom-Json if (-not $account) { Write-Host "❌ Not logged in to Azure. Please run: az login" -ForegroundColor Red exit 1 } Write-Host "✅ Logged in to Azure" -ForegroundColor Green Write-Host " Subscription: $($account.name)" -ForegroundColor Gray Write-Host "" # Get Key Vault name if ([string]::IsNullOrEmpty($KeyVaultName)) { $KeyVaultName = az keyvault list --resource-group $ResourceGroupName --output json 2>$null | ConvertFrom-Json | Select-Object -First 1 -ExpandProperty name } if ([string]::IsNullOrEmpty($KeyVaultName)) { if ($CreateKeyVault) { $KeyVaultName = "mim-prod-$(Get-Random -Minimum 1000 -Maximum 9999)-kv" Write-Host "📦 Creating Key Vault: $KeyVaultName" -ForegroundColor Cyan az keyvault create ` --name $KeyVaultName ` --resource-group $ResourceGroupName ` --location $(az group show --name $ResourceGroupName --query location -o tsv) ` --sku standard ` --enable-rbac-authorization true ` --enable-soft-delete true ` --retention-days 90 | Out-Null Write-Host "✅ Key Vault created" -ForegroundColor Green } else { Write-Host "❌ Key Vault not found. Run with -CreateKeyVault to create one." -ForegroundColor Red exit 1 } } else { Write-Host "✅ Found Key Vault: $KeyVaultName" -ForegroundColor Green } Write-Host "" # Check if .env.production exists $envFile = ".env.production" if (-not (Test-Path $envFile)) { Write-Host "❌ .env.production file not found. Please create it first." -ForegroundColor Red Write-Host " Run: .\scripts\populate-env.ps1" -ForegroundColor Yellow exit 1 } Write-Host "📄 Reading secrets from $envFile..." -ForegroundColor Cyan # Read .env file and parse key-value pairs $envContent = Get-Content $envFile -Raw $secrets = @{} # Parse environment variables (simple parser - handles KEY=VALUE format) $lines = $envContent -split "`n" foreach ($line in $lines) { $line = $line.Trim() if ($line -and -not $line.StartsWith("#") -and $line -match "^([^=]+)=(.*)$") { $key = $matches[1].Trim() $value = $matches[2].Trim() # Skip empty values and placeholders if ($value -and $value -notmatch "^(your-|YOUR_|placeholder)" -and $value -ne "") { $secrets[$key] = $value } } } Write-Host "✅ Found $($secrets.Count) secrets to store" -ForegroundColor Green Write-Host "" # Define which secrets to store in Key Vault $secretsToStore = @( @{Name="azure-tenant-id"; EnvKey="AZURE_TENANT_ID"; Required=$true}, @{Name="azure-client-id"; EnvKey="AZURE_CLIENT_ID"; Required=$false}, @{Name="azure-client-secret"; EnvKey="AZURE_CLIENT_SECRET"; Required=$false}, @{Name="stripe-publishable-key"; EnvKey="VITE_STRIPE_PUBLISHABLE_KEY"; Required=$false}, @{Name="stripe-secret-key"; EnvKey="STRIPE_SECRET_KEY"; Required=$false}, @{Name="stripe-webhook-secret"; EnvKey="STRIPE_WEBHOOK_SECRET"; Required=$false}, @{Name="cosmos-endpoint"; EnvKey="COSMOS_ENDPOINT"; Required=$false}, @{Name="cosmos-key"; EnvKey="COSMOS_KEY"; Required=$false}, @{Name="cosmos-database-name"; EnvKey="COSMOS_DATABASE_NAME"; Required=$false}, @{Name="app-insights-connection-string"; EnvKey="APPLICATIONINSIGHTS_CONNECTION_STRING"; Required=$false}, @{Name="signalr-connection-string"; EnvKey="SIGNALR_CONNECTION_STRING"; Required=$false}, @{Name="cloudflare-zone-id"; EnvKey="CLOUDFLARE_ZONE_ID"; Required=$false}, @{Name="cloudflare-api-token"; EnvKey="CLOUDFLARE_API_TOKEN"; Required=$false}, @{Name="salesforce-client-id"; EnvKey="SALESFORCE_CLIENT_ID"; Required=$false}, @{Name="salesforce-client-secret"; EnvKey="SALESFORCE_CLIENT_SECRET"; Required=$false}, @{Name="smtp-password"; EnvKey="SMTP_PASSWORD"; Required=$false}, @{Name="session-secret"; EnvKey="SESSION_SECRET"; Required=$false}, @{Name="jwt-secret"; EnvKey="JWT_SECRET"; Required=$false}, @{Name="encryption-key"; EnvKey="ENCRYPTION_KEY"; Required=$false} ) $storedCount = 0 $skippedCount = 0 $errorCount = 0 Write-Host "📦 Storing secrets in Key Vault..." -ForegroundColor Cyan Write-Host "" foreach ($secretDef in $secretsToStore) { $secretName = $secretDef.Name $envKey = $secretDef.EnvKey $required = $secretDef.Required if ($secrets.ContainsKey($envKey)) { $secretValue = $secrets[$envKey] try { Write-Host " Storing: $secretName" -ForegroundColor Gray az keyvault secret set ` --vault-name $KeyVaultName ` --name $secretName ` --value $secretValue 2>$null | Out-Null if ($LASTEXITCODE -eq 0) { Write-Host " ✅ Stored successfully" -ForegroundColor Green $storedCount++ } else { Write-Host " ⚠️ Failed to store (may need RBAC permissions)" -ForegroundColor Yellow $errorCount++ } } catch { Write-Host " ❌ Error: $($_.Exception.Message)" -ForegroundColor Red $errorCount++ } } else { if ($required) { Write-Host " ⚠️ Missing required secret: $secretName ($envKey)" -ForegroundColor Yellow $skippedCount++ } else { Write-Host " ⏭️ Skipping: $secretName (not in .env file)" -ForegroundColor Gray $skippedCount++ } } } Write-Host "" Write-Host "📊 Summary:" -ForegroundColor Cyan Write-Host " ✅ Stored: $storedCount" -ForegroundColor Green Write-Host " ⏭️ Skipped: $skippedCount" -ForegroundColor Yellow Write-Host " ❌ Errors: $errorCount" -ForegroundColor $(if ($errorCount -gt 0) { "Red" } else { "Green" }) Write-Host "" # Prompt for additional secrets Write-Host "💡 Additional Secrets" -ForegroundColor Cyan Write-Host "You can manually add more secrets using:" -ForegroundColor Gray Write-Host " az keyvault secret set --vault-name $KeyVaultName --name --value " -ForegroundColor White Write-Host "" # Show how to retrieve secrets Write-Host "📖 Retrieving Secrets" -ForegroundColor Cyan Write-Host "To retrieve a secret:" -ForegroundColor Gray Write-Host " az keyvault secret show --vault-name $KeyVaultName --name --query value -o tsv" -ForegroundColor White Write-Host "" # Show Key Vault URL $keyVaultUrl = "https://$KeyVaultName.vault.azure.net/" Write-Host "🔗 Key Vault URL: $keyVaultUrl" -ForegroundColor Cyan Write-Host "" if ($errorCount -gt 0) { Write-Host "⚠️ Some secrets failed to store. You may need to:" -ForegroundColor Yellow Write-Host "1. Grant yourself 'Key Vault Secrets Officer' role on the Key Vault" -ForegroundColor White Write-Host "2. Or use Azure Portal to manually add secrets" -ForegroundColor White Write-Host "" Write-Host "Grant role command:" -ForegroundColor Cyan $currentUser = az ad signed-in-user show --query id -o tsv Write-Host " az role assignment create --role 'Key Vault Secrets Officer' --assignee $currentUser --scope /subscriptions/$($account.id)/resourceGroups/$ResourceGroupName/providers/Microsoft.KeyVault/vaults/$KeyVaultName" -ForegroundColor White Write-Host "" } Write-Host "✅ Done!" -ForegroundColor Green