← Return to Portfolio
RCBC Baron Shield

BaronGuard

Identity Verification & Account Recovery Platform

▶  See It In Action

Interactive walkthrough — no login required

Built for: Rowan College at Burlington County — Office of Information Technology
Designed & Developed by: Dan Whittaker — OIT Systems Administrator
Stack: ASP.NET Core 8 · C# 12 · Microsoft Graph · SignalR · Entra ID

Overview

BaronGuard is an internal web application I built from the ground up to give RCBC's Student Support, Test Center, and OIT staff a single, guided, auditable workflow for verifying a person's identity and resetting their college credentials. It talks directly to Microsoft Entra ID and the college's student information system, replacing a patchwork process that had quietly become one of the biggest time-sinks in the department.

Background

For years, RCBC had a similar but much simpler tool, provided and maintained by an outside MSP, that gave the Student Help Desk the ability to reset student passwords and clear MFA on their own. It worked — until January 2026, when the college migrated its identity platform from OneLogin to Microsoft Entra. The migration broke the tool. The MSP committed to a fix, hit a snag, and the work stalled out. OIT had already absorbed the helpdesk workload through a shared Google Chat space, which reduced the urgency to resolve it — and the old tool effectively became dead in the water, leaving the college without a proper solution.

BaronGuard is the answer to that. Rather than wait for another vendor engagement, I built it internally so the college owns the source, the data, and the roadmap. The goal from day one was to never again be in a position where a vendor's silence translated into our staff losing the ability to do their jobs.

The Problem

The real damage of losing the old tool wasn't technical — it was operational. With no self-service interface, the Student Help Desk could no longer help students who couldn't log in. Every password reset, every MFA clear, every locked-out account had to be relayed from Student Support to OIT through a shared Google Chat space.

That chat became the bottleneck for everything. It needed an OIT technician monitoring it constantly — if no one was watching, students sat unresolved while staff caught up. The noise was relentless: routine resets mixed with urgent escalations mixed with unrelated tickets, all in one timeline.

By the time we measured it, roughly 43% of the average technician's week was being spent monitoring, triaging, and executing requests out of that single chat — pulling skilled OIT staff away from every other responsibility they had.

Just opening Student Support's access to Entra wasn't an option either. Entra's permission model is coarse; the smallest role that would let them reset a password would also let them edit groups, view directory data they didn't need, and touch accounts well beyond students. The risk of over-privileging a frontline team that turns over frequently was unacceptable.

Scoping access with Administrative Units could limit which accounts staff could see, but Entra's interface wasn't designed for non-technical users — and putting frontline staff directly in the portal introduced a different risk: account actions could be taken without any structured identity verification. There was also no automation for temporary passwords; staff would have had to set them manually and communicate them out-of-band, which was error-prone and inconsistent.

The Solution

BaronGuard wraps the entire identity-recovery flow in a four-step, role-gated web workflow: Lookup → Request → Verify → Result. Student Support staff can now resolve the routine cases themselves — safely, with full audit trails, with guiderails that prevent the actions they shouldn't take — and without ever needing direct access to Entra.

OIT gets its time back. Students get faster resolution. The audit log captures every action, by every staff member, for every student. The Google Chat firehose is no longer the critical path for password resets, and OIT technicians can focus on the work that actually requires their skill set.

4
Step Workflow
4
User Roles
100%
Audited Actions
0
Direct Entra Access Needed

Role-Based Workflows

BaronGuard's most important design decision is who can do what. Three operational roles cover the people who actually use the tool, and one developer role covers me. Each role gets exactly the privileges its work requires — nothing more, nothing less — and every page in the application enforces this at the framework level, not as an afterthought.

Capability
Student Support
Test Center
OIT
Look up student records
✓ Yes
✓ Yes
✓ Yes
Look up staff/faculty records
✗ No
✗ No
✓ Yes
Reset student password
✓ Yes
✗ No
✓ Yes
Clear student MFA
✓ Yes
✗ No
✓ Yes
Reset staff/faculty accounts
✗ No
✗ No
✓ Yes
Generate Temporary Access Pass
✗ No
⚠ One-time, 60 min
✓ Yes
Skip checklist (pre-verified path)
✗ No
✗ No
✓ Yes
View audit log
✗ No
✗ No
✓ Yes
Reset privileged accounts (Admins)
✗ No
✗ No
✗ No
🎫
Student Support / Help Desk
The frontline — first contact for students who can't log in

