Skip to content

BabsBBG/project-gatekeeper

Repository files navigation

Project Gatekeeper

Post-Acquisition Identity Security Framework

Helix Communications × Pulse Networks


Microsoft Entra ID Microsoft Sentinel Azure Logic Apps Terraform KQL SC-300 AZ-500


Phases Built CA Policies KQL Detection Rules Containment Time
6 7 14 2.42 seconds

The Real Story

Project Gatekeeper simulates a fictional telecom acquisition with all the identity chaos that comes with it. Helix Communications, a UK ISP, acquires Pulse Networks. Overnight, the identity attack surface doubles:

  • 400+ Pulse identities - inconsistent naming, no offboarding process
  • No MFA on legacy accounts
  • Stale accounts and over-privileged users
  • Unmanaged contractor and partner access
  • Zero detection or automated response

I built a complete identity security framework to fix this. Six phases, 14 custom KQL detection rules mapped to MITRE ATT&CK, 10 live attack simulations with evidence, and a SOAR playbook that contains a compromised account in 2.42 seconds.

Metric Before After
MFA enforcement 0% 100% via CA001
Legacy authentication Enabled Blocked - CA002
Privileged roles Permanent Global Admin JIT with dual approval
Custom detection rules None 14 KQL rules
Incident response Manual - hours SOAR - under 3 seconds
Identity Secure Score N/A 32.04%

Gatekeeper Architecture

Architecture


┌------------------------------------------------------------------┐
│                   HELIX COMMUNICATIONS TENANT                    │
│                                                                   │
│  ┌------------------┐    ┌----------------------------------┐   │
│  │  PULSE LEGACY    │    │       CONDITIONAL ACCESS          │   │
│  │                  │---▶│  CA001  CA002  CA003  CA004      │   │
│  │  400+ identities │    │  CA005  CA006  CA007             │   │
│  │  No MFA · Stale  │    │  7 policies · all enforced       │   │
│  └------------------┘    └----------------┬-----------------┘   │
│                                           │                       │
│  ┌-------------------┐   ┌---------------▼-----------------┐   │
│  │    PIM GATE       │   │        IDENTITY LIFECYCLE         │   │
│  │                   │   │                                   │   │
│  │  JIT · 4hr max    │   │  Joiner → TAP + Groups + Email  │   │
│  │  Dual approval    │   │  Mover  → Group update + Notify │   │
│  │  Zero standing    │   │  Leaver → Disable + Revoke +    │   │
│  └-------------------┘   │           Strip + Notify         │   │
│                           └-----------------------------------┘  │
│                                                                   │
│  ┌------------------------------------------------------------┐  │
│  │                  ITDR DETECTION LAYER                       │  │
│  │  Entra ID Protection  ·  14 KQL Rules  ·  Sentinel         │  │
│  └------------------------------┬---------------------------- ┘  │
│                                 │ High severity incident          │
│  ┌------------------------------▼---------------------------- ┐  │
│  │              HLX-SOAR-HighRiskResponse                      │  │
│  │  Revoke Sessions → Disable Account → HLX-Offboarding       │  │
│  │  → Leaver Workflow → SOC Email                2.42 seconds  │  │
│  └----------------------------------------------------------- ┘  │
└-------------------------------------------------------------------┘

Phase 1 - Identity Baseline

Goal: Understand what Pulse brought in, then lock down the foundation before a single legacy identity touches the Helix environment.

Security Groups

Seven groups: IT Admins, NOC Engineers, Corporate Staff, Field Ops, Break-Glass, PIM Approvers, and Pulse Legacy Users. HLX-IT-Admins is role-assignable, required for PIM in Phase 3.

Groups list

Break-Glass Accounts

Two accounts (bg-01, bg-02) with permanent Global Administrator. Credentials stored offline and never used day-to-day. Excluded from all CA policies and all SOAR automation.

Break-glass members BG-01 roles

Bulk User Creation via PowerShell

16 users created in one script using Microsoft Graph PowerShell. Each Pulse legacy account (prefixed pls-) was created with a documented gap: no MFA, stale, over-privileged, or unlicensed.

PowerShell creation Users list

Licensing and Authentication Methods

M365 E5 licences assigned to all users. Authentication methods hardened: Microsoft Authenticator, FIDO2, and Temporary Access Pass enabled. SMS and voice calls disabled.

Auth methods

SSPR

Self-service password reset enabled for all users, two methods required.

