Private/Assert-CIEMAuthenticated.ps1

function Assert-CIEMAuthenticated {
    <#
    .SYNOPSIS
        Asserts that CIEM is authenticated to the specified provider.

    .DESCRIPTION
        Internal function used by scan functions to verify authentication before
        proceeding. Throws an error with instructions to run Connect-CIEM if not
        authenticated.

        If an AzContext exists but the script-scoped AuthContext hasn't been
        populated (e.g., module was reloaded), this function will populate it
        from the existing context.

    .PARAMETER Provider
        The cloud provider to check. Defaults to the provider in CIEM config.

    .EXAMPLE
        Assert-CIEMAuthenticated
        # Throws if not authenticated to default provider

    .EXAMPLE
        Assert-CIEMAuthenticated -Provider Azure
        # Throws if not authenticated to Azure
    #>

    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateSet('Azure', 'AWS')]
        [string]$Provider
    )

    if (-not $Provider) {
        $Provider = $script:Config.cloudProvider
    }

    # Initialize auth context storage if not exists
    if (-not $script:AuthContext) {
        $script:AuthContext = @{}
    }

    # Check if authenticated via Test-CIEMAuthenticated
    $authStatus = Test-CIEMAuthenticated -Provider $Provider | Where-Object { $_.Provider -eq $Provider }

    if (-not $authStatus -or -not $authStatus.Authenticated) {
        throw @"
Not authenticated to $Provider. Run Connect-CIEM first to establish authentication.

Example:
    Connect-CIEM

Or to connect to a specific provider:
    Connect-CIEM -Provider $Provider

Use Test-CIEMAuthenticated to check connection status.
"@

    }

    # If we're authenticated but AuthContext is not populated, populate it from existing context
    # This handles cases where module was reloaded but AzContext persists
    if (-not $script:AuthContext[$Provider]) {
        Write-Verbose "AuthContext not populated but provider is authenticated. Populating from existing context..."

        if ($Provider -eq 'Azure') {
            $context = Get-AzContext -ErrorAction Stop

            # Get subscriptions
            $subscriptions = @(Get-AzSubscription -TenantId $context.Tenant.Id -ErrorAction SilentlyContinue)
            $subscriptionIds = @($subscriptions | Select-Object -ExpandProperty Id)

            # Determine account type
            $accountType = switch ($context.Account.Type) {
                'User' { 'User' }
                'ServicePrincipal' { 'ServicePrincipal' }
                'ManagedService' { 'ManagedIdentity' }
                default { $context.Account.Type }
            }

            $script:AuthContext['Azure'] = [PSCustomObject]@{
                TenantId        = $context.Tenant.Id
                SubscriptionIds = $subscriptionIds
                AccountId       = $context.Account.Id
                AccountType     = $accountType
                ConnectedAt     = Get-Date
            }

            Write-Verbose "Populated AuthContext from existing AzContext: $($context.Account.Id)"
        }
    }

    # Return the auth context for convenience
    $script:AuthContext[$Provider]
}