Context
Microsoft 365 tenants arrive in a predictable state. Legacy authentication still enabled somewhere, administrative rights attached to accounts that also read mail, and no device posture requirement, so any endpoint holding a valid token is trusted as much as a managed laptop.
That combination holds up against password attacks and not against token replay. Authentication is satisfied once at sign-in and not re-evaluated, so a stolen session behaves like a signed-in user until it expires. The sign-in looks legitimate at the authentication layer while the surrounding context, network and device and timing, does not.
What I owned
Detection, containment, and the control changes afterwards. I am the escalation point for identity incidents, which means I am the one deciding when a sign-in stops being suspicious and starts being an intrusion, and the one who has to justify the policy change that follows.
Detection
Native alerting tells you a risky sign-in happened. It does not tell you whether the person recognizes it, and waiting for someone to open a portal is not detection.
I pull the signals into automation instead. Risk and impossible-travel events come out of Microsoft Graph, get enriched with address reputation and network ownership, and land in a chat channel with enough context for a responder to judge them.
- Datacenter and anonymizing sources separated from ordinary residential networks, because where the sign-in came from is usually the strongest early signal.
- Enrichment runs before a human sees the alert, so the first question a responder would ask is already answered.
- One incident produces one notification. Deduplication across sources matters more than alert volume.
Containment
Containment is a sequencing problem before it is a technical one. Sessions, credentials, and any persistence the attacker established have to be handled in an order that does not leave a way back in.
- Active sessions and issued tokens invalidated for the affected account.
- Credentials and reachable application secrets rotated.
- Persistence checked for rather than assumed absent.
- Sign-in trail reconstructed to establish what the session could actually reach.
Controls that followed
Incident response that does not change a control is just cleanup. Each event fed a policy change, and each policy change went out in report-only mode first so I could see who it would have blocked before it blocked anyone.
- Conditional Access covering device state, sign-in risk, and administrative role elevation.
- Legacy authentication protocols disabled, with emergency-access accounts handled correctly.
- Intune compliance gating access, so an unmanaged endpoint holding a valid token still cannot reach tenant data.
- Identity Protection risk policies tuned to the events that actually indicated compromise rather than the full alert catalog.
What I would do differently
I built detection before I built the containment runbook. That order is backwards. The first real incident was slower than it needed to be because I was deciding the sequence while the session was still live, and sequencing under time pressure is exactly what a runbook is for.