Blog Post

Educator Developer Blog
12 MIN READ

AfterLogin: We Turned Forgotten-Account Cleanup into a Haunted-House Game with Microsoft Foundry

jefflynch107's avatar
Jul 24, 2026

Every organization has old accounts nobody remembers. We built a game where they're ghosts in a manor, an AI helps you decide their fate, and the evidence it cites is real.

Guest post from Jeff Lynch the winner of Best Overall Agent Soutution from Microsoft Agents League who secured $15,000

Afterlogin: The Hunt — https://github.com/jlynch160/afterlogin-the-hunt  (Creative Apps track) 

The problem: every organization has ghosts

Picture a former employee whose badge still opens the building two years after they left. That happens constantly in the digital world. At MajorKey Technologies, where our work centers on identity security and how AI is changing it, forgotten accounts come up in nearly every client conversation we have: service accounts nobody remembers creating, admin logins for people long gone, emergency credentials that look abandoned but must never be touched. Security folks call these orphaned accounts, and they're one of the most common ways attackers get their first foothold. They're powerful, unwatched, and often not protected by multi-factor authentication, because nobody is around to care.

Here's the catch, though. Finding these accounts is easy. Any system report will happily list every account that hasn't signed in for 400 days. The hard part is the judgment call that comes next: is this account truly dead, or is something still quietly depending on it? Delete a "dead" account that an automated billing job still uses every night and you've broken production. Leave a dormant administrator account sitting there and you've left bait out for an attacker. Making that call correctly takes evidence: old documentation, system inventories, security policies, sign-in records. Digging through all of that is tedious, and tedious work gets skipped. We've watched it get skipped.

So we tried something different. Instead of another dashboard, we built a game. AfterLogin is a haunted manor where every ghost is a forgotten account, every judgment you pass mirrors a real decision an identity team makes, and the evidence you "summon" is looked up by AI from real indexed documents, with citations. Our hope was simple: the triage instinct this work requires is easier to teach when getting it wrong spawns a poltergeist.

"Every identity someone stopped watching is a door left unlocked. "from the game's mission briefing

Why this matters now

Three trends make this problem worse every year, not better.

  • Machine identities are exploding. In most organizations, service accounts, automation identities, and app registrations already far outnumber the people, and the arrival of AI agents is accelerating that. Every agent that gets an identity today is a candidate ghost two years from now, when the project ends and nobody remembers to clean up. The manor is only getting bigger.
  • Attackers prefer the front door. Breaking in through an unpatched flaw is hard work. Signing in with a valid, forgotten, over-privileged account is not, which is why the abuse of legitimate credentials shows up in incident report after incident report. There's no malware to detect. It's just a login that nobody questioned, because nobody owned it.
  • The judgment doesn't scale. Tools can list stale accounts by the thousand, but the "truly dead or load-bearing?" call still needs a person who knows what evidence to ask for, and that judgment lives in the heads of senior people who are always in short supply. If we can't scale the people, we have to scale the teaching. That's what a game with real consequences does, and it's also the deeper reason the grounded-AI pattern matters: an AI that shows its citations lets a junior analyst make a senior analyst's call, safely.

What AfterLogin is

One night, two worlds: the title screen offers The Hunt (the haunted security audit) and Helper Patrol (the same mechanics, reskinned for a family-friendly audience).

You play a warden walking a haunted manor at night. Each room holds a spirit, graded A through F by a risk engine (A is a healthy resident, F is a screaming liability). For each one, you investigate its connections, summon documented evidence, and then pass one of three judgments, each of which maps to a real-world action:

  • Lay to Rest: the account is truly dead, remove it safely.
  • Bind & Watch: it's risky but something still depends on it, so disable and monitor it.
  • Acknowledge: it's a healthy, legitimate account, document its owner and move on.

While you deliberate, a Possession creature hunts through the halls toward the Vault, feeding on any high-risk account you've left unjudged. There are turn-based rounds and dice combat, and a clock genuinely ticking against you. It's the nightly reality of an identity team, dressed up as a tabletop adventure. And it doesn't stop at identity: the campaign runs three acts, each built on a different part of the Microsoft security stack, from stale accounts (Microsoft Entra) to haunted data (Microsoft Purview) to active takeovers (Microsoft Defender XDR).

