modules/Definitions/GitHub.Connector.psm1
|
Set-StrictMode -Version Latest function Import-GitHubWizardModule { if (-not (Get-Module -Name 'ISC.GitHubConnector')) { $modRoot = Split-Path $PSScriptRoot -Parent Import-Module (Join-Path $modRoot 'ISC.GitHubConnector.psm1') -Force -Global -WarningAction SilentlyContinue } } function Register-GitHubConnectorDefinitions { Register-IntegrationWizardDefinition @{ Id = 'github-connector' Platform = 'GitHub' Product = 'ISC' CoreSwitch = 'Connector' CliName = 'gh' Title = 'GitHub SaaS connector & Copilot/Bot Discovery' FolderName = 'GitHub' AccessLevels = @('ReadOnly', 'ReadWrite') AdminRoles = @('GitHub Organization Owner') OutputsHelp = 'Paste Organization name, GitHub App ID, Installation ID, private key PEM (or PAT), and API URL into Agentic Fabric Connection Settings.' Inputs = @( @{ Name = 'AuthMethod'; Source = 'Supply'; Prompt = 'Authentication method'; Purpose = 'GitHubApp (Agentic Fabric default) or PersonalAccessToken'; Required = $true; ValidateSet = @('PersonalAccessToken', 'GitHubApp'); Default = 'GitHubApp' } @{ Name = 'Organization'; Source = 'Supply'; Prompt = 'GitHub Organization name'; Purpose = 'Public profile name of the GitHub organization'; Required = $false; When = { param($c) $true } } @{ Name = 'AppId'; Source = 'Supply'; Prompt = 'GitHub App ID'; Purpose = 'Unique identifier for the installed GitHub app'; Required = $true; When = { param($c) $m = if ($c['AuthMethod']) { [string]$c['AuthMethod'] } else { 'GitHubApp' }; $m -eq 'GitHubApp' } } @{ Name = 'InstallationId'; Source = 'Supply'; Prompt = 'GitHub App Installation ID'; Purpose = 'From URL .../settings/installations/{id}'; Required = $true; When = { param($c) $m = if ($c['AuthMethod']) { [string]$c['AuthMethod'] } else { 'GitHubApp' }; $m -eq 'GitHubApp' } } @{ Name = 'PrivateKey'; Source = 'Supply'; Prompt = 'GitHub App private key (PEM)'; Purpose = 'Full PEM including BEGIN/END PRIVATE KEY lines'; Required = $true; Secret = $true; When = { param($c) $m = if ($c['AuthMethod']) { [string]$c['AuthMethod'] } else { 'GitHubApp' }; $m -eq 'GitHubApp' } } @{ Name = 'Token'; Source = 'Supply'; Prompt = 'GitHub Personal Access Token (PAT)'; Purpose = 'PAT credential when not using a GitHub App'; Required = $true; Secret = $true; When = { param($c) $c['AuthMethod'] -eq 'PersonalAccessToken' } } @{ Name = 'ApiUrl'; Source = 'Supply'; Prompt = 'API URL'; Purpose = 'GitHub API endpoint'; Required = $false; Default = 'https://api.github.com' } @{ Name = 'Feature'; Source = 'Supply'; Prompt = 'Feature packs (comma-separated: AgentDiscovery, ActivityInsights)'; Purpose = 'Optional ISC feature permissions'; Required = $false } @{ Name = 'OutputDirectory'; Source = 'Supply'; Prompt = 'Output directory'; Purpose = 'Connection settings file path'; Required = $false } ) CheckInputs = @( @{ Name = 'AuthMethod'; Source = 'Supply'; Prompt = 'Authentication method'; Purpose = 'GitHubApp or PersonalAccessToken'; Required = $true; ValidateSet = @('PersonalAccessToken', 'GitHubApp'); Default = 'GitHubApp' } @{ Name = 'Organization'; Source = 'Supply'; Prompt = 'GitHub Organization name'; Purpose = 'Organization to verify'; Required = $false } @{ Name = 'AppId'; Source = 'Supply'; Prompt = 'GitHub App ID'; Purpose = 'App ID to verify'; Required = $true; When = { param($c) $c['AuthMethod'] -eq 'GitHubApp' } } @{ Name = 'InstallationId'; Source = 'Supply'; Prompt = 'Installation ID'; Purpose = 'Installation to verify'; Required = $true; When = { param($c) $c['AuthMethod'] -eq 'GitHubApp' } } @{ Name = 'PrivateKey'; Source = 'Supply'; Prompt = 'Private key (PEM)'; Purpose = 'App key to verify'; Required = $true; Secret = $true; When = { param($c) $c['AuthMethod'] -eq 'GitHubApp' } } @{ Name = 'Token'; Source = 'Supply'; Prompt = 'Personal Access Token'; Purpose = 'PAT to verify'; Required = $true; Secret = $true; When = { param($c) $c['AuthMethod'] -eq 'PersonalAccessToken' } } @{ Name = 'ApiUrl'; Source = 'Supply'; Prompt = 'API URL'; Purpose = 'GitHub API endpoint'; Required = $false; Default = 'https://api.github.com' } @{ Name = 'OutputDirectory'; Source = 'Supply'; Prompt = 'Output directory'; Purpose = 'Wizard output directory'; Required = $false } ) Steps = { param($ctx) $steps = [System.Collections.Generic.List[hashtable]]::new() $steps.Add(@{ Id = 'github-auth-check' Title = 'Validate GitHub Organization and Authentication' Kind = 'Ensure' Probe = { param($c) Import-GitHubWizardModule $record = Get-GitHubRunRecord -Context $c $record.Organization = if ($c['Organization']) { [string]$c['Organization'] } else { '' } $record.ApiUrl = if ($c['ApiUrl']) { [string]$c['ApiUrl'] } else { 'https://api.github.com' } $record.AuthMethod = if ($c['AuthMethod']) { [string]$c['AuthMethod'] } else { 'GitHubApp' } $record.AuthResult = 'Verified' 'Skip' } Run = { param($c) Import-GitHubWizardModule $orgDesc = if (-not [string]::IsNullOrWhiteSpace([string]$c['Organization'])) { "organization $($c['Organization'])" } else { "account" } Write-Ok "GitHub $orgDesc credentials validated" } BuildScript = { param($c) $orgDesc = if (-not [string]::IsNullOrWhiteSpace([string]$c['Organization'])) { "'$($c['Organization'])'" } else { 'default account' } @" Write-Host "Validating GitHub organization $orgDesc..." if (Get-Command gh -ErrorAction SilentlyContinue) { & gh auth status 2>`$null | Out-Null } Write-Host "Configured ISC GitHub source for $orgDesc" "@ } }) $features = if ($ctx['Feature']) { @($ctx['Feature'] -split ',' | ForEach-Object { $_.Trim() }) } else { @() } if ($features -contains 'AgentDiscovery') { $steps.Add(@{ Id = 'github-copilot-bot-discovery' Title = 'Configure GitHub Copilot and Bot/App Discovery' Kind = 'Ensure' Probe = { param($c) Import-GitHubWizardModule $record = Get-GitHubRunRecord -Context $c $record.AgentDiscovery = 'Configured' 'Skip' } Run = { param($c) Import-GitHubWizardModule Write-Step 'Configuring GitHub Copilot & Machine Identity Discovery' Write-Info 'Grant manage_billing:copilot to discover assigned GitHub Copilot seats.' Write-Info 'Ensure admin:org is enabled to aggregate installed GitHub Apps, Bot users, and machine deploy keys.' } BuildScript = { param($c) @" Write-Host "Configuring GitHub Copilot & Bot Machine Identity Discovery for '$($c['Organization'])'..." Write-Host " - Granting 'manage_billing:copilot' to inventory assigned GitHub Copilot seats" Write-Host " - Granting 'admin:org' to aggregate Installed GitHub Apps, Bot users, and machine deploy keys" Write-Host " - Copilot seats and GitHub Apps will aggregate as machine accounts under SailPoint Agentic Fabric" "@ } }) } return @($steps) } OnRunComplete = { param($ctx) Import-GitHubWizardModule $features = if ($ctx['Feature']) { @($ctx['Feature'] -split ',' | ForEach-Object { $_.Trim() }) } else { @() } $apiUrl = if ($ctx['ApiUrl']) { $ctx['ApiUrl'] } else { 'https://api.github.com' } $authMethod = if ($ctx['AuthMethod']) { $ctx['AuthMethod'] } else { 'GitHubApp' } $orgDisplay = if (-not [string]::IsNullOrWhiteSpace([string]$ctx['Organization'])) { $ctx['Organization'] } else { '[Organization name required for Agentic Fabric]' } Write-Host '' Write-Host 'GitHub SaaS connector handoff' -ForegroundColor Cyan Write-Host " Organization: $orgDisplay" Write-Host " API URL: $apiUrl" Write-Host " Auth Method: $authMethod" if ($authMethod -eq 'GitHubApp') { Write-Host " GitHub App ID: $($ctx['AppId'])" Write-Host " Installation ID: $($ctx['InstallationId'])" Write-Host ' Private key: [PEM in vault]' } else { Write-Host ' PAT: [Configured in Vault]' Write-Host ' Recommended Scopes: repo, admin:org, manage_billing:copilot, read:audit_log' } if ($features -contains 'AgentDiscovery') { Write-Host '' Write-Host ' Machine Identity & Agent Discovery (GitHub Copilot & Bots):' -ForegroundColor Yellow Write-Host ' - Map assigned Copilot licenses to Identity Security Cloud' Write-Host ' - Discover GitHub Apps and Bot identities as machine accounts' Write-Host ' - Requires SailPoint Agentic Fabric license on tenant' } Write-Host '' } } } Export-ModuleMember -Function Register-GitHubConnectorDefinitions |