This is the role that motivated the project. Student Support staff handle student walk-ins, phone calls, and the Help Desk chat. They need to resolve routine login issues quickly without escalating every one to OIT, but they shouldn't be able to touch staff accounts, generate persistent credentials, or see other staff members' activity.

✓ Can Do
  • Look up student records by ID or name
  • Reset a student's password to the default formula
  • Clear a student's registered MFA methods
  • Use phone, in-person, or video as verification methods
  • See the student's account status (registered MFA, last password change)
✗ Cannot Do
  • Look up any staff or faculty account
  • Generate a Temporary Access Pass
  • Skip the verification checklist
  • View the audit log or export historical data
  • Reach the developer panel or system broadcast tools

Why these limits? A TAP is essentially a temporary credential. If misused or socially engineered, it grants direct sign-in access for up to 24 hours. That's an OIT decision, not a frontline one. Likewise, staff/faculty accounts often have elevated permissions in other college systems — a compromised faculty reset is a much larger blast radius than a student reset. Keeping those flows behind the OIT gate eliminates an entire class of social-engineering attack against the Student Help Desk.

📝
Test Center
A narrow, special-purpose workflow for proctored exam access

The Test Center has a very specific problem: personal devices are not allowed in the testing area, so students can’t use their usual MFA app to sign in to their exam session. The exam start time is fixed — they can’t wait for an OIT ticket. What they need is a Temporary Access Pass: a one-time, short-duration credential that lets them authenticate without MFA for that one session.

✓ Can Do
  • Look up the student physically present at the test center
  • Generate a one-time, 60-minute Temporary Access Pass
  • Verify identity using the student's physical RCBC ID card (single-point strong verification)
✗ Cannot Do
  • Reset passwords or clear MFA — only TAP generation is exposed
  • Generate multi-use or extended-duration TAPs (forced to one-time / 60 min)
  • Look up staff/faculty accounts
  • View the audit log

Why force one-time, 60 minutes? Because the student only needs to sign in to start their exam. Once they’re in, their regular credentials — password and MFA — work normally for everything outside the Test Center. A reusable or extended-duration TAP isn’t necessary and would grant more access than the situation requires.

🛠
OIT (Office of Information Technology)
Full operational access — the team that owns the identity platform

OIT is the team that already has Entra admin access through Microsoft. BaronGuard doesn't grant them anything they couldn't already do via the admin console — it just gives them a faster, audited workflow for doing it. The benefit isn't capability; it's speed, consistency, and a unified audit trail that doesn't depend on Microsoft's tenant log retention. Crucially, the Office of Information Technology does not have the ability to reset any privileged user accounts, such as system administrators. This restriction is strictly enforced to prevent an OIT staff member from resetting account credentials for someone with privileges they should not have access to.

✓ Full Access
  • Everything Student Support can do, for students and staff/faculty
  • Generate Temporary Access Passes with configurable lifetime and usability
  • Skip the verification checklist when Student Support has pre-verified
  • View, filter, and paginate the full audit log
  • Delete individual audit entries or clear the entire log when needed
  • Access the staff record workflow including position title and department checks
✗ Still Cannot
  • Reset privileged user accounts (e.g., admins) to prevent unauthorized privilege escalation
  • Bypass the audit log — every action they take is recorded
  • Reach the developer panel (separate role, opt-in)
  • Send system-wide broadcast messages

Why give OIT the audit log viewer? So they don't need to log into a separate compliance tool to answer the question "who reset student X this month?"

🔧
Developer
Application observability and live diagnostics — mine, currently

The Developer role is intentionally separate from the operational roles. The developer panel isn’t locked behind having operational permissions — a Developer-only account gets full observability and testing tools with no reset capabilities. Conversely, OIT staff don’t see the panel in their sessions unless they also hold the Developer role. The separation is enforced at the policy level, not via “Developer is a superset of OIT.”

✓ Can Do
  • Open the developer panel — live logs, sessions, latency, activity feed, bug reports
  • Push a system broadcast banner to all signed-in users via SignalR
  • Enable Mock-Graph mode (canned responses, no real Entra calls)
  • Inject a forced error to test failure-path UI
  • Impersonate any operational role to test what they see — no second test account needed, no role swapping in Entra
✗ Cannot Do
  • Perform any reset action unless they also hold an operational role
  • Bypass the audit log — impersonated actions are recorded as such

Technology Stack

