Auburn MyGov Docs Gitea

Platform

Microsoft Platform

How MyGov integrates with Microsoft 365 — the guiding principle, two integration patterns, and the design for authentication, Exchange resource mailboxes, calendar surfaces, and Entra-based permissions.

Status Draft
Last updated
Related LayerLocation · Calendar & Time · Distribution & Publishing
PlatformWorkflow Engine
ModuleReservations

Guiding Principle

Design Rule

MyGov can fully control any data it depends on. If MyGov reads from Microsoft and displays or acts on that data, it must also be able to modify it — either by writing back to Microsoft directly, or by maintaining its own override layer. No feature should be blocked by a ticket to IT or a permission MyGov does not hold.

This rule resolves integration questions without case-by-case debate. It produces two distinct patterns, each appropriate for different data:

Pattern How it works When to use Examples
Read / Write MyGov reads from and writes directly to Microsoft via Graph API. Microsoft and MyGov stay in sync; Microsoft is not bypassed. MyGov owns the operational outcome. The Microsoft artifact exists because MyGov needs it to exist. Resource mailbox provisioning and management; Entra group membership for module permissions; pushing reservation confirmations to room calendars
Seed and Override MyGov reads from Microsoft to populate its own records, then manages a local override layer. Microsoft remains the source of truth for its own data; MyGov's display or behavior can diverge without IT involvement. Microsoft owns the record of truth, but MyGov needs control over how it is displayed or used — without changing the underlying Microsoft record. Employee display name and title (seeded from Entra, overridable in Employee module); resource mailbox display name (seeded from Exchange, overridable in FacilitySpace record)

The seed-and-override pattern is the same principle as Employee → EmployeeContact — the record of truth is separated from what is displayed. Applied at the integration layer it means MyGov is never fully dependent on the Microsoft record being correct or current for the public-facing experience.

Two Surfaces, Two Authorities

The core calendar design splits cleanly along audience lines. Trying to use one surface for both has been the source of past reliability and compliance problems.

MyGov — authoritative

Citizen-facing

  • MyGov calendar component — WCAG 2.1 AA compliant
  • ICS / webcal feeds for public subscriptions
  • Program and event data owned by MyGov
  • No dependency on Exchange availability or formatting
Microsoft 365 — staff working surface

Staff-facing

  • Outlook calendar — where staff work, not replaced
  • Resource mailboxes for room booking and availability
  • MyGov writes TO Exchange; staff see results in Outlook
  • Staff subscribe to MyGov ICS feeds — add to Outlook, not embed on pages
The embedded Outlook calendar is retired. Embedding Exchange calendars directly on public web pages is a WCAG compliance failure and a reliability dependency on Microsoft's rendering. It is replaced by the MyGov calendar component on public pages. Internal staff pages offer an ICS subscription link ("Add to Outlook") — not an embed. Staff who want to see a calendar use Outlook; citizens use the website.

Authentication — Entra / Azure AD

All MyGov admin portal staff authentication is handled by Entra (Azure AD) via OAuth 2.0 / OpenID Connect. No credentials are stored in MyGov. The login flow redirects to Microsoft, and MyGov receives an identity token and claims on return.

Claims currently used by the API include basic identity (name, email, object ID) and extended properties for department and position checks. Entra group membership is partially in use for some permission checks but has not been widely rolled out due to the lack of admin portal tooling to manage group membership without IT involvement.

Authorization model

The guiding principle applies here: if MyGov makes authorization decisions based on Entra group membership, MyGov must be able to manage that membership. The design therefore separates two concerns:

  • Identity — always Entra. Who the user is, that they are a city employee, their base profile. MyGov does not replicate this.
  • Authorization — MyGov manages its own role and permission assignments in the admin portal. Entra group membership can seed an initial role on first login (e.g. a member of the Parks group gets the Parks Editor role), but MyGov admins can adjust permissions without filing an IT request. MyGov writes group membership back to Entra via Graph API when an admin changes a role that maps to a group.

This means the admin portal needs a permission management screen where a MyGov admin can assign module roles to staff members, and those assignments are reflected in both MyGov's own permission records and the corresponding Entra group. Neither system is out of sync, and neither IT nor a developer is in the critical path for a permission change.

Migration note. The current department/position extended property checks on the API are a transitional mechanism. As the admin portal permission management screen is built out, module access should migrate to role-based checks against MyGov's own permission records, with Entra groups as the backing store. The extended property checks can be retired module by module.

Exchange Resource Mailboxes

A FacilitySpace may be backed by an Exchange resource mailbox. The mailbox provides room availability in Outlook's room finder, receives calendar events for confirmed reservations, and gives staff a familiar surface for seeing what is booked in a space.

MyGov is the system of record for the FacilitySpace. Exchange is a sync target — a staff-facing artifact that MyGov creates, manages, and writes to. The association is optional per space, and it is independent of citizen-reservability: a staff-only conference room booked entirely through Outlook still has a resource mailbox, and that mailbox address is stored on the FacilitySpace record even without a reservationConfig present.

