# inFM for Modern IT Administrators

This guide describes how inFM can fit into an existing identity and facilities
data environment, including Microsoft Entra ID (formerly Azure AD), Microsoft
365, and Azure App Service deployments. It is intended for IT, identity, and
facilities administrators planning deployment and user access.

## Fit with an existing identity lifecycle

A common enterprise lifecycle looks like this:

```text
HR / HRIS
   |
   v
Organisation account provisioning
   |
   v
Active Directory -> Microsoft Entra ID
   |
   +--> Entra security groups (including dynamic groups, if configured)
   |
   v
inFM sign-in and group-to-role assignment
```

The HRIS, Active Directory, and Entra provisioning and group rules remain the
organisation's responsibility. inFM does not provision accounts into AD or
Entra and does not run a background directory synchronisation. Instead, a user
signs in to inFM with SSO; inFM can create the corresponding application
account and check the user's Entra group memberships during that sign-in.

For example, Entra can maintain dynamic groups based on HR-fed department,
job-title, or office-location attributes. An inFM administrator maps those
groups to inFM roles and locations. inFM checks group membership, not HR
attributes such as department or job title directly.

## What Entra SSO can do

### Available sign-in methods

SSO sign-in is hidden until the server has complete, valid `SSO_PROVIDER`,
`SSO_CLIENT_ID`, `SSO_CLIENT_SECRET`, `SSO_AUTH_URL`, `SSO_TOKEN_URL`, and
`SSO_REDIRECT_URI` environment settings and SSO is enabled in Authentication.
Provider settings saved only in the app do not enable SSO; the client secret
must stay server-side. `SSO_USERINFO_URL` and `SSO_LOGOUT_URL` are optional for
Microsoft Entra.

In **Settings -> Authentication**:

- **Simple Login (Email & Password)** allows password sign-in only (the default).
- **Both Simple & SSO** offers both methods once SSO is configured.
- Check **Only allow SSO sign-in** (or choose **SSO Only**) to prohibit password
  sign-in for every user, on both frontend and backend. Unchecking selects dual
  sign-in. This uses the existing authentication-method setting.

The SSO-only checkbox and SSO authentication choices are disabled until the
environment is configured. Test SSO with an administrator account before
enabling SSO-only. The password API also rejects sign-in in SSO-only mode;
existing sessions are not revoked by changing this setting. If environment
configuration later becomes incomplete, SSO-only remains enforced and no
password fallback is offered. Restore the environment settings and restart
the app to recover access.

Repeated SSO sign-in matches the existing account by email; a new session does
not create a new account or clear its named Jobs/Assets filter presets. These
presets are saved to the account in the database and can be applied again after
login. The selected appearance theme is retained per account in the current
browser after logout, but does not sync across browsers or devices. Unsaved
active filters are not automatically restored. Changes to the SSO email address
can match a different account; review identity changes with the administrator.

After an administrator configures Microsoft SSO in **Settings ->
Authentication**, the first successful login can create a user account; the
user does not have to be pre-created in **Settings -> Users**. Existing users
are matched by email address.

When group mappings are configured, inFM checks Microsoft Graph group
membership at sign-in and can apply:

- An inFM base role (Viewer, User, Domain Admin, or Super Admin).
- An optional inFM custom role for granular permissions.
- Domain, Region, Site, and Building assignments selected on the group
  mapping.

Prefer the Entra security group's object ID over its display name. If a user is
in multiple mapped groups, inFM selects the highest-priority mapped role and
combines the locations assigned to the matching scoped groups. A selected
Domain, Region, or Site expands to its descendant Buildings; selecting a
Building grants only that Building. inFM stores the resolved assignments on
the user and filters the job-reporting building picker accordingly. The API
also checks the selected Building when a user creates a job, so changing the
browser request cannot bypass that job-location restriction.

Group membership and role/location changes are evaluated at sign-in; this is
not a continuous sync or an immediate revocation of existing sessions. The
current Microsoft lookup uses the signed-in user's `/me/memberOf` results; do
not assume nested group membership is included. Test the actual membership
pattern used by your tenant.

### Admission control and least privilege

SSO group mappings assign roles; they are not by themselves a deny-list for
sign-in. A user who can sign in from an allowed email domain but has no
matching group mapping can still be provisioned as a Viewer with front-end
access when no location-scoped mappings are configured. Configure Entra
enterprise-application assignment restrictions as well as inFM's
**Allowed Email Domains** when only specifically assigned users or groups
should be admitted.

