Alpha — the platform is in development. Docs cover what ships today; anything unbuilt is marked. Concepts
-rw-rw-r-- content:content /docs/concepts/elevation.dtmpl ● verified against v2.0

Elevation

Being a member of the admin group is who you are. It is permanent, and on its own it does nothing that an ordinary permission would refuse. Elevation is a temporary state a session enters to do those few things — and it is a state, not a role. Identity introduces the distinction and Permissions lists the seven gates that ask for it; this page is elevation itself, start to finish.

The shape to hold before the detail: a member proves they may, the session is marked elevated with an end time, and the mark expires. No role changes, no group changes. The person is the same person the whole time; only the session's state moves.

Starting it#

An action a member is allowed to attempt only because they are a member — one of the seven gates — is refused when the session is not elevated, and that refusal is a 403. The admin client raises a prompt off that 403, quoting the server's own reason, and asks for:

  • the admin password, and
  • a second factor (a time-based code), when the installation has one on.

If they check out, the elevation is granted and the refused request is sent again, unchanged — the person does not redo their work, they authorise it and it proceeds. In the terminal the same thing has a name: sudo <command> elevates the session and runs the command behind it.

The admin password is not a login password, and it is not the person's own account password. It authenticates elevation and is set from outside the running system:

docker exec coolms_app php bin/console coolms:admin:credential

That command has two duties — it sets the password and registers the first confirmed second factor — and until it has run, elevation cannot be granted at all. A fresh installation has no elevated path into it by design.

The clock#

An elevation carries an end time, fixed at the moment it is granted. This is the single most important thing about it, because it is what makes elevation temporary in fact and not just in intention:

  • The lifetime is a runtime setting — fifteen minutes by default — with a ceiling of one hour that the platform enforces whatever the setting says, and a floor of one minute so the prompt cannot reappear inside a single operation. A stored value above the ceiling is clamped down to it, not refused.
  • It is read at grant, and never at the check. The end time is written into the grant; the check that later asks "is this session still elevated?" reads the grant. So changing the lifetime setting affects the next grant, and elevations already running finish exactly as they were issued — a setting change is never retroactive.
  • When the clock passes the end time, the session is simply not elevated any more. Nothing has to fire for that to become true: it is a comparison against the clock, made when the state is read. A suspended tab, a laptop asleep, a clock nudged forward — none of them can leave a session elevated past its end time, because none of them is what ends it. The end time does.

The record#

Every elevation is a row, and the row is the audit trail. It carries the session it belongs to, when it was granted and when it expires, whether a second factor was confirmed, the reason it ended, and the address and browser the grant was made from. Two consequences of belongs to the session are worth stating:

  • It is not a property of the account. Another browser signed in as the same person is a different session and is not elevated by this grant.
  • A refresh of the elevation that arrives from a different address or browser than the grant was made from is treated as suspect and ends the elevation rather than extending it (refresh_from_other_pair). The grant is pinned to where it started.

The second factor#

When the second factor is on — COOLMS_ELEVATION_MFA, one environment switch, on by default — the code is required at every elevation, and the confirmed factor is what coolms:admin:credential registers. The factor's secret is sealed at rest with the installation's master key. If that key is missing or does not open the secret, elevation does not silently proceed without a factor and it does not fail obscurely: it answers 409, and the elevation state names which of the reasons applies — no key, a malformed key, a secret that does not open under the current key, or a secret stored before encryption at rest was added. An unreadable second factor is a stated conflict, not a bypass.

What the person elevating reads is about their own account, in plain words: no password of its own, no confirmed second factor, or a factor this server cannot read. It names no setting and no server command; how those are changed is the operator's to know.

Turning the factor off is possible, and it is an environment decision. The operator is told about it, not the person elevating: the doctor's Elevation second factor row says whether the factor is on, and which effective administrators have a confirmed factor this server can read. While it is off, the row says what to do before turning it on: register each administrator's own factor with coolms:admin:credential <account> first, because with none registered, turning it on means nobody can elevate. While it is on, an administrator without one is a finding.

Ending it#

An elevation ends for one of these reasons, and the client is told which so it can say so plainly:

reason what happened
expired the fixed lifetime ran out
dropped_by_user the person ended it themselves, from the badge
closed the last admin tab closed or reloaded
refresh_from_other_pair a refresh came from a different address or browser than the grant
never no elevation has been granted in this session

A badge shows the end time while a session is elevated — the time it runs out, not a counting-down remainder — and it is also the control that ends the elevation early. Ending it early and letting it expire reach the same state; the only difference is the reason on the row.

Enforced, or only watched#

Whether a gate's elevation answer actually decides is the deployment's choice, COOLMS_ELEVATION_MODE, read once when the system starts:

  • enforce — the production posture. A member who is not elevated is refused at the gate and offered elevation.
  • log_only — membership still decides, exactly as before elevation existed, and every place where the elevation answer would have refused is counted. An installation runs this to watch the narrowing before living under it. coolms:elevation:shadow-report reads that count.

A non-member is refused in both modes; there is nothing to rehearse for someone who was never going to pass. Where this switch lives among the platform's other kinds of configuration — and why it is a restart to change rather than a screen — is on the Settings page.

In one sentence#

A member proves they may, the session is marked elevated until a fixed time it was told at the start, the mark expires on its own, and every step of it is a row you can read afterwards.