Private/Get-MsecAccessToken.ps1

function Get-MsecAccessToken {
    <#
    .SYNOPSIS
        Returns a cached or freshly acquired bearer token for the given Entra resource.

    .DESCRIPTION
        Looks up $script:MsecSession.Tokens[$Resource]; if present and not within 60s of expiry,
        returns it. Otherwise builds a JWT client assertion signed by Key Vault (the private
        key never leaves the vault) and exchanges it at the v2.0 /token endpoint for the
        resource's /.default scope.
    #>

    [CmdletBinding()]
    param(
        # The API resource, e.g. 'https://graph.microsoft.com' or 'https://api.securitycenter.microsoft.com'.
        [Parameter(Mandatory)]
        [string] $Resource
    )

    Assert-MsecSession
    $session = $script:MsecSession

    $cached = $session.Tokens[$Resource]
    if ($cached -and $cached.ExpiresOn -gt [DateTimeOffset]::UtcNow.AddSeconds(60)) {
        return $cached.Token
    }

    # AAD login authority for the session's cloud. Falls back to commercial when the
    # session predates endpoint resolution (older Connect-Msec, or unit-test sessions).
    $authority = if ($session.Endpoints -and $session.Endpoints.AadAuthority) {
        $session.Endpoints.AadAuthority
    }
    else {
        'https://login.microsoftonline.com'
    }

    Write-Verbose "Acquiring access token for $Resource via $authority"
    $assertion = New-MsecClientAssertion `
        -TenantId        $session.TenantId `
        -ClientId        $session.ClientId `
        -VaultName       $session.KeyVaultName `
        -KeyName         $session.KeyName `
        -ThumbprintBytes $session.ThumbprintBytes `
        -Authority       $authority

    $response = Invoke-RestMethod -Method Post -ErrorAction Stop `
        -Uri "$authority/$($session.TenantId)/oauth2/v2.0/token" `
        -ContentType 'application/x-www-form-urlencoded' `
        -Body @{
            client_id             = $session.ClientId
            scope                 = "$Resource/.default"
            client_assertion_type = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
            client_assertion      = $assertion
            grant_type            = 'client_credentials'
        }

    $session.Tokens[$Resource] = @{
        Token     = $response.access_token
        ExpiresOn = [DateTimeOffset]::UtcNow.AddSeconds([int]$response.expires_in)
    }

    $response.access_token
}