Altien wires Mike into corporate Microsoft logins

The fork swaps a single hardcoded login system for a switchable one, with Microsoft's enterprise identity service now a first-class option.

integrationsecurity

Maintained by Allen Morgan · verified on MikeWatch

Altien rebuilt how Mike checks who's logging in. Where the original fork was locked to one login provider, this version lets a deployment pick its own - and the headline addition is support for Microsoft Entra, the corporate identity system most large organisations already use to manage staff accounts. For a firm or in-house team that runs on Microsoft, that means Mike can sit behind the same logins, groups, and tenants employees use for everything else, rather than standing up a separate account system.

There's also a built-in local login mode for development or air-gapped, no-internet deployments - useful for anyone with data that can't touch outside services. The work was done carefully enough to accept the various token formats different Microsoft setups hand out, so customers shouldn't have to reconfigure their identity setup to adopt it.

So what Legal teams standardised on Microsoft can plug Mike into their existing corporate sign-on instead of managing yet another set of credentials.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

3 commits from Altien/mikeOssAzure, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
bfee639b refactor(auth): extract AuthProvider interface and Supabase provider Allen Morgan 2026-05-08 ↗ GitHub
commit body
Provider-neutral AuthPrincipal + AuthValidationResult types in
auth/types.ts. Existing inline Supabase validation extracted to
auth/providers/supabase.ts. Middleware dispatches on AUTH_PROVIDER env
var, defaulting to 'supabase'; unknown values return 500.

Zero behaviour change when AUTH_PROVIDER is unset or 'supabase'.
Downstream routes still receive res.locals.userId / userEmail / token;
res.locals.principal is added as the canonical surface.
f9eb061c feat(auth): Entra ID provider with JWKS + tenant lifecycle + roles Allen Morgan 2026-05-08 ↗ GitHub
commit body
Adds the Entra branch of the auth boundary established in the previous
refactor. Components:

  * lib/auth/providers/entra.ts  - JWT validation against the tenant's
    JWKS (5-minute cache), with both v1.0 and v2.0 issuer + audience
    shapes accepted, exp/nbf checks, and a fallback chain for the
    email and display-name claims that Entra optionally populates.

  * lib/auth/roles.ts            - Maps Entra group OIDs to app roles
    via ENTRA_ADMIN_GROUP_IDS / ENTRA_MEMBER_GROUP_IDS env vars.
    TenantAdmin includes Member by inheritance.

  * middleware/tenantAccess.ts   - Entra-only tenant lifecycle: looks
    up the principal's tenant in the tenants table, denies UNKNOWN /
    PENDING / SUSPENDED tenants, and enforces group-to-role mapping.
    Auto-onboards when TENANT_ONBOARDING_MODE=auto.  No-ops for any
    other auth provider so non-Entra deployments are unaffected.

  * middleware/requireRole.ts    - Tiny role guard that 403s when the
    principal lacks the requested role.

  * Auth middleware now dispatches "entra" alongside "supabase" and
    routes every authenticated request through tenantAccess (no-op for
    non-Entra) after upserting the user_profiles row from the IdP
    claims.  upsertUserProfile back-fills display_name only when null
    so the user's own edits aren't clobbered on every request.
ec310e59 feat(auth): local HS256 provider + login/OpenID routes Allen Morgan 2026-05-08 ↗ GitHub
commit body
Adds the third arm of the auth boundary - a local HS256 provider for
the docker-compose dev stack - plus the routes that drive provider-
flow logins:

  * lib/auth/providers/local.ts - stdlib-only HS256 verification.
    No new dependency.  When PostgREST eventually moves to JWKS, this
    becomes a thin jose wrapper and call sites stay the same.

  * routes/auth.ts - three families of routes:
      - POST /local-login        : mints an HS256 token for a stub email
                                   when AUTH_PROVIDER=local
      - GET  /providers          : lists available IdPs for the frontend
      - GET  /logout             : provider-aware sign-out (entra clears
                                   the IdP session, others bounce to /login)
      - GET  /select-provider, /login-provider/:id, /openid-callback/:id
                                 : Entra OIDC code-flow with HMAC-signed
                                   state cookie

  * Middleware now dispatches the "local" branch.

The router itself is added to the codebase but not yet mounted on the
Express app - the index.ts wiring (and the API prefix shift) lands in a
later commit so this one stays focused on the provider boundary.

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-189.md from inside the repo you want the changes in.

⬇ Download capture-thread-189.md