SSPR properties SSPR methods

Pulse Legacy Gap Remediation

  • Disabled pls-jakub.kiwior - stale, no activity since acquisition close
  • Removed inherited AI Reader and Directory Readers roles from pls-reiss.nelson - assigned outside any governance framework

Kiwior disabled Nelson inherited roles


Phase 2 - Conditional Access Architecture

Goal: Control who can sign in, from where, and under what conditions, across two merged organisations with different risk profiles.

Named Locations

Five locations defining the network topology. Helix-NOC-Floor is trusted. Both Pulse locations are known but not trusted, they generate additional scrutiny.

Named locations

Seven CA Policies

Policy Scope Control
CA001 All users Require MFA - break-glass excluded
CA002 All users Block legacy auth (ActiveSync, other clients)
CA003 All users - High/Medium sign-in risk Require MFA + re-auth every time
CA004 All users - High user risk MFA + forced password change
CA005 HLX-IT-Admins MFA + 4hr session, never persistent
CA006 Guest/contractor users MFA + 1hr session
CA007 Pulse-Partner-Network location MFA + 2hr session

All policies started in report-only mode and were moved to enforcement once the environment stabilised, standard enterprise deployment practice.

CA policy list CA001 CA002 CA003 sign-in risk CA007 Pulse partner


Phase 3 - Privileged Identity Management

Goal: Zero standing privilege. Every admin role activated just-in-time, with justification and where required, approval from someone outside the IT Admin tier.

Role Settings

Role Max Duration MFA Approval
Global Administrator 4 hours Required Required - HLX-PIM-Approvers
Security Administrator 8 hours Required Not required
Privileged Role Administrator 4 hours Required Required - HLX-PIM-Approvers

Global Admin settings

Eligible Assignments

Odegaard → Global Admin. Rice → Security Admin. Saliba → Privileged Role Admin. None are active by default. Every elevation is a deliberate, auditable act.

Eligible assignments

Separation of Duties

HLX-PIM-Approvers consists of Jurrien Timber and Kai Havertz, Corporate staff, not IT Admins. They cannot approve their own requests because they have none to approve.

PIM approvers group Global Admin approvers configured

Access Review

Global Administrator eligible assignments reviewed monthly by Timber. Auto-remove on non-response.

Access review active

Live Activation Simulation

Odegaard requested Global Admin → Timber approved from outside the IT Admin tier. Full audit trail captured.

Activation request Timber approval


Phase 4 - Identity Lifecycle: JML Workflows

Goal: Replace manual helpdesk tickets with automated lifecycle workflows that respond in seconds, not days.

Joiner

Trigger: user added to HLX-New-Joiners. Tasks: Generate Temporary Access Pass, assign default group, send welcome email. The TAP lets new users register MFA without an existing credential, breaking the circular dependency that would otherwise require a helpdesk call.

Joiner workflow Joiner test

Mover

Trigger: department attribute change. Tasks: Remove previous group, add new group, notify manager.

Mover workflow Mover test

Leaver

Trigger: user added to HLX-Offboarding. Tasks: Disable account, revoke all sessions, remove all groups, strip licences, notify manager before and on final day.

Leaver workflow Leaver test Lokonga disabled

The leaver workflow also serves as an emergency containment trigger. The SOAR playbook in Phase 6 adds compromised accounts to HLX-Offboarding, immediately chaining into the full offboarding sequence.


Phase 5 - ITDR: Threat Detection

Goal: Build detection rules that catch Pulse-specific threats, then prove they work with live evidence.

14 Custom KQL Rules - MITRE ATT&CK Mapped

All 14 rules deployed as Sentinel scheduled analytics and available in /kql-queries/.

Rule Threat Severity Tactic Technique
HLX-DETECT-001 Break-Glass Account Access High Initial Access T1078
HLX-DETECT-002 Impossible Travel High Initial Access T1078
HLX-DETECT-003 Password Spray High Credential Access T1110.003
HLX-DETECT-004 Role Assigned Outside PIM High Privilege Escalation T1098.003
HLX-DETECT-005 Pulse Legacy Account Activity Medium Initial Access T1078.004
HLX-DETECT-006 MFA Fatigue / Push Bombing Medium Defense Evasion T1621
HLX-DETECT-007 Legacy Auth Post-Migration Medium Defense Evasion T1550
HLX-DETECT-008 After-Hours NOC Access Medium Initial Access T1078
HLX-DETECT-009 Mass Group Membership Change High Privilege Escalation T1098.001
HLX-DETECT-010 Offboarding Workflow Bypass Medium Defense Evasion T1098
HLX-DETECT-011 PIM Activation Outside Window High Privilege Escalation T1078.004
HLX-DETECT-012 Pulse Account Impossible Travel High Initial Access T1078
HLX-DETECT-013 Pulse Partner Network Anomaly Medium Initial Access T1078
HLX-DETECT-014 Risk-Alert Correlation High Initial Access T1078

