Rules/APP-001.expiring-credentials.psd1

@{
    Id          = 'APP-001'
    Title       = 'No app credentials are expired or about to expire'
    Area        = 'Applications'
    Severity    = 'High'
    References  = @(
        'https://learn.microsoft.com/entra/identity-platform/how-to-add-credentials'
    )
    Rationale   = 'Expired credentials break integrations without warning; credentials expiring unnoticed within 30 days are outages waiting to happen - and often get "fixed" with rushed, over-privileged replacements.'
    Remediation = 'Rotate the affected app credentials ahead of expiry and set up expiry monitoring (this rule in a scheduled TenantLens run works).'
    Test        = {
        param($Snapshot)
        $applications = @($Snapshot.Applications.applications)
        $affected = @($applications | Where-Object {
                $_.PSObject.Properties['_tlCredentialStatus'] -and $_._tlCredentialStatus -and
                (([int]$_._tlCredentialStatus.expired -gt 0) -or ([int]$_._tlCredentialStatus.expiringWithin30Days -gt 0))
            })
        if ($affected.Count -gt 0) {
            New-TLRuleResult -Status Fail -Evidence @($affected | ForEach-Object {
                    "{0}: {1} expired, {2} expiring within 30 days" -f $_.displayName, $_._tlCredentialStatus.expired, $_._tlCredentialStatus.expiringWithin30Days
                })
        }
        else {
            New-TLRuleResult -Status Pass -Evidence ("No expired or soon-expiring credentials across {0} app registrations." -f $applications.Count)
        }
    }
}