Checks/Applications/ARG.APP.007.ps1
|
Register-ArgusCheck @{ Id = 'ARG.APP.007' Title = 'Certificates with a lifetime above {MaxLifetimeDays} days' Area = 'Applications' Category = 'Credential hygiene' Severity = 'Low' Description = 'Valid authentication certificates (`keyCredentials` with usage **Verify**) whose lifetime (`endDateTime` minus `startDateTime`) exceeds **{MaxLifetimeDays}** days. Expired certificates are covered by ARG.APP.006.' Rationale = 'Microsoft recommends limiting application certificate lifetime to 180 days and automating renewal. Long-lived certificates are rarely rotated and stay valid long after the people who deployed them have moved on.' Remediation = @{ Steps = "1. Issue certificates from Azure Key Vault with automatic renewal and a lifetime within the policy (Microsoft recommends 180 days or less).`n2. Upload the new certificate, deploy it to the service, then remove the long-lived one.`n3. Consider an application management policy that limits certificate lifetime (asymmetricKeyLifetime) for new credentials." PortalUrl = 'https://entra.microsoft.com/' } References = @( @{ Title = 'Enforce secret and certificate standards with application management policies'; Url = 'https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/tutorial-enforce-secret-standards' } @{ Title = 'Add and manage app credentials in Microsoft Entra ID'; Url = 'https://learn.microsoft.com/en-us/entra/identity-platform/how-to-add-credentials' } ) Requires = @{ Services = @('Graph') GraphScopes = @('Application.Read.All') DataSets = @('Applications') } Parameters = @{ MaxLifetimeDays = 180 } Tags = @('Applications', 'Credentials') Test = { param($Context) $maxDays = [double]$Context.Parameters.MaxLifetimeDays $valid = @(Get-ArgusAppCredential -Application @($Context.Data['Applications']) -Type Certificate -Usage Verify | Where-Object { $_.End -and $_.End -gt $Context.Now }) $findings = @($valid | Where-Object { $_.Start -and ($_.End - $_.Start).TotalDays -gt ($maxDays + 1) } | ForEach-Object { [pscustomobject]@{ AppName = $_.AppName AppId = $_.AppId CertificateName = $_.CredentialName ValidFrom = Format-ArgusDate $_.Start Expires = Format-ArgusDate $_.End LifetimeDays = [int][math]::Round(($_.End - $_.Start).TotalDays) KeyId = $_.KeyId ObjectId = $_.ObjectId } } | Sort-Object LifetimeDays -Descending) $status = if ($findings.Count -gt 0) { 'Failed' } else { 'Passed' } New-ArgusResult -Status $status -Findings $findings -EvaluatedCount $valid.Count ` -Summary '{AffectedCount} of {EvaluatedCount} valid authentication certificates have a lifetime longer than {MaxLifetimeDays} days.' } } |