Two distinct Exchange fields: FacilitySpace.exchangeResourceMailbox is the room resource identity (Place-level; used for room finder, meeting invite, Place.ReadWrite.All operations). data.Calendar.exchangeCalendarAddress is the Exchange calendar that MyGov syncs events to (Calendars.ReadWrite operations). For a reservable conference room both fields may reference the same SMTP address, but they represent different Exchange concepts and different Graph API calls. See Calendar & Time.

Mailbox lifecycle — fully managed by MyGov

IT currently provisions resource mailboxes manually in Exchange Admin. Under this design, the MyGov API takes over that responsibility for spaces managed within MyGov, using Graph API with the appropriate service principal permissions. IT consents to those permissions once; MyGov manages the mailboxes from that point forward.

Admin Portal
Create / update FacilitySpace
set reservationConfig
MyGov API
MyGov API
Graph API
provision mailbox
Exchange Resource Mailbox
MyGov API
stores mailbox ID
on FacilitySpace
FacilitySpace record

The admin portal exposes the following mailbox operations:

  • Provision — create a new resource mailbox for a FacilitySpace. Naming convention is enforced by the API (e.g. space-{facilitySlug}-{spaceSlug}@auburnal.gov). Admin-only.
  • Look up and associate — search existing Exchange mailboxes via Graph API and link one to a FacilitySpace record. Used for spaces that predate this system or were provisioned outside MyGov.
  • Add to Outlook — given a staff member, add the space's resource mailbox to their Outlook calendar list via Graph API. Removes the need for staff to find and subscribe manually.
  • Write reservation events — when a reservation is confirmed in MyGov, a calendar event is written to the resource mailbox automatically. Staff see it in Outlook.

Naming convention

Resource mailbox addresses follow the pattern rm_{building-abbreviation}_{roomName}@auburnal.gov — for example, rm_LIB_ProgramRoom for the Program Room at the Library. The convention is enforced at provisioning time by the MyGov API. The display name visible in Outlook's room finder is seeded from the FacilitySpace name and can be overridden in the FacilitySpace record without renaming the mailbox address.

Calendar Integration

MyGov → Exchange (write)

MyGov writes to Exchange immediately when a booking or calendar event is created, updated, or deleted in MyGov — not on a scheduled job. The Exchange resource mailbox is the single source of truth for room availability: both staff (via Outlook) and citizens (via the MyGov booking form querying Exchange free/busy) read from it in real time.

Resource mailbox writes:

  • A reservation is submitted — write a blocking event to the resource mailbox immediately, regardless of approval status. This ensures the time is unavailable in Outlook and to other MyGov bookings from the moment of submission.
  • Staff approve a pending reservation — send a confirmation email to the citizen. The Exchange event is already there.
  • Staff deny a pending reservation — cancel the Exchange event and notify the citizen.
  • A reservation is cancelled (citizen or staff) — remove the Exchange event immediately.

Shared calendar writes: When any entity in MyGov publishes or updates an event that maps to a Calendar with an exchangeCalendarAddress, the write to Exchange happens in the same operation — no scheduled sync needed. The scheduled job model was rejected for the write direction because it creates a window where Exchange and MyGov are out of sync.

Exchange → MyGov (read)

Reading from Exchange into MyGov is a deliberate, opt-in flow — not an automatic sync. The use case is staff who author events in Outlook that need to surface on the public website. This should be an intentional action (a "publish to website" step) rather than an automatic mirror, for two reasons:

  • Not everything on a staff calendar should be public. Automatic sync risks surfacing internal or private events.
  • ICS feeds lose structured data — location links, registration URLs, images. An event authored in Outlook and synced to MyGov arrives as thin iCal fields only.

When this flow is used, the mechanism is Graph API read (not ICS) to preserve as much structure as possible. The result is a native MyGov calendar entry that staff can then enrich with structured fields (facilityId, imageUrl, registrationUrl) in the admin portal.

ICS feeds

MyGov publishes an ICS feed for each calendar. These feeds are:

  • Outbound only. Citizens and staff subscribe; nothing writes back via ICS.
  • Public-facing. The primary use case is citizens adding a city calendar to their personal calendar app, or staff adding a MyGov calendar to Outlook as a subscription calendar.
  • Read-only in Outlook. Staff who subscribe to a MyGov ICS feed see events but cannot edit them. This is intentional — edits happen in the MyGov admin portal, not in Outlook.
Staff adding events to their Outlook subscription does not write back to MyGov. This was the source of the previous "I added it in Outlook but it didn't show on the website" problem. Staff documentation must be explicit: MyGov is where events are managed. Outlook is where you see them. The ICS subscription is read-only by design.

Graph API Permissions