Treat a role mapping as an automatic grant. A dynamic group based on a title
such as "Facilities Manager" can automatically grant the role configured for
that group; it does not wait for an inFM administrator to approve each person.
Map groups to the minimum role needed, test with representative accounts, and
keep Super Admin membership tightly controlled. Removing a user from a mapped
group does not disable their identity-provider account. If any location-scoped
group mappings are configured, a user must match at least one scoped group to
complete SSO; role-only groups do not grant location access on their own. If a
user moves between scoped groups, their assigned role and location scope are
updated at their next successful sign-in. Include Entra disablement and access
review in the organisation's offboarding process.

Users with front-end-only access should be tested against the exact reporting
and issue-submission flows intended for them before enrolling a large group.

## Location data and user access scope

inFM's location hierarchy is:

```text
Domain -> Region -> Site -> Building -> Floor / Space
```

The repository includes
[Export-LocationDataFromAzureAD.ps1](../../scripts/Export-LocationDataFromAzureAD.ps1)
to prepare location rows from Microsoft Graph profile attributes for review
and CSV import. Its defaults map `companyName` to Domain, `state` to Region,
`city` to Site, and `officeLocation` to Building. These are configurable
defaults, not a required interpretation of your directory. Agree on the
organisation's source attributes, clean up inconsistent values, and review
the export before importing it. This is a one-time export, not live sync.

**HR attribute mapping pattern:** Entra dynamic groups can use HR-synchronised
attributes (for example Department, Job Title, or Office Location) as group
membership rules. Map each appropriate group to the matching inFM Region,
Site, or Building in **Settings -> Authentication -> SSO Security Group
Mappings**. For example, a dynamic group for an office can map to that office's
inFM Building; a regional group can map to the inFM Region and include all
buildings under it. inFM does not directly read or interpret those HR profile
attributes during SSO.

If any group mapping has a location scope configured, every SSO user must
belong to at least one matching location-scoped group. Login is denied when
the account has no such match or when the mapped inFM locations resolve to no
Buildings. This avoids silently giving an unmapped user access to every
building. An unscoped role mapping can still contribute its role when the user
also matches a scoped group; it does not widen that user's location scope.

The restriction applies to job creation: the front-end reporting form lists
only assigned Buildings and the API rejects a job for an unassigned Building.
Other data visibility continues to follow inFM's existing role and Domain
scoping; Building assignments are not a global filter for every screen.
Changes to Entra memberships take effect on the user's next SSO sign-in.

The location export and import workflow is documented in the
[Administration User Guide](./USER_GUIDE_ADMIN.md#csv-upload-utility).

## Recommended rollout

1. Deploy inFM to the organisation's approved hosting environment. For Azure
   App Service configuration, networking, and runtime settings, see the
   [Azure Deployment Guide](./AZURE_DEPLOYMENT.md).
2. Confirm the inFM Domain, Region, Site, and Building hierarchy with
   Facilities and IT. Use the export script only with approved Microsoft
   Graph access, and review its CSV before importing.
3. Configure the Entra application, exact SSO redirect URI, server-side
   client secret, allowed email domains, and any Entra application assignment
   restrictions. See the [Environment Variables Reference](./ENVIRONMENT_CONFIGURATION.md)
   for deployment configuration.
4. Configure one low-privilege all-staff or pilot group and a separate,
   tightly controlled administrator group. Prefer object IDs and map each
   permitted user cohort to the appropriate inFM Region, Site, or Building.
   A broad role-only group must be accompanied by a matching scoped group for
   each user when location-scoped mappings are configured.
5. Test first login, automatic account creation, front-end access, role
   assignment, allowed/denied Building selections, domain visibility, and
   offboarding with separate test accounts. Confirm that out-of-scope job
   submissions are rejected by the API, not only hidden in the UI.
6. Document who owns Entra group membership, inFM role mappings, location
   assignments, and user offboarding. Review the configuration whenever
   identity or facilities hierarchies change.

For the inFM authentication settings and SSO setup details, see the
[Administration User Guide](./USER_GUIDE_ADMIN.md#microsoft-entra-id--microsoft-365-single-sign-on).
