Skip to content

Positions & terminals — the concepts

The Positions & shared terminals page is the admin workflow (click here, enable that). This page explains the model behind it — what the building blocks are, how they connect, and how it feels in daily use. Protocol details live under Integrate → Position terminals.

The four building blocks

Two of them live in Modgud, two in the real world:

PeopleAnna, Ben, Carla …ordinary user accountsPositionthe post: "gate","control room", "reception"Terminalthe device slot at theposition: "left terminal"Devicethe physical hardwarestanding at the postreal worldin Modgud

The position is the star of the model: a business role staffed by changing people. It receives rights through the ordinary groups & roles machinery, but it never signs in — it gets activated (more on that below). For downstream systems, the gate acts — never Anna or Ben.

The whole system is three links between those blocks. Each has its own moment, its own flow — and answers a different question.

PersonPositionTerminalDevice① "may staff"changeable any time, per person② "the position may run here"created when you add the terminal③ "this device is it"at installation, exactly once
LinkQuestion it answersWhen & how
① Person ↔ PositionWho may staff this post?A simple list on the position ("authorized users"). Grant, suspend, revoke — takes effect immediately.
② Terminal ↔ PositionWhere may this post be staffed?An authorization assignment. One terminal may carry several positions, selected for each shift.
③ Device ↔ TerminalWhich hardware actually stands there?At installation, exactly once. DPoP pins a device key, client-secret identifies its holder, while none deliberately leaves this link unproven.

Mnemonic

Link ① says who, ② says where, ③ says with what. The daily unlock is not a fourth link — it is the moment all three are checked at once.

The realm security floor decides how strong links ① and ③ must be. A weaker position policy cannot silently undercut that floor.

For engineers: ① is the grant, ② is the terminal slot with its auto-created OAuth client, ③ is the enrollment (device key binding). The client appears in the OAuth grid as inventory only — everything is managed in the position.

A position is not a group

The most tempting confusion — and the most important distinction in the model:

The one-liner

A group distributes rights. A position acts.

  • Group "porters" with Anna as member: rights flow to the person. Anna acts, under her own name, with the group's rights. The group itself never appears at runtime — no tokens, no sessions. It is a distribution mechanism.
  • Position "gate" with Anna authorized: rights never flow to Anna! The grant gives her no right of the gate — only the ability to switch the gate on. Then the gate acts, with its rights. Anna's own permissions are irrelevant during the shift.

The authorized-users list looks like membership but is a key cabinet: "these people may start the engine", not "these people are the engine". And the two concepts stack instead of competing — the position receives its own rights through groups, like any other principal.

Same person, two devices, two actors

Annaone humanSecured terminalAnna unlocks → the actor is"the gate"✓ acknowledge alarms✓ operate barriers✓ keep the watch logrights of the POSITIONHer PC, 1 m awayAnna signs in → the actor is"Anna"✓ read e-mail✓ time tracking✗ no barriers, no alarmsrights of the PERSON

This is why the terminal is hardened more than the PC next to it: it is the vessel for the post's rights, which can exceed those of any single person in front of it. Security scales with the position's rights, not the person's. The inverse exists too — a kiosk position can deliberately hold fewer rights than the human in front of it.

A position never authenticates — it gets activated

A position has no login credential of its own (that is the difference to a service account, which identifies itself, from anywhere). Every position token starts with an allowed activation proof — a person proving themselves or a position-owned hardware token — at an enrolled terminal. The chain is strict:

Position → terminal assignment → enrolled device → allowed activation proof → session

No slot → no device → no unlock → never a token. A position without terminals is valid, but dormant: configuration waiting for hardware.

A shift at the gate

  1. 06:02 — Anna taps. Modgud checks all three links at once: is this the real device (③)? may the gate run here (②)? may Anna staff the gate (①)? → unlocked. From now on the terminal acts as the gate.
  2. Handover: Ben taps → Anna's shift ends automatically, his begins. Exactly one shift runs per terminal at any time.
  3. Locking: at the device, or remotely by an admin (force-lock, effective immediately — terminal tokens are revoked on the spot).
  4. Time limits: every shift ends at the configured ceiling at the latest (default 16 h, absolute maximum 24 h), even if nobody locks.
  5. Cascades: deactivating Anna, revoking her grant, disabling the slot or the position — each ends the affected running shift automatically.

What the audit attests — and what it doesn't

The staffing audit attests the unlock, not each action:

06:02  gate / left terminal unlocked by Anna
07:15  alarm #4711 acknowledged by "the gate"
14:01  handover: Anna's shift ended, unlocked by Ben
17:40  force-lock by admin — terminal locked

Who actually clicked the alarm at 07:15 is not recorded — if Anna was on a break and a colleague clicked, the log still shows Anna's shift. That is not a gap; it is the nature of every shared device. What the model guarantees: only authorized people can unlock, and who unlocked is cleanly recorded. Accountability is session-level, not action-level. For a critical action, the consumer can request a fresh step-up proof. Modgud then returns a separate access token valid for at most 60 seconds; it may be bound to an action and consumer nonce and is intended to be consumed once by jti.

Which principal for which job?

If …… then
a person acts and must appear in the business data (receipt, ticket, signature)ordinary user login — also on a shared device, with fast switching
a post acts that has to be activated (gate, control room, reception)position + terminals — this model
a machine acts, with no human activation at all (sealed appliance, server job)service account

The test question in one sentence: "Who owns what the system does — the person, the post, or the machine?" One concept per answer, and no fourth is needed. (A group is none of the three — it distributes rights, it never acts.)

Policy choices and guard rails

How people and devices prove themselves is a per-position policy. Multiple activation classes can be enabled together; DPoP + personal passkey remains the recommended default.

  • Activation proof: personal passkey, personal password, personal e-mail OTP, or a position-owned activation token. The token is a logical, individually revocable object with an RP-bound WebAuthn credential; the audit names the token rather than a person. team-secret is reserved for a future feature and is deliberately unavailable today.
  • Device binding: DPoP key, client secret, or none. Client-secret and none still run the complete admin-approved Device Flow; none only removes a cryptographic device identity and is appropriate only where the physical and network controls justify it.
  • Realm guard rails: the realm declares required proof and binding capabilities. Tightening a floor first previews affected positions and, when confirmed, immediately ends sessions that no longer comply.
  • Multi-position terminals: one device may serve several positions ("reception" by day, "night gate" after hours). New assignments are fixed before enrollment; adding one later requires a replacement slot and fresh approval. Exactly one active shift still exists per terminal.

Released under the Apache-2.0 License.