Rules/APP-004.client-secrets-in-use.psd1

@{
    Id          = 'APP-004'
    Title       = 'App registrations use certificates instead of client secrets'
    Area        = 'Applications'
    Severity    = 'Low'
    References  = @(
        'https://learn.microsoft.com/entra/identity-platform/security-best-practices-for-app-registration'
    )
    Rationale   = 'Client secrets are strings that end up in scripts, pipelines and chat messages. Certificates (or managed identities) are harder to leak and easier to rotate cleanly.'
    Remediation = 'Replace client secrets with certificate credentials or federated credentials/managed identities where the workload supports them.'
    Test        = {
        param($Snapshot)
        $applications = @($Snapshot.Applications.applications)
        $withSecrets = @($applications | Where-Object {
                $_.PSObject.Properties['_tlCredentialStatus'] -and $_._tlCredentialStatus -and
                ([int]$_._tlCredentialStatus.passwordCredentials -gt 0)
            })
        if ($withSecrets.Count -gt 0) {
            New-TLRuleResult -Status Fail -Evidence @($withSecrets | ForEach-Object {
                    "{0}: {1} client secret(s)" -f $_.displayName, $_._tlCredentialStatus.passwordCredentials
                })
        }
        else {
            New-TLRuleResult -Status Pass -Evidence ("No client secrets across {0} app registrations." -f $applications.Count)
        }
    }
}