Under the hood, the same game exists in three forms that share one brain:

  1. The game you see: a single web page, playable in any browser, no installation.
  2. A version AI can play: using MCP (Model Context Protocol, an open standard that lets AI assistants operate tools), GitHub Copilot can walk the manor by itself, summoning evidence and passing judgments with no human at the keyboard.
  3. A plain service layer: the risk-scoring engine and AI endpoints, which the other two surfaces both rely on.

Why that matters: because the human game and the AI-playable version share the same rules and the same scoring engine, you can directly compare how a person judges a room against how an AI agent judges it. The game doubles as a small test lab for AI decision-making.

How the pieces fit together

 

Where each Microsoft technology fits

TechnologyRole in AfterLogin
Microsoft Foundry (Foundry IQ)The knowledge layer. When you summon evidence, the AI doesn't make something up; it retrieves cited passages from an indexed library of documents. That "look it up and show your source" pattern is called grounded retrieval, and it's a real integration here, not a mockup.
Azure AI SearchThe search infrastructure underneath Foundry IQ. It ranks results by meaning, not just keywords, and can pull out the exact sentence that answers the question.
Azure OpenAI / GitHub ModelsPowers the Warden, the in-game advisor that reads the evidence and recommends the least-destructive action. Its credentials stay on the server, never in your browser.
GitHub Copilot + MCPCopilot helped build the app, and thanks to the MCP server it can also play it, using the exact same rules a human does.
Azure Static Web Apps + FunctionsThe hosting. The game runs as a simple website with a small cloud function behind it for the evidence lookups.
Microsoft Entra (modelled)The account data mimics a real Microsoft Entra directory but is entirely synthetic. There's an optional read-only mode that can grade a real directory, with a privacy flag that masks names for public demos.

How we built it

The risk engine is the game

Everything hangs off one honest scoring function. It weighs how powerful an account is (an unused administrator account is a much bigger liability than an unused mailbox), how long it has sat dormant, whether it has multi-factor authentication, and, crucially, whether it's load-bearing: whether some living process still depends on it, like an automated job that runs every night.

For the technical readers

 

The gameplay consequences map straight onto operational reality. Lay to rest an account that something still depends on and you spawn a Poltergeist, because you just broke a live process (minus 60 points). Shrug at a grade-F corpse and you've left breach bait sitting in a room (minus 20). And the