The MyGov API service principal requires the following Microsoft Graph application permissions. These are consented once by a tenant admin (the City's IT administrator or the MyGov system owner with appropriate Entra access). No per-request IT involvement is needed after initial consent.

Permission Type Purpose
Calendars.ReadWrite Read / Write Write reservation events to resource mailbox calendars; read calendar data when pulling Exchange events into MyGov
Place.ReadWrite.All Read / Write Provision and manage Exchange resource mailboxes (rooms); read existing room directory for association
Group.ReadWrite.All Read / Write Manage Entra group membership for MyGov module permissions; read group membership on login for role seeding
User.Read.All Read Seed employee records from Entra profile data; look up staff by name or email in admin portal
User.ReadWrite.All Read / Write Add resource mailboxes to a staff member's Outlook calendar list on their behalf
Directory.Read.All Read Read department, position, and organizational unit data for role seeding and display in Employee records
These are application permissions, not delegated. MyGov acts as a service principal — it does not act on behalf of individual users for these operations. The exception is User.ReadWrite.All for adding a mailbox to a specific user's Outlook, which may require a delegated flow initiated by that user or an admin acting on their behalf. The exact consent model for that operation should be confirmed during implementation.

Employee Data — Seed and Override

Employee records in MyGov are seeded from Entra on first login or via a periodic sync. Entra remains the source of truth for identity — the employee's legal name, primary email, and organizational position. MyGov maintains its own override layer for fields that need to differ on the public-facing website:

  • Display name (may differ from legal name)
  • Job title as shown to the public (may differ from HR title)
  • Contact phone and email shown on pages (may be a department line, not a personal address)
  • Photo
  • Whether the employee is shown publicly at all

The EmployeeContact record (see Distribution & Publishing) carries the public-facing values. The Employee record carries the Entra-seeded values plus the overrides. Neither requires an IT request to update.

A periodic sync (ServerJob schedule) refreshes Entra-sourced fields on Employee records — name, email, department — without overwriting locally managed fields. New employees who log in for the first time get an Employee record created automatically.

Audit Findings

Codebase audited: api/Classes/Workflow/Handlers/MSGraphHandler.cs, api/Classes/Services/FacilityBookingService.cs, api/Classes/Services/TokenService.cs, api/Classes/Workflow/Handlers/MSGraphHandler.md

MSGraphHandler registered operations

ActionStatusNotes
CreateEventBUILTCreates calendar event for a user or user\CalendarName. Used for room blocking from program sessions.
CreateListItemBUILTCreates SharePoint list items via Graph
SendMailBUILTSend email via Graph on behalf of service account or shared mailbox
SendTemplateBUILTRender HtmlEmail template + send — combines Mail/Merge + MSGraph/SendMail in one action
ListUsersBUILTLists Azure AD users with optional filters
GetUserPhotoBUILTDownloads user profile photos; Target: "all" or specific email/objectId
GetAccessTokenBUILTAcquires token into context for downstream handlers
SyncUsersDeltaBUILTSyncs Azure AD users to local employee table using delta query — the Entra→Employee sync mechanism
ProcessMailboxNDRsBUILTPolls shared mailbox for bounce messages, updates CampaignRecipient delivery status. Needs ServerJob row + credential to activate.

IFacilityBookingService — resource mailbox operations

A dedicated service (not a workflow handler) handles all Exchange room operations:

MethodStatusNotes
GetScheduleAsync (free/busy)BUILTGraph getSchedule endpoint; checks resource mailbox availability for a date
CreateBookingAsync (create event)BUILTCreates Exchange event on resource mailbox; returns eventId for future cancellation
CancelBookingAsync (delete event)BUILTDeletes Exchange event by ID from the resource mailbox
Provision resource mailboxNOT STARTEDDesign calls for API-driven mailbox provisioning; not yet implemented

Feature status summary

FeatureStatusNotes
Entra auth for staff (JWT bearer)BUILTStandard ASP.NET Microsoft Identity Web integration
Employee sync from Azure AD (SyncUsersDelta)BUILTDelta query sync to local employee table. ServerJob runs this on a schedule.
Employee photo sync (GetUserPhoto)BUILTDownloads and stores photo to ImagePathSource
Resource mailbox read (free/busy)BUILTGetScheduleAsync via FacilityBookingService
Resource mailbox write (create/cancel events)BUILTCreateBookingAsync / CancelBookingAsync via FacilityBookingService
NDR processing (ProcessMailboxNDRs)BUILTActive — ServerJob and credential configured, ran successfully against first live campaign.
Resource mailbox provisioning (create new)NOT STARTEDDesign calls for Place.ReadWrite.All permission and admin UI — not yet built
Entra group management (Group.ReadWrite.All)NOT AUDITEDDesign calls for MyGov to manage Entra groups backing portal roles; not audited in this pass. Prerequisite: agree a group naming convention with IT before rollout (e.g. mygov-{module}-{role}).
Exchange → MyGov event flow (opt-in publish from Outlook)DEFERREDRead direction is complex and deferred. Design is documented (Graph API read, not ICS; staff enriches in admin portal). Until built: Outlook is read-only relative to the public website — must be explicit in staff documentation.
Employee sync frequencyCONFIGUREDSync runs as a scheduled ServerJob via the workflow engine. Frequency is configured in the ServerJob record — no code change needed to adjust the schedule.
Teams notifications (TeamsNotifyHandler)BUILTSeparate handler; posts to Teams channels via incoming webhook or Graph