BaronGuard is built on the modern Microsoft web stack and integrates deeply with the same identity platform it manages. Every layer was chosen for production stability, observability, and a small operational footprint — this is a tool that needs to run quietly on a single internal IIS box and survive nightly reboots without anyone thinking about it.

ASP.NET Core 8
Razor Pages for the UI, with a clean page-per-workflow-step structure. Hosted in-process under IIS in production.
C# 12
Records, pattern matching, and nullable reference types throughout. Compiled with warnings-as-errors for safety.
Microsoft Entra ID
OpenID Connect sign-in via Microsoft.Identity.Web. Role membership comes from Entra security groups mapped to app roles.
Microsoft Graph
Used for password resets, MFA method enumeration/clearing, TAP generation, and account status reads. Delegated permissions only.
SignalR
Two hubs: BroadcastHub (system messages to all users) and DevHub (live log/session/activity stream for the developer panel).
Informer REST API
Custom HTTP client for the college's reporting platform. Used to fetch student/staff records by ID with timeout and TLS handling.
SharePoint Online
Secondary audit sink. Every audit entry mirrors to a SharePoint list for compliance reporting outside the application.
Custom CSS
No framework. Hand-crafted styles tied to the RCBC brand. Sub-2KB critical CSS, scales cleanly on tablets used at walk-in desks.

The Four-Step Workflow

Every successful reset moves through four guided pages. The workflow is deliberately rigid — you can't reset an account without first verifying identity, and you can't verify identity without first specifying what's being requested and why.

Step 1 — Lookup

Staff begin by entering a student or staff ID number. The system pulls the live record from the college's Informer reporting platform and presents it for confirmation. Student Support only sees the Student lookup form — the Staff toggle is gated to OIT.

Student Lookup
Student ID (7-digit)
3131313
Search
OR
First Name
First name
Last Name
Last name

Student Lookup — search by ID or name (Student Support view)

Step 2 — Request

After confirming the record, staff fill out a structured request: what needs to be reset (password, MFA, Temporary Access Pass), how the person is contacting them (in-person, phone, video), and why. The system also shows a live Account Status panel pulled from Microsoft Graph — which MFA methods are registered and the date of the last password change — so staff have context before they start verifying.

This page also checks the audit log on load. If the same account has been reset within the past 4 hours, a prominent red warning surfaces showing who did it and when. This catches two distinct failure modes: social engineering attempts where someone tries the same story with multiple staff members, and the more common case of two staff members accidentally stepping on each other's toes by resetting the same account back-to-back without realizing the first one already happened.

🚨
Recent reset on record — this account was reset recently.
Dan Whittaker reset Password + MFA — 47 minutes ago (2:14 PM)
Please make sure account actions are still needed. If unsure, please verify with a supervisor before proceeding with another reset.
BO
Baron Oxley
ID: 3131313
🎓 Student Account
🔒 MFA✓ Authenticator, Phone
🗓 PasswordMay 17, 2026 (47m ago)
Complete the request details, then proceed to identity verification.
→ Wrong Student
What does the student need?
Select all that apply.
🔑  Password Reset
📱  MFA (Multi-Factor Authentication)
How are you verifying the student’s information?
🙂  In-Person
📹  Video Call
📞  Phone Call
Why does the student need assistance?
Forgot Password
New or Lost Phone
MFA / Authenticator Not Working
Locked Out / Account Disabled
Continue to Verification →

Request page with account status, recent-reset warning, and the structured request form for Baron Oxley

Step 3 — Verify

The verification page presents a checklist of identity points to confirm: ID number, address, phone, personal email, last term enrolled, and so on. A physical RCBC ID card counts as a single-item strong verification; otherwise, staff must collect a minimum of three verbally confirmed fields. The page enforces this threshold — you cannot submit until you have checked enough items.

Once submitted, the requested account actions execute against Microsoft Graph. For password resets, BaronGuard uses the SSPR (Self-Service Password Reset) pipeline endpoint specifically so that hybrid AD-synced accounts trigger writeback to on-premises Active Directory via Entra Connect. This is a critical distinction in hybrid environments: the more obvious Graph API password reset endpoint updates the cloud account but leaves the on-premises password stale. The practical result is that a student can sign in once with the new password, but then the “Current Password” prompt during Windows sign-in reports it as incorrect — because the on-prem side never got the update. SSPR writeback avoids this entirely. Identifying this distinction — and knowing which endpoint to use — is what made BaronGuard work where the MSP’s tool couldn’t. The symptom they couldn’t resolve (sign in once, then immediately blocked on password change) is a well-known artifact of using the standard reset endpoint against a hybrid-synced account. Routing through the SSPR pipeline instead resolved it completely.