function grade(idn) {
  const dormant = daysSince(idn.lastInteractiveSignIn);
  const priv = isPrivileged(idn);
  const lb = loadBearing(idn);          // live runbook refs, recent token refresh, active OAuth
  let score = 0;
  if (priv) score += 45;                // privilege = blast radius
  if (dormant > 365) score += 35; else if (dormant > 180) score += 20; else if (dormant > 90) score += 10;
  if (!idn.mfaRegistered && idn.accountType !== 'servicePrincipal') score += 15;
  if (idn.riskLevel === 'high') score += 15; else if (idn.riskLevel === 'medium') score += 8;
  if (idn.accountEnabled && !lb && dormant > 180) score += 10; // enabled, dead, dormant = pure liability
  const g = score >= 75 ? 'F' : score >= 55 ? 'D' : score >= 35 ? 'C' : score >= 18 ? 'B' : 'A';
  return { grade: g, score, privileged: priv, loadBearing: lb };

Possession monster deliberately moves toward unjudged high-risk accounts on its way to the Vault, which is more or less how real attackers move through a network.

Evidence with receipts: Foundry IQ

Inside the manor: the room roster on the left grades each account A to F, the spirit gives its testimony, and the Case panel on the right walks you through Divine (dependency mapping) and Summon (Foundry IQ cited evidence) before you judge.

The heart of the project is the evidence step. When you summon evidence against a suspicious account, the question goes to a Foundry IQ knowledge base (built on Azure AI Search) loaded with the kinds of documents a real identity team would consult: operational runbooks, system inventories, and security policies. What comes back isn't an AI's opinion. It's cited passages, with sources, like "Runbook AP-Close.ps1, line 88, still calls this account." That one line is the difference between a safe cleanup and a broken month-end close, and it's exactly what we wanted players to feel.

For the technical readers

export async function groundQuery(question, top = 3) {
  if (!isConfigured()) return null;   // caller falls back to baked synthetic evidence
  const url = `${EP}/indexes/${INDEX}/docs/search?api-version=2024-07-01`;
  const body = { search: question, top, select: 'id,title,content,source' };
  if (SEM) { body.queryType = 'semantic'; body.semanticConfiguration = SEM;
             body.captions = 'extractive'; body.answers = 'extractive|count-3'; }
  const res = await fetch(url, { method: 'POST',
    headers: { 'content-type': 'application/json', 'api-key': KEY },
    body: JSON.stringify(body) });
  const data = await res.json();
  return { grounded: true, question,
    answers: (data['@search.answers'] || []).map(a => a.text),
    citations: (data.value || []).map(d => ({ title: d.title, source: d.source,
      score: d['@search.rerankerScore'] ?? d['@search.score'],
      snippet: d['@search.captions']?.[0]?.text || String(d.content).slice(0, 200) })) };
}

The Warden: an AI advisor on a short leash

The in-game advisor, the Warden, is deliberately boxed in. It receives the account's signals plus the retrieved evidence, and it must answer in a fixed format: a recommended judgment, a rationale under 180 characters, and a confidence score. The instructions we gave it are what we'd tell a junior analyst: pick the least-destructive action that's still correct. The Warden advises; the deterministic rules of the game decide what actually happens. That split, AI proposes and the engine disposes, is one we'd recommend for any AI system that touches real operations.

Letting Copilot play

Because the manor is exposed through MCP, registering it with GitHub Copilot in VS Code takes four lines of configuration:

{ "servers": { "afterlogin": { "command": "node", "args": ["mcp-server.mjs"] } } }

From there you can ask Copilot to "clear the manor" and watch it investigate rooms, summon evidence, and pass judgments in a loop, playing by the same rules a human does. The first time it correctly spared the break-glass emergency account, the one that looks abandoned but is dormant by design, was a genuinely good moment in the office.

What gave us trouble

  • Live cloud services fail at the worst possible moment. Anyone who has demoed on conference Wi-Fi knows this. So every cloud integration in AfterLogin checks whether it's configured and quietly falls back to built-in synthetic evidence when it isn't. The game runs fully offline, and lights up real retrieval the moment it's pointed at a Foundry knowledge base. Same code path either way, no demo-mode switch to forget.
  • The versions drifted apart. Early on, the human game and the AI-playable version had separate logic, and they disagreed in embarrassing ways. The fix was making the scoring engine the single source of truth that everything consumes. Now Copilot playing by itself gets identical outcomes to a human clicking rooms, which is the whole point.
  • A simple website can't hold secrets. A game that ships as one web page has nowhere safe to keep an API key. Everything that needs one got moved behind two small server endpoints, so credentials never touch the browser.
  • Teaching without preaching. Nobody wants a lecture disguised as a game. We let the mechanics do the teaching: players internalize "dormant plus powerful plus nothing depends on it means lay it to rest" because the score, the Poltergeist, and the Possession punish every other choice.

What it actually does

We'll be upfront: this is a demo and a teaching tool, not a product, and we don't have benchmark charts for a haunted house. What we can point to:

  • Evidence changes decisions, provably. The manor's two deceptive cases (a terrible-looking service account that something still depends on, and an emergency account that's dormant on purpose) cannot be judged correctly from the statistics alone. Both hinge on retrieved citations. Skip the evidence step and you lose the game. That's the argument for grounded AI, made playable.
  • Three surfaces, one brain. One scoring model powers the visual game, the AI-playable version, and the service layer. The game itself ships as a single web page.
  • Works offline, upgrades gracefully. With no configuration it runs anywhere, no keys and no network needed. Configured, the evidence step returns real, semantically ranked, cited passages from Azure AI Search.
  • It opens conversations. The game is live on Azure Static Web Apps and has become a genuinely useful icebreaker in our identity-governance work. People who would never read an orphaned-account runbook will happily spend ten minutes banishing a Possession, and they walk away able to explain "truly dead" versus "still depended on." That's more than most slide decks achieve.
  • Safe by construction. The bundled data is fully synthetic, with no real names or secrets anywhere. The optional live-directory mode is read-only, with a privacy flag that masks identifying details for public demos.

