CloudCloud FlowsScheduledPremium connectors

Offboarding Collaborator Cross-Check

Daily flow compares List Repository Collaborators output against the Azure AD Active Employees group; anyone no longer active triggers a ServiceNow-style ticket via HTTP for manual removal review.

Members OnlySign in or create a free account to download this solution.

Overview

Every weekday morning at 06:00 ET, cross-references collaborators on a configurable list of GitHub repositories against the Active Employees group in Microsoft Entra ID. Anyone present in GitHub but missing from the group is treated as potentially offboarded — opens a ServiceNow incident for manual removal review and rolls every hit into a single HTML summary email sent to Security Operations. On clean days the flow stays silent.

**State:** Stopped

Use Case

External GitHub collaborators routinely outlive the engineers who added them — contractors finish projects, employees leave, nobody remembers to revoke repo access. This flow gives Security Operations a daily, automated, zero-effort answer to "who has access to our repos that shouldn't?" without forcing IT to maintain a parallel access spreadsheet.

**Key Benefits:** daily detection; auto-creates ServiceNow incidents; single consolidated email per day; word-boundary CSV match avoids false positives; defensive coalesce around connector bodies.

Flow Architecture

Trigger: **Recurrence — Daily 06:00 EST**.

1. Init 8 vars (repo list, active group ID, SNow endpoint, sec email, org, hits HTML, tickets created, active logins CSV)
2. **Get_Active_Employees_Group_Members** (Azure AD GetGroupMembers $top=999)
3. Project_Active_Logins (Select to lowercase mailNickname or UPN local-part)
4. Set_varActiveLoginsCsv to `,login1,login2,...,` (word-boundary)
5. **Apply_To_Each_Monitored_Repo**:
   - List_Repository_Collaborators (GitHub ListCollaborators per_page=100)
   - Apply_To_Each_Collaborator: Check_If_Collaborator_Inactive (If); if inactive: Create_ServiceNow_Incident (HTTP POST), Append_Offboarded_Hit_Row, Increment_Tickets_Created
6. **Check_If_Any_Inactive_Found** (If) → Send_Offboarded_Summary_Email (Outlook High importance)

Environment Variables

VariableSchema NameTypeDefaultPurpose
Monitored Repo Listflowlibs_MonitoredRepoListString(none)Comma-separated owner/repo to audit
Active Employees Group IDflowlibs_ActiveEmployeesGroupIdString(none)Entra group object ID of the Active Employees group
ServiceNow Endpointflowlibs_ServiceNowEndpointString(none)ServiceNow Table API URL or Scripted REST endpoint for incident.do
Security Team Emailflowlibs_SecurityTeamEmailString(none)Distribution list that receives the summary
GitHub Organizationflowlibs_GitHubOrganizationString(none)GitHub org slug

Connectors & Connections

ConnectorAPI NameConnection FormatUsage
Azure ADshared_azureadService account with GroupMember.Read.AllGetGroupMembers — pulls Active Employees group
GitHubshared_githubPAT or OAuth (repo scope)ListCollaborators per monitored repo
Office 365 Outlookshared_office365SecOps sender mailboxSendEmailV2 — daily summary
HTTPshared_httpEndpoint via env varPOST to ServiceNow incident.do

Customization Guide

1. Import; set 5 env vars; bind 3 connection refs; run Flow Checker; manual test; turn on.

**Common Modifications:** different ITSM (Jira CreateIssue, Zendesk); tighten cadence to hourly; multi-group active source via JSON array env var; auto-remove via GitHub RemoveCollaborator (after burn-in); skip bots via Filter Array; per-repo owner email via JSON map.

Key Expressions

- @parameters('flowlibs_MonitoredRepoList') — read repo list
- @concat(',', join(body('Project_Active_Logins'), ','), ',') — build active logins CSV
- @toLower(coalesce(item()?['mailNickname'], split(item()?['userPrincipalName'], '@')[0])) — lowercase login projection
- @not(contains(variables('varActiveLoginsCsv'), concat(',', toLower(item()?['login']), ','))) — word-boundary inactive check

Offboarding Collaborator Cross-Check — FlowLibs | FlowLibs