BO
Baron Oxley
ID: 3131313
ResettingPassword
ContactIn-Person
ReasonForgot Password
Age
35
Last Term on File
2026SP
Address
900 College Cir, Mt Laurel NJ 08054
Phone
856-222-9311
Personal Email
boxley@example.com
Active Programs
AAS.IAC
Identity Verification
The student is present in person. Confirm their RCBC ID card to verify identity.
Student presented their RCBC ID card
— or verify at least 3 of the following —
ID Number (verbal) — 3131313
Age
Address / Zip Code
Phone Number
College Email
Personal Email
Last Term on File
Active Program
3 of 3 selected
Complete Verification
Cancel — Return to Search

Verify page — Baron Oxley’s record on the left, checklist on the right with 3 of 3 confirmed

Step 4 — Confirm and Execute Account Actions

After verification passes, the page does not execute anything immediately. Instead it presents a confirmation screen summarizing exactly what is about to happen: the student’s account, the actions selected, and the verification method used. Staff must explicitly confirm before any Graph calls are made. This prevents accidental execution and gives staff one last opportunity to catch a mistake before it is in the audit log.

⚠  Confirm Account Actions
Student Baron Oxley — ID 3131313
Actions Password Reset, MFA Clear
Verified via In-Person — 3 fields confirmed
Reason Forgot Password
These actions cannot be undone. Confirm only if you have completed identity verification.
← Go Back
✓  Confirm & Execute

Confirmation screen — summary of pending actions before any Graph calls are made

Once confirmed, the actions execute and the result page renders immediately. The result varies by what was performed. For password and MFA resets, it shows a checkmark for each completed action. Student Support staff are shown the temporary password formula — a template they can walk the student through using the student’s own information — rather than the raw value, keeping FERPA-sensitive data off the screen. OIT sees the generated value directly. For TAP generation (Test Center and OIT), the one-time code is displayed with a copy button and expiry time; it is shown once and is never retrievable after that. If an active TAP already exists, the confirmation step requires an additional acknowledgment before deleting the existing one and issuing a new one.

✅  Actions Complete
Baron Oxley (3131313) — verified In-Person by Dan Whittaker
Password Reset
Temporary password formula provided to student.
MFA Methods Cleared
All registered methods removed. Student can re-enroll at next sign-in.
Logged at 05/17/2026 3:01 PM ET
←  Next Student
🔒  Test Center — TAP
Student must be physically present with their RCBC ID card.
TAP Generated
Baron Oxley (3131313) — confirmed via Physical RCBC ID Card.
🔒 Temporary Access Pass
QAf+MLKB
📋  Copy TAP
One-time — expires 4:45 PM ET. Valid for one sign-in only.
Logged by P. Proctor at 05/17/2026 3:45 PM ET
←  Next Student

Result screens — Password + MFA reset (Student Support / OIT view, left) and TAP generation (Test Center view, right)

Core Features

Beyond the core workflow, BaronGuard ships with operational and safety features that were added in direct response to feedback during the pilot rollout. Each one solves a real problem observed in actual use, not a hypothetical one.

🔍

Live Account Status

Pulls real-time MFA methods and last-password-change date from Microsoft Graph so staff see the current state of the account before requesting a reset. Helps spot accounts that don't need to be reset at all.

🚨

Recent-Reset Warning

The Request page checks the audit log on load and surfaces a red alert if the same account has been reset within 4 hours, naming who did it and when. Stops both social engineering and accidental double-resets.

Repeat-Lookup Flag

In-memory tracker warns when two different staff members look up the same person within 10 minutes. Catches "I'll just ask the next agent" patterns in real time, before either reset happens.

🔐

Temporary Access Pass

OIT and Test Center can generate a Microsoft Entra TAP for proctored exam access or first-time setup. Includes safeguards for existing TAPs and (for OIT) configurable usability and lifetime.

📱

Full MFA Clear

One click removes every authentication method on the account — Authenticator, phone, software OATH, email, FIDO2 keys — in a single audited operation. Recovers students from lost-device situations cleanly.

🔑

Hybrid Password Reset

