Skip to content
Tobias Almén edited this page Sep 28, 2026 · 1 revision

Admin elevation

Lets a standard user hold administrator rights for a fixed number of minutes, with a reason recorded where they cannot edit it.

Read this first. Elevation is containment with an audit trail, not a security boundary. Brief root access has other routes to persistence — a launch daemon, a sudoers drop-in, enabling the root account — none of which group membership shows. Treat it as a speed bump you can account for afterwards.

Turning it on

All of these must come from a configuration profile. Set anywhere else they are ignored and the reason is logged. See Configuration.

<key>EnableElevation</key>
<true/>
<key>MaxElevationTime</key>
<integer>10</integer>
<key>RequireResonForElevation</key>
<true/>
<key>ReasonMinLength</key>
<integer>20</integer>

Before you turn it on, read Deploying the helper. Deploying the helper declaratively is recommended wherever elevation is used, because an elevated user is briefly root and root can unload an ordinary LaunchDaemon — including the one that is about to demote them.

What the user sees

  1. An Elevate button on the home page and in the menu bar popover.
  2. If RequireResonForElevation is set, a field for the reason, which must reach ReasonMinLength characters.
  3. Rights are granted, and the menu bar shows the time remaining.
  4. A notification says when the session starts and warns before it ends. Its Demote button hands the rights back early.
  5. At the deadline the helper demotes them, whether or not the app is still running.

ShowElevateTrayCard controls only whether the card appears in the menu bar popover.

How it is enforced

Everything below is the helper's doing, not the app's.

  • The deadline lives in a root-owned file under /var/db/com.github.macadmins.SupportCompanion, along with the timer. Quitting the app does not extend an elevation, and a deadline that passed while the Mac was off is caught up on at startup. The app's timer only drives the countdown shown on screen.
  • Rights granted to other accounts during a window are taken back. The helper watches the admin group for the length of the window, by short name and by UUID, and revokes rights given to anyone who was not already an administrator when the window opened — repeatedly, if they are granted again. The elevated user keeps their own until the timer runs out.
  • More than one user can be elevated at once. With fast user switching each window is tracked separately with its own deadline.
  • Uninstalling demotes first. The uninstaller removes the helper, which is the thing that would have taken the rights away, so it demotes anyone still elevated before removing anything.

The audit trail

Reasons and every grant and revocation are written to elevation.log, a root-owned file in /var/db/com.github.macadmins.SupportCompanion, next to the elevation state in elevation.plist. Reasons are flattened to a single line and bounded in length first, so one containing newlines cannot forge entries and a very long one cannot inflate the log.

A copy is also written to ~/Library/Application Support/SupportCompanion/ElevationReasons.json. That file is writable by the user, so treat it as a convenience, not as evidence.

Webhook

Set ElevationWebhookUrl and each reason is posted as JSON:

{
  "reason": "Installing a printer driver",
  "date": "2026-09-24T09:15:00Z",
  "user": "geralt",
  "host": "Kaer-Morhen-MBP",
  "serial": "C02XK1ABCDEF",
  "severity": 6
}

severity is whatever you set ElevationSeverity to, for feeding straight into a SIEM. If the post fails, the reason is written to disk instead so it is not lost.

The admin allowlist

Optional, and off by default. Without it, a user who is briefly root can delete the helper's state file and restart the helper, leaving nothing to say a demotion was owed — and no way to tell their rights from a permanent administrator's.

With an allowlist set, the helper reconciles the admin group at startup and every five minutes. Anyone holding administrator rights who is neither in PermanentAdmins nor inside a live elevation window is demoted. Deleting the state file then ends an elevation rather than extending it.

Both keys must come from a device-scoped profile, since reconciliation runs when there is no logged-in user to attribute it to.

<key>EnforceAdminAllowlist</key>
<true/>
<key>PermanentAdmins</key>
<array>
    <string>ladmin</string>
    <string>breakglass</string>
</array>

PermanentAdmins must list every account that should keep administrator rights before you turn enforcement on. Management accounts, break-glass accounts, permanently-admin staff — and accounts granted rights by something else, such as Platform SSO's AdministratorGroups. Anything not on the list is demoted within five minutes, and an identity provider that grants it again simply produces a demotion every five minutes.

Details worth knowing:

  • An empty array is honoured and means nobody is permanently an administrator; every administrator is a live elevation. A missing key is refused with an error rather than acted on, because acting on it would demote every administrator on the Mac.
  • root is always permitted and never demoted.
  • The policy is re-read on every pass, so removing the profile suspends enforcement while it is actually missing rather than permanently.
  • Group members that cannot be resolved to an account are reported and left alone. A failed lookup is not evidence that an entry does not belong.
  • ElevationAllowedAdmins names accounts the watchdog should not report as unexplained — a management account an MDM may legitimately add while somebody is elevated.

Clone this wiki locally