KQL folder

10 Live Attack Simulations

A KQL rule that fires but does nothing is a ticket generator. A Sentinel incident that triggers a Logic Apps playbook that revokes, disables, and offboards - that's security.

Every simulation generated real log entries in the Helix tenant. Advanced Hunting and Entra audit log evidence was captured for 12 of 14 rules.


Simulation 1 - Credential Harvest (Rules 1, 5)

Attack Simulation Training launched against all four Pulse legacy accounts. Real phishing campaign — real sign-in activity logged.

Credential harvest results Phish page — Zinchenko


Simulation 2 - Password Spray (Rule 2)

Manual failed logins cycled across all four Pulse accounts from the same browser and IP. Multiple failed attempts, multiple targets, short time window, the signature spray pattern.

Password spray logs


Simulation 3 - Role Assigned Outside PIM (Rule 4)

Direct Security Reader assignment to a Pulse legacy user bypassing PIM entirely. Audit log captured the assignment. Role removed immediately after.

Role outside PIM audit


Simulation 4 - Mass Group Membership Change (Rule 9)

Added three users simultaneously to HLX-IT-Admins. Audit log shows bulk additions in a single 15-minute window, the pattern Rule 9 targets.

Mass group change audit Mass group change detail


Simulation 5 - Break-Glass Account Access (Rule 13)

Signed in as bg-01 from an incognito window. CA policies correctly showed Not Applied, break-glass exclusion working. Identity Protection flagged the unfamiliar IP and interrupted the flow, but the sign-in completed. This is the correct behaviour, emergency access must never auto-block.

Break-glass signin CA policies not applied Identity Protection interrupted Advanced Hunting evidence


Simulation 6 - Offboarding Workflow Bypass (Rule 10)

Disabled pls-reiss.nelson directly without adding to HLX-Offboarding first. Audit log shows AccountEnabled changed to false with no preceding offboarding group entry. Then attempted sign-in on the disabled account, 50057 error confirmed.

Offboarding bypass audit Account locked 50057


Simulation 7 - MFA Fatigue (Rule 6)

Repeatedly signed in as Bukayo Saka and denied the MFA push each time. Sign-in logs show the Interrupted → Interrupted → Interrupted → Success pattern, exactly what push bombing looks like in logs.

MFA fatigue sign-in logs MFA fatigue Advanced Hunting


Simulation 8 - Legacy Authentication (Rule 7)

PowerShell sent a Basic Auth HTTP request to the Exchange MAPI endpoint. 401 Unauthorized, CA002 blocked it at the protocol level.

Legacy auth 401


Simulation 9 - Impossible Travel (Rules 1, 12)

Signed in as pls-oleksandr.zinchenko from Nigeria, then immediately via VPN from the US and Belgium. Three countries in minutes. Sign-in logs and Advanced Hunting both capture the pattern.

Impossible travel Advanced Hunting

CA003 did not block this sign-in and that is correct. Impossible travel is a post-sign-in detection. Both sign-in events must occur before the pattern can be calculated. By the time Identity Protection scores it, the session exists. CA004 catches the elevated user risk on the next sign-in. This is how the detection chain is designed.


Simulation 10 - PIM Activation Anomaly (Rule 11)

Odegaard activated Global Administrator. Full PIM audit log captured with timestamp, the evidence Rule 11 queries for out-of-window activations.

PIM activation audit


VPN Risky Sign-in (Baseline evidence - Rules 1, 5)

The first foreign VPN test that kicked off the detection work. Identity Protection flagged the sign-in, CA003 enforced MFA, and the risky sign-ins dashboard populated for the first time.

Risky sign-ins Risk detections CA003 block


Phase 6 - Response Automation and Governance

Goal: Close the detection-to-response loop. Prove the whole system works end-to-end.

Enable All CA Policies

No more report-only. All 7 policies enforced.

All CA policies enabled

Access Reviews

Global Admin monthly review - Timber approved Odegaard. Pulse legacy quarterly review configured for external identities.