Uses the Entra SSPR pipeline endpoint specifically so password changes write back to on-premises AD via Entra Connect. Critical for hybrid environments where the simpler API call leaves the on-prem password stale.

📢

System Broadcast Banner

Developer-only feature that pushes a real-time banner to all signed-in users via SignalR. Used to announce planned maintenance, urgent alerts, or temporary tool issues without an email blast.

🐛

Bug Report Workflow

Floating button (with the RCBC Baron mascot) lets any staff member submit a bug or feedback note. Reports flow into the developer panel with page context, severity, and submitter role auto-attached.

📋

Help Desk Pre-Verified Path

When Student Support has already verified a student via the Google Chat space, OIT can skip the verification checklist with a single radio. The audit entry records this, helping OIT track and manage Chat-originated requests while Student Support is being phased into handling resets on their own.

Security & Audit

Every design decision in BaronGuard answers the question: "if this got abused, what would the audit log show?" Authentication, authorization, action execution, and event recording are all separated and layered so that no single compromise — including a stolen staff session — can produce an unrecorded action.

Authentication

Sign-in is delegated entirely to Microsoft Entra ID via OpenID Connect. There are no local accounts, no service accounts shared between staff, and no API keys floating in config files. Every Graph call to perform a reset uses the signed-in staff member's token — meaning Microsoft's audit log also records who did what, providing a second independent record outside BaronGuard's control.

The sign-in flow explicitly forces the credential prompt every time, defeating browser session reuse so that a sign out or idle timeout actually means a re-authentication.

Authorization

Four roles, mapped from Entra security groups, gate every page:

OIT Student Support Test Center Developer

Policies enforce these at the page level. A Student Support agent literally cannot reach the TAP generation flow, the audit log viewer, or staff/faculty records. The Developer role exists separately from operational roles — the panel isn’t gated behind having reset permissions, and OIT staff don’t see it in their sessions unless they also hold the Developer role.

Audit Trail

Every completed reset writes a structured audit entry to a thread-safe JSON Lines file, and simultaneously mirrors to a SharePoint Online list as a secondary record. The audit entry captures: timestamp (Eastern Time), staff UPN and display name, account type, user ID, user name, verified fields, reset types performed, contact method, and reason. The OIT-only audit viewer in the app supports filtering by date range, staff member, and free-text search.

📜 Audit Log
Showing 42 of 1,287 entries
Time Staff Type User Resets Reason
05/17 3:01 PM Ron Cahall Student Baron Oxley Password + MFA New / Lost Phone
05/17 2:47 PM Dan Whittaker Staff Pat Faculty TAP (60min) First-Time Setup
05/17 2:14 PM Dan Whittaker Student Baron Oxley Password Forgot Password
05/17 1:55 PM Ron Cahall Student Sam Demo MFA MFA Not Working
Page 1 of 26

Audit log viewer — OIT-only, with date range filter, staff filter, and free-text search

Rate Limiting

Per-user sliding-window rate limiting (30 lookups per minute, partitioned by UPN) prevents either accidental form-resubmit storms or deliberate enumeration attempts. The limit is high enough to never affect normal work but tight enough to halt a runaway script.

Idle Timeout with Background-Tab Awareness

Idle staff sessions auto-logout after a configurable period (10 minutes by default, with a warning at 2 minutes remaining). The original implementation used a JavaScript interval to count down, which broke when the browser tab was backgrounded — browsers throttle inactive timers. The shipping version uses absolute timestamps plus the Page Visibility API to detect the true elapsed time when the tab becomes visible again, and signs the user out immediately on return if the deadline passed while the tab was hidden.

Developer Tools

Operating a production tool inside an OIT department means I'm both the developer and the on-call. I built a suite of developer-only tools into the application itself so I can observe and diagnose without ever needing to remote into the server or attach a debugger.

The Developer Panel

Visible only to users with the Developer role, the panel slides out from the right side of any page and shows the application's internal state. The whole panel is a single Razor partial gated by an IRoleContext.IsDeveloper check — non-Developer sessions don't even receive the HTML, let alone the data behind it.

