Skip to content

Features

Sebastian F. Markdanner [MVP] edited this page May 24, 2026 · 4 revisions

Long-form feature reference for the first public release. For a quick overview, see the README.

Bulk activation across three PIM planes

The portal unifies three normally separate planes into a single table:

  • Microsoft Entra ID roles — directory-scoped (e.g. Global Reader) and Administrative-Unit-scoped roles.
  • Azure Resource roles — discovered from a tenant-root asTarget() enumeration so the portal does not need to crawl every subscription you can see. Scopes shown beneath each role: management group, subscription, resource group, or specific resource.
  • PIM for Groups — both Member and Owner access types.

Select any combination across all three planes and submit them as a single bulk operation. Results stream back per role; partial successes are normal and visible.

Bulk deactivation

Active roles can be selected and deactivated in bulk with optimistic UI updates. The "Select All" affordance on the active table selects only PIM-activated roles, leaving permanent assignments untouched.

Pending approval tracking

Roles whose policy requires approval are surfaced inline with a Pending tag from the moment the request is submitted. The activity-details modal shows the request ID and status code so you can correlate with notifications from your approver workflow.

Tenant switcher

Switch between home, guest, and member directories without signing out. Your selection persists in sessionStorage for the tab session. Each directory has its own role and policy cache so toggling does not blow away cached data.

Per-role policy matrix

Every eligible role exposes the policy requirements that govern its activation:

Requirement What it means
Justification A reason is mandatory at submit
Ticket A ticket system + ID is mandatory at submit
MFA The user must have a recent strong authentication
Auth context The user must satisfy a Conditional Access auth context (claims challenge)
Approval The activation request must be approved before it takes effect
Max duration Hard cap applied to the requested duration

The policy matrix is fetched once per tenant and cached for 30 minutes in memory. See Policy Awareness for what the portal does with each requirement.

Conditional Access auth context (claims threading)

When a role's policy requires a Conditional Access auth context (acrs claim), the portal:

  1. Detects the requirement from the role policy.
  2. Triggers an MSAL re-auth with the appropriate claims challenge.
  3. Threads the resulting claims into every subsequent token acquisition for the operation, so all Graph and ARM calls satisfy the requirement without prompting again.

401 responses with WWW-Authenticate: insufficient_claims (or a JSON-encoded claims body) are also detected at the API client layer and resolved through the same flow.

Activation profiles

Named role sets persisted in browser-local IndexedDB. Per-profile pre-fills for justification, ticket, and duration. Optional tenant scoping for guest scenarios. JSON import / export to move profiles between browsers, devices, and teammates (tenant scoping preserved on import). See Activation Profiles.

Live expiry countdowns

Every active role shows time-remaining, ticking every 30 seconds. Colour-coded urgency (green → yellow → red) as expiry approaches. Hovering a row reveals the absolute expiry time.

Notifications and activity history

  • Typed toast notifications (success / warning / error / info) with optional descriptions.
  • Persistent in-session notification panel with an unread badge.
  • Activity-details modal: per-role outcome, status code, error message, submission time, scheduled start, duration, justification, ticket number used.

Three themes plus system auto-detect

  • Dark (default), Light, and High contrast.
  • Until you pick one explicitly, the portal follows your OS light / dark preference.
  • Theme choice is saved in localStorage.

Inline search, filter pills, saved filters

  • Type-ahead filter on both the eligible and active tables, matching role name and scope.
  • Quick-toggle pills for role types (Entra / Azure / Groups).
  • Saveable named filters that pin to the filter bar for one-click reuse.

Settings and feature flags

The Settings modal exposes feature flags persisted to localStorage:

  • Enable / disable individual planes (Entra / Azure / Groups)
  • Default activation duration
  • Show already-active roles in the eligible table
  • Tenant-scoped profiles
  • UI toggles (theme switcher in header, show inactive policies, persisted section state)

Installable as a PWA

The portal ships a Web App Manifest (Portal/manifest.json) with display: standalone, maskable 192 / 512 icons, a theme-color, and the apple-mobile-web-app-* meta tags Safari needs.

In practice that means:

  • Desktop (Chrome / Edge) — click the Install app icon in the address bar, or browser menu → Install PIMActivation Portal. It launches in its own window with its own icon, no browser chrome.
  • Android (Chrome) — menu → Install app / Add to Home screen.
  • iOS / iPadOS (Safari) — Share sheet → Add to Home Screen. Tapping the home-screen icon launches the portal full-screen with the title "PIM".

There is no service worker, so the portal does not function offline — installing it is purely about an app-like launch and window chrome. You still need a network connection to talk to Microsoft Graph and ARM.

Help and in-app guide

The Help dropdown in the header surfaces an in-app guide, FAQ, "how it works" overview, and a direct link to GitHub Issues.

State and caching

  • TokenssessionStorage only; cleared when the tab closes.
  • Roles — per-tenant role cache in localStorage, refreshable on demand.
  • Policies — 30-minute in-memory cache.
  • Profiles — IndexedDB; survives across browser sessions.
  • Feature flagslocalStorage; surfaced in the Settings modal.

Clone this wiki locally