Private/ConvertTo-AACRedactedObject.ps1
|
function ConvertTo-AACRedactedObject { <# .SYNOPSIS Copies an object (hashtables, lists and values, as JSON is parsed) with its secrets replaced by '[REDACTED]' - for anything written to a file that may be sent to someone else. .DESCRIPTION A value is redacted when its key names a secret (password, secret, token, connection string, SAS, credentials, access/account/shared access/primary/secondary/instrumentation key, private key) or when the value itself looks like one (a connection string with AccountKey=, SharedAccessKey=, Password= or SharedAccessSignature=, a SAS query string with sig=, a JWT, a PEM private key). Names that only mention a key (keyVaultUri, keySource, publicKey, keyName) are kept: they say where a secret lives, not what it is. -Count is a [ref] to an int that is increased once per redaction. #> [CmdletBinding()] param( [AllowNull()] $InputObject, [ref] $Count ) $secretKey = '(?i)(^|[_\-.])?(password|passwd|pwd|secret|clientsecret|token|accesstoken|refreshtoken|connectionstring|connectionstrings|sas|sastoken|sasurl|saskey|credential|credentials|privatekey|accesskey|accountkey|sharedaccesskey|primarykey|secondarykey|primarymasterkey|secondarymasterkey|primaryreadonlymasterkey|secondaryreadonlymasterkey|instrumentationkey|adminpassword|storageaccountkey|apikey|subscriptionkey)$' $secretValue = '(?i)(AccountKey=|SharedAccessKey=|SharedAccessSignature=|Password=|Pwd=)[^;]+|[?&]sig=[^&\s]+|^eyJ[\w-]+\.[\w-]+\.[\w-]+$|-----BEGIN [A-Z ]*PRIVATE KEY-----' $walk = { param($Value, [string] $Name) if ($null -eq $Value) { return $null } if ($Value -is [System.Collections.IDictionary]) { $copy = [ordered]@{} foreach ($k in $Value.Keys) { $copy[[string]$k] = & $walk $Value[$k] ([string]$k) } return $copy } if ($Value -is [System.Collections.IEnumerable] -and $Value -isnot [string]) { return , @(foreach ($item in $Value) { & $walk $item $Name }) } if ($Value -is [string] -and $Value) { if (($Name -and $Name -match $secretKey) -or $Value -match $secretValue) { if ($Count) { $Count.Value++ } return '[REDACTED]' } } $Value } & $walk $InputObject '' } |