Access review approval Pulse legacy review

Deploy Sentinel

Log Analytics workspace created. Entra ID, MDI, and M365 Defender data connectors connected. All 14 KQL rules deployed as scheduled analytics with MITRE ATT&CK tactic and technique mapping.

Log Analytics workspace All 14 analytics rules active Sentinel overview

SOAR Playbook: HLX-SOAR-HighRiskResponse

Trigger: HTTP webhook - lab implementation. Production uses Sentinel incident automation rule.

Incident fires
    │
    ▼
Break-glass check - IS break-glass -▶ P1 alert only, no action
    │
    │ NOT break-glass
    ▼
Sessions revoked (Graph API)
    │
    ▼
Account disabled (Entra ID)
    │
    ▼
Added to HLX-Offboarding
    │
    ▼
Leaver workflow fires — groups, licences, notifications
    │
    ▼
SOC alert email
    │
    ▼
Full containment — 2.42 seconds

Logic App workflow

Live Test - pls-oleksandr.zinchenko

Playbook triggered via PowerShell webhook. All steps executed in 2.42 seconds.

Run history — all green Account disabled Added to HLX-Offboarding SOC alert email

Break-Glass Exclusion Test

bg-01 submitted to the playbook. Account not touched. P1 alert sent.

Break-glass alert email Break-glass still enabled

Final Secure Score

32.04% post-acquisition, with the full control stack active. The score reflects bringing 400+ Pulse accounts into the MFA registration calculation, expected to climb above 70% as legacy users complete registration and controls continue to mature.

Final Secure Score


What I Learned the Hard Way

Lifecycle Workflows need Entra ID Governance - a separate trial licence on top of E5. I activated the free trial and it unlocked immediately. Not obvious until you hit the 401 on the overview page.

Access reviews in trial tenants - the My Access portal sometimes doesn't surface PIM reviews for reviewers despite correct licence assignment and 24+ hours. The email notification with direct link works. The configuration is correct.

Sentinel entity extraction is unreliable in trial workspaces - the built-in Entities - Get Accounts action consistently returned empty results for both analytics-rule-generated and manually created incidents. Switched to an HTTP webhook trigger and passed the UPN directly. In a production Sentinel workspace with sufficient ingestion history, the native trigger works correctly. The response chain logic - revoke, disable, offboard, notify, is fully validated regardless of trigger method.


Reproduce This Project

# Prerequisites: Terraform CLI, Azure CLI, M365 E5 trial tenant
az login
az account set --subscription "your-subscription"

cd terraform
terraform init
terraform plan
terraform apply

Terraform covers: all Entra ID groups, all 21 users, all 7 CA policies, all 5 named locations, all PIM eligible assignments, Log Analytics workspace, Sentinel, and all 14 KQL analytics rules as scheduled analytics.

Resources deployed via alternative methods are documented in /terraform/README.md:

  • Lifecycle Workflows - Entra ID portal, definitions in /scripts/
  • Logic Apps SOAR - ARM template in /logic-apps/

Repository Structure

project-gatekeeper/
├-- Phase 1/                    # 15 screenshots
├-- Phase 2/                    # 11 screenshots
├-- Phase 3/                    # 11 screenshots
├-- Phase 4/                    # 7 screenshots
├-- Phase 5/                    # 25 screenshots + 10 simulations
├-- Phase 6/                    # 14 screenshots
├-- kql-queries/                # 14 KQL detection rules
├-- terraform/                  # Full IaC — Entra ID + Azure
│   └-- modules/
│       ├-- identity-baseline/
│       ├-- conditional-access/
│       ├-- pim/
│       └-- sentinel/
├-- scripts/
│   └-- New-GatekeeperUsers.ps1
├-- logic-apps/
│   └-- hlx-soar-playbook.json
└-- README.md

Cert Alignment

Domain Cert
Implement identities in Microsoft Entra ID SC-300
Implement authentication and access management SC-300
Plan and implement identity governance SC-300
Manage identity and access AZ-500
Manage security operations AZ-500

Built by Tobi Babalola - now go secure something.

GitHub

About

Complete identity security overhaul for a telecom acquisition - 6 phases, 14 KQL detection rules, 10 attack simulations, and a SOAR playbook that contains compromised accounts in under 60 seconds. Built with Entra ID P2, Sentinel, Logic Apps, and Terraform. SC-300 / AZ-500 aligned.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors