private/Save-MsecTenantProfile.ps1
|
function Save-MsecTenantProfile { <# .SYNOPSIS Remembers how to connect to a tenant, so switching Azure context can reconnect the msec session without being told the vault again. .DESCRIPTION Writes the CONFIGURATION needed to call Connect-Msec - vault name, client id, certificate name - into the tenant's own cache folder, beside the completion caches. NO SECRET IS STORED, and none needs to be. msec authenticates with a JWT client assertion signed inside Key Vault; the private key never leaves it. What is here is the same information you would type on the command line, and it is worth nothing to anyone who cannot already reach the vault. Best effort by design: a profile that cannot be written costs the convenience of auto-reconnect, not the session. Failing Connect-Msec because a cache folder was read-only would be the wrong trade. .PARAMETER TenantId The tenant this profile connects to. Also the folder it is stored under, so two tenants can never overwrite each other's. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string] $TenantId, [Parameter(Mandatory)] [string] $KeyVaultName, [Parameter(Mandatory)] [string] $ClientId, [Parameter()] [string] $CertificateName = 'msec-app', # THE ACCOUNT Connect-MsecAdmin SIGNED IN AS, remembered per tenant so a later # sign-in can tell "you picked the wrong account" from "you have no consent". Two # tenants with two identities is where that distinction stops being obvious: a user # from one tenant reaching a resource in the other fails with AADSTS500213, which # names a cross-tenant policy and says nothing about the account being wrong. # # A UPN, not a secret, and not a credential of any kind. [Parameter()] [string] $AdminAccount ) try { $path = Get-MsecCachePath -Name 'profile' -TenantId $TenantId $dir = Split-Path -Path $path -Parent if (-not (Test-Path -LiteralPath $dir)) { New-Item -Path $dir -ItemType Directory -Force | Out-Null } [pscustomobject]@{ TenantId = $TenantId KeyVaultName = $KeyVaultName ClientId = $ClientId CertificateName = $CertificateName # Preserved when this save is only about the app session, so recording a # connection does not forget which admin account belongs to this tenant. AdminAccount = if ($PSBoundParameters.ContainsKey('AdminAccount')) { $AdminAccount } else { (Get-MsecTenantProfile -TenantId $TenantId).AdminAccount } SavedUtc = [DateTime]::UtcNow.ToString('yyyy-MM-dd HH:mm:ss') } | ConvertTo-Json -Depth 3 | Set-Content -LiteralPath $path -Encoding utf8 -ErrorAction Stop Write-Verbose "Saved the connection profile for tenant $TenantId to '$path'." } catch { Write-Verbose "Could not save the connection profile for tenant $TenantId - auto-reconnect will not be available for it: $($_.Exception.Message)" } } |