Private/Get-FDAProviderToken.ps1

function Get-FDAServicePrincipalToken {
    <#
    .SYNOPSIS
        Acquire an app-only (client-credentials) token for a scope using the
        Service Principal configuration in module state.
    .DESCRIPTION
        Supports both secret-based and certificate-based (client-assertion)
        auth. Reads ClientId / ClientSecret / Certificate / TenantId from
        $script:FDAState so the provider scriptblock stays a plain,
        module-affiliated block (see Connect-FDAObservability for why this
        matters — closures cannot resolve module-private functions such as
        New-FDAClientAssertion).
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)] [string] $Scope)

    $tenant = $script:FDAState.TenantId
    $cid    = $script:FDAState.ClientId
    $sec    = $script:FDAState.ClientSecret
    $cert   = $script:FDAState.Certificate

    $tokenUrl = "https://login.microsoftonline.com/$tenant/oauth2/v2.0/token"
    $form = @{
        client_id  = $cid
        grant_type = 'client_credentials'
        scope      = $Scope
    }
    if ($cert) {
        # Client assertion (cert) flow.
        $jwt = New-FDAClientAssertion -ClientId $cid -TenantId $tenant -Certificate $cert
        $form['client_assertion_type'] = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
        $form['client_assertion'] = $jwt
    } else {
        $plain = [System.Net.NetworkCredential]::new('', $sec).Password
        $form['client_secret'] = $plain
    }
    $resp = Invoke-RestMethod -Method Post -Uri $tokenUrl -Body $form -ErrorAction Stop
    [pscustomobject]@{
        Token     = $resp.access_token
        ExpiresOn = (Get-Date).AddSeconds([int]$resp.expires_in)
    }
}

function Get-FDAManagedIdentityToken {
    <#
    .SYNOPSIS
        Acquire a Managed Identity token for a scope via IMDS, honoring the
        App Service / Azure Arc IDENTITY_ENDPOINT variant when present.
    .DESCRIPTION
        Reads the optional user-assigned MI client id from module state.
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)] [string] $Scope)

    $miCid = $script:FDAState.ManagedIdentityClientId
    # IMDS endpoint. resource = scope-without-/.default suffix.
    $resource = $Scope -replace '/\.default$', ''
    $imds = 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource={0}' -f [uri]::EscapeDataString($resource)
    if ($miCid) {
        $imds += '&client_id=' + [uri]::EscapeDataString($miCid)
    }
    $headers = @{ Metadata = 'true' }
    # Azure Arc / App Service variants use env-supplied endpoints. Detect:
    if ($env:IDENTITY_ENDPOINT -and $env:IDENTITY_HEADER) {
        $imds = '{0}?resource={1}&api-version=2019-08-01' -f $env:IDENTITY_ENDPOINT, [uri]::EscapeDataString($resource)
        if ($miCid) { $imds += '&client_id=' + [uri]::EscapeDataString($miCid) }
        $headers = @{ 'X-IDENTITY-HEADER' = $env:IDENTITY_HEADER }
    }
    $resp = Invoke-RestMethod -Method Get -Uri $imds -Headers $headers -ErrorAction Stop
    $expires = if (($resp.PSObject.Properties.Name -contains 'expires_on') -and $resp.expires_on) {
        [DateTimeOffset]::FromUnixTimeSeconds([long]$resp.expires_on).LocalDateTime
    } else {
        (Get-Date).AddSeconds([int]$resp.expires_in)
    }
    [pscustomobject]@{
        Token     = $resp.access_token
        ExpiresOn = $expires
    }
}