Providers/Authentik/Public/Get-AuthentikServiceApp.ps1
|
function Get-AuthentikServiceApp { <# .SYNOPSIS Reports the stored service account credential and whether it still works .DESCRIPTION Reads the credential record for an instance and says what this machine would connect as: the account, where its token is kept and how it is protected. Connected, it also checks that the account still exists in the instance. With -TestCredential it proves the token by calling the API with it, which is the check to run before rotating anything when a connect has failed. The token itself is never in the output. .PARAMETER CredentialPath The record to read, when not in the default location. .PARAMETER BaseUrl The instance whose default record to read, when not connected. .PARAMETER VaultPassword The SecretStore password, when the token is in a vault whose password is not a default. .PARAMETER TestCredential Prove the token authenticates. .OUTPUTS PSCustomObject with BaseUrl, Username, UserPk, Protection, VaultName, SecretName, CredentialPath, CreatedUtc, AccountExists and CredentialWorks. .EXAMPLE PS> Get-AuthentikServiceApp -TestCredential DESCRIPTION: Reads the record and proves the token OUTPUT: The account's identifiers with CredentialWorks true or false USE CASE: Diagnosing a failed Connect-TestEnvironment -ServiceAccount .NOTES Author: Jeffrey Stuhr Blog: https://www.techbyjeff.net LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', 'CredentialPath', Justification = 'A file path to a credential record, not a credential.')] [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter()] [string]$CredentialPath, [Parameter()] [string]$BaseUrl, [Parameter()] [System.Security.SecureString]$VaultPassword, [Parameter()] [switch]$TestCredential ) $connection = Get-AuthentikConnection -AllowNone $resolvedUrl = if ($BaseUrl) { $BaseUrl } elseif ($connection) { $connection.BaseUrl } else { $null } if (-not $resolvedUrl -and -not $CredentialPath) { throw 'Not connected. Pass -BaseUrl, or -CredentialPath, or connect first.' } $existingPath = if ($CredentialPath) { $CredentialPath } elseif ($connection) { $connection.CredentialPath } else { $null } $recordPath = Get-AuthentikCredentialPath -BaseUrl $(if ($resolvedUrl) { $resolvedUrl } else { 'https://unknown' }) -Path $existingPath if (-not (Test-Path -LiteralPath $recordPath)) { Write-Warning "No credential record at $recordPath. Run New-TestServiceApp after connecting with an API token." return } $credential = Import-AuthentikCredential -Path $recordPath -VaultPassword $VaultPassword $accountExists = $null if ($connection) { try { $null = Invoke-AuthentikRequest -Method GET -Path "/core/users/$($credential.UserPk)/" -Connection $connection $accountExists = $true } catch { $accountExists = $false Write-Verbose "Could not read the account back: $($_.Exception.Message)" } } $credentialWorks = $null if ($TestCredential) { try { $probe = @{ BaseUrl = $credential.BaseUrl; AuthorizationHeader = "Bearer $($credential.Token)"; AuthType = 'ServiceAccount' } $me = Invoke-AuthentikRequest -Method GET -Path '/core/users/me/' -Connection $probe $credentialWorks = [bool]($me -and $me.user -and $me.user.username -eq $credential.Username) } catch { $credentialWorks = $false Write-Verbose "Credential test failed: $($_.Exception.Message)" } } return [PSCustomObject]@{ PSTypeName = 'AuthentikServiceAppStatus' BaseUrl = $credential.BaseUrl Username = $credential.Username UserPk = $credential.UserPk Protection = $credential.Protection VaultName = $credential.VaultName SecretName = $credential.SecretName CredentialPath = $recordPath CreatedUtc = $credential.CreatedUtc AccountExists = $accountExists CredentialWorks = $credentialWorks } } |