Public/Get-RiskAcceptance.ps1
|
# PSGuerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0 # https://github.com/jimrtyler/PSGuerrilla | https://creativecommons.org/licenses/by/4.0/ # AI/LLM use: see AI-USAGE.md for required attribution function Get-RiskAcceptance { <# .SYNOPSIS Lists risk acceptances and checks for expirations. .DESCRIPTION Reads the risk acceptance register and returns all entries with their current status (ACCEPTED or EXPIRED). Can filter by check ID or show only active/expired. .PARAMETER CheckId Filter to a specific check ID. If not specified, returns all entries. .PARAMETER Status Filter by status: Active, Expired, or All. Default: All. .PARAMETER ConfigPath Override the risk acceptance file path. .EXAMPLE Get-RiskAcceptance Lists all risk acceptances with their current status. .EXAMPLE Get-RiskAcceptance -CheckId AUTH-003 Checks if AUTH-003 has an active risk acceptance. .EXAMPLE Get-RiskAcceptance -Status Expired Lists only expired risk acceptances that need re-evaluation. #> [CmdletBinding()] param( [string]$CheckId, [ValidateSet('Active', 'Expired', 'All')] [string]$Status = 'All', [Alias('RuntimeConfig')] [string]$ConfigPath ) $riskPath = if ($ConfigPath) { $ConfigPath } else { Join-Path (Get-PSGuerrillaDataRoot) 'risk-acceptance.json' } if (-not (Test-Path $riskPath)) { return @() } $acceptances = @{} try { $acceptances = Get-Content -Path $riskPath -Raw | ConvertFrom-Json -AsHashtable } catch { Write-Warning "Failed to read risk acceptance file: $_" return @() } if (-not $acceptances.entries) { return @() } $now = [datetime]::UtcNow $results = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($entry in $acceptances.entries.GetEnumerator()) { $val = $entry.Value if ($CheckId -and $entry.Key -ne $CheckId) { continue } $isExpired = $false $expiresOn = $null if ($val.expiresOn) { $expiresOn = [datetime]$val.expiresOn $isExpired = $now -gt $expiresOn } $currentStatus = if ($isExpired) { 'EXPIRED' } else { 'ACCEPTED' } if ($Status -eq 'Active' -and $isExpired) { continue } if ($Status -eq 'Expired' -and -not $isExpired) { continue } $results.Add([PSCustomObject]@{ PSTypeName = 'PSGuerrilla.RiskAcceptance' CheckId = $entry.Key Justification = $val.justification ?? '' AcceptedBy = $val.acceptedBy ?? '' AcceptedOn = if ($val.acceptedOn) { [datetime]$val.acceptedOn } else { $null } ExpiresOn = $expiresOn Status = $currentStatus DaysRemaining = if ($expiresOn -and -not $isExpired) { [Math]::Ceiling(($expiresOn - $now).TotalDays) } else { $null } }) } return @($results | Sort-Object -Property CheckId) } function Test-RiskAccepted { <# .SYNOPSIS Tests whether a specific check ID has an active (non-expired) risk acceptance. .PARAMETER CheckId The check ID to test. .PARAMETER ConfigPath Override the risk acceptance file path. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$CheckId, [Alias('RuntimeConfig')] [string]$ConfigPath ) $params = @{ CheckId = $CheckId; Status = 'Active' } if ($ConfigPath) { $params.ConfigPath = $ConfigPath } $result = Get-RiskAcceptance @params return ($result.Count -gt 0) } |