🔧  Developer Panel
×
Role & Impersonation
Real roles BaronGuard.Developer
Active view Student Support impersonating
Developer OIT Student Support Test Center
Dev Modes active
🟢 ON   Mock Graph — synthetic success, no real Entra calls
Disable Mock-Graph
Force Error
No forced error queued.
Code: None ▾ Scope: One-shot ▾ Apply
Dev modes apply only to your session. Mock-Graph takes effect on the next Graph call.
Broadcast Banner
No active broadcast.
Message to all staff…
Send Clear
Sends a live banner to every currently signed-in staff member.
Active Sessions 3
Ron Cahall Student Support
/request/3131313 · 12s ago
Dan Whittaker OIT DEV
/audit · 4m ago
Pat Proctor Test Center
/tap · 1m ago
Recent Logs 412 / 500 · seen 8,914
All Info Warn Error
Info 15:01:42 · GraphService
Password reset operation succeeded for student 3131313
Info 15:01:42 · AuditLogService
Audit entry written: e4f1a2c3
Warn 14:58:11 · GraphService
ResetPassword: retry attempt 2/3 (transient 503)
Bug Reports 1 open
Medium Open 05/16 4:20 PM · J. Smith (Student Support)
Pagination on audit page doesn't preserve filters

Developer Panel slide-out — role switcher, dev modes, broadcast, sessions, logs, and bug reports in one place

What's in the Panel

Role Impersonation

The role switcher in the panel is one of the most useful pieces. Tap "Student Support" and the entire UI re-renders as if I were a Student Support agent — the Staff lookup toggle disappears, the TAP option vanishes from the request page, and so on. Tap "OIT" and it all comes back. The impersonated role is shown as a banner across the top of every page so I can never forget which role is active, and every action I take while impersonating is recorded in the dev activity log with both the real and impersonated roles.

This means I can test what every role sees without needing a second test account, and without having to keep switching role group memberships in Entra. A one-click change in BaronGuard replaces what used to be a multi-minute round-trip through the admin portal.

Mock-Graph & Forced-Error Modes

Two session flags let me exercise the full UI without touching real Entra data. Mock-Graph mode short-circuits every Graph call to return canned success responses — useful when I want to walk through the entire reset flow during a demo without actually resetting anyone. Forced-Error mode queues a specific error code (insufficient permissions, rate limited, transient 503, expired TAP) to be returned on the next real Graph call, so I can test how the UI handles each failure mode on demand.

Architecture Highlights

BaronGuard runs as a single-instance application on an internal IIS host. Most of the engineering complexity is in keeping that single instance fast, observable, and resilient without the operational overhead of a distributed system.

Service Layer

Dependency injection wires up the entire service graph at startup. The major interfaces:

Resilience Patterns

Every Graph call passes through an auto-retry wrapper that detects transient errors (HTTP 429, 503, 504, "concurrent request" messages) and retries with backoff — 500ms, then 2 seconds — for up to three attempts. Permanent errors (user not found, insufficient permissions) skip the retry and surface immediately. This is invisible to the operator when it works, and the dev panel shows the retry attempts when it doesn't.

Long-running operations like password reset use the Graph long-running-operation pattern: BaronGuard receives a 202 Accepted with a polling URL, then polls every second for up to 30 seconds for the operation to reach a terminal state. This is what lets the UI wait correctly for hybrid AD writeback to complete before showing "success" to the operator.

Real-Time via SignalR

Two hubs, two purposes. The BroadcastHub is open to all authenticated users and pushes system-wide banner messages. The DevHub is gated to the Developer role and pushes live updates to the dev panel: log entries, session changes, new activity events, and new bug reports. A hosted background service wires singleton event sources (log buffer, session tracker, activity log, bug report service) to the hub broadcaster at startup, with a 2-second coalesce window so a burst of events produces a single push, not dozens.

Caching & Cache Invalidation

Student/staff records pulled from Informer are cached for the duration of a verification flow to avoid hammering the reporting backend, but the cache is explicitly evicted after any reset completes — so the next lookup always sees fresh data, particularly important when an MFA or email field might have just changed.

Path-Base Awareness

The app is deployed as an IIS sub-application at /BaronGuard in production but runs at the root in dev. Razor's Url.Page() and tag helpers handle this automatically. Client-side JavaScript needs to do the same — all fetch URLs and SignalR hub URLs are rendered through Razor into a single window.BaronGuard config object, so the JS uses path-base-aware URLs without any conditional logic.

Workflow Polish

The difference between a working internal tool and one that staff actively enjoy using is in the small things. These are the touches that came out of pilot feedback — each one removes a moment of friction or confusion that frontline staff hit during real use.

🔄 Reasons Filter Themselves

When you check "Password Reset" only, the reasons list automatically hides MFA-only reasons like "New or Lost Phone." Check MFA too and they reappear. Staff don't see options that don't apply to what they just selected.

