Public/Discovery/Get-FederatedAppCredential.ps1
|
function Get-FederatedAppCredential { [cmdletbinding()] param ( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Alias('Id', 'object-id')] [ValidatePattern('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$', ErrorMessage = "It does not match expected pattern '{1}'")] [string]$ObjectId, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Alias('application-id')] [ValidatePattern('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$', ErrorMessage = "It does not match expected pattern '{1}'")] [string]$AppId, [Parameter(Mandatory = $false)] [ValidateSet("Object", "JSON", "CSV", "Table")] [Alias("output", "o")] [string]$OutputFormat = "Table" ) begin { Write-Verbose " Starting function $($MyInvocation.MyCommand.Name)" $MyInvocation.MyCommand.Name | Invoke-BlackCat -ResourceTypeName 'MSGraph' } process { try { $results = @() $app = $null if ($AppId) { Write-Host " Resolving Application ID to Object ID..." -ForegroundColor Cyan Write-Verbose " Get Application with Application Id $($AppId)" $app = Invoke-MsGraph -relativeUrl "applications(appId='$AppId')" -NoBatch $ObjectId = $app.id Write-Host " Resolved to application: $($app.displayName)" -ForegroundColor Green } elseif ($ObjectId) { Write-Host " Retrieving application details..." -ForegroundColor Cyan Write-Verbose " Get Application with Object Id $($ObjectId)" $app = Invoke-MsGraph -relativeUrl "applications/$ObjectId" -NoBatch Write-Host " Found application: $($app.displayName)" -ForegroundColor Green } Write-Host " Analyzing federated identity credentials..." -ForegroundColor Yellow Write-Verbose " Get Federated Identity Credentials for Application: $($app.displayName)" $federatedCreds = Invoke-MsGraph -relativeUrl "applications/$ObjectId/federatedIdentityCredentials" if ($federatedCreds -and $federatedCreds.Count -gt 0) { Write-Host " Found $($federatedCreds.Count) federated credential(s)" -ForegroundColor Green # Enhance output with application context and emojis foreach ($cred in $federatedCreds) { $enhancedCred = [PSCustomObject]@{ 'App Name' = "$($app.displayName)" 'App ID' = $app.appId 'Object ID' = $app.id 'Credential Name' = "$($cred.name)" 'Subject' = $cred.subject 'Issuer' = $cred.issuer 'Audiences' = $cred.audiences -join ', ' 'Description' = $cred.description } $results += $enhancedCred } Write-Host "`n Federated Credential Analysis Summary:" -ForegroundColor Magenta Write-Host " Application: $($app.displayName)" -ForegroundColor White Write-Host " Total Credentials: $($federatedCreds.Count)" -ForegroundColor Yellow # Group by issuer for summary $issuerCounts = $results | Group-Object 'Issuer' | Sort-Object Count -Descending Write-Host " Issuers:" -ForegroundColor Cyan foreach ($group in $issuerCounts) { $issuerName = $group.Name if ($issuerName -eq 'https://token.actions.githubusercontent.com') { $issuerName = " GitHub Actions" } elseif ($issuerName -match 'sts\.windows\.net') { $issuerName = " Azure AD" } elseif ($issuerName -match 'login\.microsoftonline\.com') { $issuerName = " Microsoft Identity Platform" } Write-Host " $($issuerName): $($group.Count)" -ForegroundColor White } } else { Write-Host " No federated identity credentials found" -ForegroundColor Red } # Format and return results using the standardized output formatter Format-BlackCatOutput -Data $results -OutputFormat $OutputFormat -FunctionName $MyInvocation.MyCommand.Name } catch { Write-Message -FunctionName $($MyInvocation.MyCommand.Name) -Message " $($_.Exception.Message)" -Severity 'Error' } } <# .SYNOPSIS Retrieves federated identity credentials for Microsoft Entra applications. .DESCRIPTION Retrieves federated identity credentials configured for Entra applications. These credentials enable OIDC token exchange patterns commonly used in CI/CD pipelines and external workload identities. The function queries Microsoft Graph to enumerate all federated credentials on specified applications. .PARAMETER ObjectId The Object ID (GUID) of the Microsoft Entra application. This parameter must match the pattern of a valid GUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). .PARAMETER AppId The Application ID (GUID) of the Microsoft Entra application. This parameter must match the pattern of a valid GUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). If provided, it will be resolved to the corresponding Object ID. .PARAMETER OutputFormat Specifies the output format for the results. Valid values are: - Table (default): Displays results in a formatted table - Object: Returns PowerShell objects - JSON: Exports results to a timestamped JSON file - CSV: Exports results to a timestamped CSV file .EXAMPLE Get-FederatedAppCredential -ObjectId "12345678-1234-1234-1234-123456789012" Retrieves all federated identity credentials for the specified application using its Object ID. .EXAMPLE Get-FederatedAppCredential -AppId "87654321-4321-4321-4321-210987654321" Retrieves all federated identity credentials for the specified application using its Application ID. .EXAMPLE Get-FederatedAppCredential -ObjectId "12345678-1234-1234-1234-123456789012" -OutputFormat JSON Retrieves all federated identity credentials for the specified application and exports results to a JSON file. .EXAMPLE Get-FederatedAppCredential -AppId "87654321-4321-4321-4321-210987654321" -OutputFormat CSV Retrieves all federated identity credentials for the specified application and exports results to a CSV file. .EXAMPLE Invoke-MsGraph -relativeUrl "applications" | Get-FederatedAppCredential Retrieves all federated identity credentials for all applications returned by the `Invoke-MsGraph` command. .EXAMPLE Get-AzAdApplication -All $true | Get-FederatedAppCredential Retrieves all federated identity credentials for all applications returned by the `Get-AzAdApplication` command. .OUTPUTS PSCustomObject with enhanced properties: - App Name: Display name of the application (with emoji) - App ID: Application ID (GUID) - Object ID: Object ID (GUID) - Credential Name: Name of the federated credential (with emoji) - Subject: The subject claim pattern - Issuer: The token issuer URL - Audiences: Comma-separated list of audiences - Description: Credential description .LINK https://learn.microsoft.com/en-us/graph/api/application-list-federatedidentitycredentials .NOTES This function requires Microsoft Graph permissions to read application configurations: - Application.Read.All (application permission) - Application.ReadWrite.All (application permission) - Directory.Read.All (application permission) .LINK MITRE ATT&CK Tactic: TA0007 - Discovery https://attack.mitre.org/tactics/TA0007/ .LINK MITRE ATT&CK Technique: T1526 - Cloud Service Discovery https://attack.mitre.org/techniques/T1526/ #> } |