What we learned

  1. Fallbacks earn their keep. Designing every integration to degrade gracefully made the app more demoable and, as a side effect, forced cleaner boundaries in the code. It's now our default pattern for anything AI-backed.
  2. Grounding lands hardest when the ungrounded answer is wrong. The best moments in AfterLogin are the accounts where the statistics lie. If an AI retrieval demo only confirms what the raw data already says, nobody feels the value. Build the deceptive case first.
  3. MCP is a cheap second product. Wrapping the existing game logic in ten MCP tools took a fraction of the total effort, and it turned a visual demo into something an AI agent can be tested against. If your app already has an API, it's about one file away from being usable by an AI assistant.
  4. Constrain the model, trust the engine. Keeping the AI advisory, with a fixed answer format, a short rationale, and a confidence score, avoids both invented actions and outcomes nobody can explain afterwards. The deterministic engine always has the final say.

A field note from our MajorKey practice: this pattern isn't just for games. The identity programs we see work best run access reviews the way the manor does: a deterministic policy engine decides what's allowed, retrieved evidence about ownership, usage, and dependencies sits next to every decision, and AI recommends rather than rules. If your certification campaigns have turned into rubber stamps, the poltergeist has a lesson for them.

Where it goes next

  • A real Fabric IQ ontology. The web of relationships between accounts, mailboxes, groups, and live jobs is currently modelled in code. Moving it to Microsoft Fabric's semantic layer would make those "spirit threads" a governed, queryable asset.
  • Agent-vs-agent mode. Two AI agents racing to clear the manor, one tuned for speed and one for safety. We can't think of a more fun way to demonstrate how you evaluate AI agents.
  • A deeper live-directory mode. Extending the read-only Microsoft Entra integration with sign-in analysis and ownership lookups, behind the same privacy layer.
  • Scenario packs. The manor layout and its ghosts are just data, so industry-specific versions (healthcare, public sector, finance) are new data files plus new documents to index. Given the range of clients we see at MajorKey, this one is probably next.

Wrapping up

Orphaned accounts are a judgment problem wearing an inventory problem's clothes, and good judgment needs grounded evidence. The pattern under AfterLogin reuses well beyond games: a deterministic rules engine at the core, Foundry IQ retrieval for evidence with citations, a constrained AI for recommendations, and an MCP wrapper so AI agents can work the same process people do. It also sits squarely at the intersection our team at MajorKey Technologies works in every day, where the job is identity security and the interesting question is how AI genuinely evolves it: past chatbots, toward governed, evidence-backed decisions. This started as a side experiment, but that intersection is why it got built.

Try clearing the manor before dawn. Then look at your own organization and ask which rooms are haunted.

Explore, contribute, build on it

  • Watch the demo: the 90-second walkthrough on YouTube
  • Get the code: github.com/jlynch160/afterlogin-the-hunt, including the synthetic document library and the indexer script to stand up your own Foundry IQ knowledge base
  • Run it in 60 seconds: clone the repo and open index.html. No installation, no API keys, no network needed; the cloud integrations light up later if you want them
  • Make it yours: point the three FOUNDRY_SEARCH_* settings at your own Azure AI Search index and the grimoire starts citing your runbooks
Updated Jul 24, 2026
Version 1.0

1 Comment

  • Congrats on the win, Jeff! Great concept. The "AI proposes, engine disposes" pattern is the real takeaway here. A deterministic engine owns the outcomes, grounded citations back up every decision, and AI stays advisory. That's exactly what governed automation should look like in production. The public sector scenario pack would be an easy sell in the municipal space I work in; bookmark the repo.