🔑 Default Password Generated For You

RCBC uses a unique temporary password formula tied to each student’s own information. Rather than computing it manually, the result page shows Student Support the formula template so staff can walk the student through what their password will be — without ever displaying FERPA-sensitive information directly. OIT sees the generated value in full.

↩ "Wrong Student" Escape Hatch

Every step has a one-click way back to the lookup page if the wrong person was selected. The audit log only records action when something actually happens — abandoned flows produce no noise.

🚫 Mutually-Exclusive Reset Options

TAP can't be combined with Password or MFA — if you tick TAP, the other two grey out with an inline hint explaining why. Stops invalid combinations before submission rather than throwing an error after.

⌛ Existing TAP Detection

If a student already has an active TAP and OIT requests another, the system pauses and confirms before deleting the old one. Microsoft never returns the original code after creation, so this prevents accidentally invalidating a TAP the student already has in hand.

📋 Help Desk Pre-Verified Shortcut

If Student Support has already verified identity via the Google Chat space, OIT can pick “Student Help Desk Verified” as the contact method and skip the checklist entirely. The audit entry records this so OIT can quickly manage and track Chat-originated requests while Student Support is being phased into handling resets directly.

🕰 Eastern Time, Everywhere

Every timestamp shown to users — audit entries, broadcast send times, recent-reset warnings — is in Eastern Time, regardless of the server's timezone. No mental conversion needed during a high-pressure walk-in.

⚡ Page Loader Prevents Double-Submit

A loading indicator appears on every navigation that takes longer than a moment, and form submit buttons disable themselves. Fetch-based forms (broadcast send, bug report) opt out cleanly with a single attribute to keep the loader from sticking.

The Barry Bug Report Button

The floating bug-report button uses RCBC's Baron mascot, "Barry," with a hover-revealed speech bubble. A small touch that turned a generic feedback button into something staff actually click on. Reports flow into the developer panel with page context, severity, and the submitter's role automatically captured — the friction for "I saw something weird" is one click and a short description.

Found a bug?Let me know!
Barry the Baron mascot

Click reveals a clean modal with title, description, and severity (Low / Medium / High). On submit, the page context (current URL), user UPN, and role are auto-attached. The button itself is transparent-backgrounded with a soft drop shadow so it floats over content without competing with it.

Engineering Takeaways

BaronGuard was my first production ASP.NET Core application of this scope, and the lessons compounded quickly. A few that I'd carry forward:

Build the dev tools first, not last.

The dev panel, mock-graph mode, and dev activity log existed before half the user-facing features did. Being able to see exactly what was happening internally — with no external observability tooling — cut my debug cycles by an order of magnitude and made the rollout phase calm instead of panicked.

Make the audit log the source of truth.

Once every state-changing action wrote a structured audit entry, I could derive most other features from it cheaply — the recent-reset warning, the staff activity dashboard, the CSV export, the SharePoint mirror. If I'd started with a logging library and "we'll add structured audit later," I would have ended up with two inconsistent records.

Match permissions to the actual workflow, not the org chart.

Student Support doesn't need staff record access, so they don't get it. Test Center doesn't need multi-use TAPs, so the toggle isn't even rendered for them. Granting only what the workflow requires — not what the role technically could do — made the tool safer to roll out and easier to defend in a security review.

Respect the network you're on.

Several of the trickiest production bugs (broadcast not working in IIS, audit delete redirects 404ing, the path-base issue) all came down to dev/prod environment differences. The fix wasn't to fight them — it was to write code that respects the platform's URL generation pipeline (Url.Page, UsePathBase) instead of hardcoding paths. Once that was systematic, the bugs stopped.

A single-instance app doesn't need distributed-system complexity.

BaronGuard uses in-memory ring buffers, in-memory caches, and in-process SignalR. There's no Redis, no message queue, no second app server. For the scale (about 30 staff, thousands of actions per year), this is the right answer. The simplicity makes the operational story trivial — "if it breaks, recycle the app pool" — which matters more than "scales to a million users" when the user base is the OIT department.

Build feedback loops into the tool itself.

The bug report button isn't a vanity feature — it's the primary feedback channel for the pilot. Half the features described in this document came from a single submitted bug report or a "would it be possible to..." comment. Lowering the friction for "I saw something weird" turned every operator into a usability tester.

▶  BaronGuard Interactive Demo