Users and Roles
Every user other than root holds a role. A role decides what that user can see and change; nothing else does. A Slot’s roles are rows you create, rename, edit and delete, the same way you manage users, stations and tasks.
Every Slot has exactly one root user, created with the Slot:
- Name fixed. root’s user name is always
root, and nothing changes it. No other user in the Slot can be namedroot,RootorROOTeither — the name is unique regardless of case. - Full access. root can see and do everything in the Slot, on every row — including a row another user created.
- Not a role you assign. No command turns an existing user into root, and none creates a second one: there is always exactly one.
- Its own password. root’s password is set by root, either in the Slot itself or from nonbl.com. No other user, whatever their role, can set it.
Seeded roles
Section titled “Seeded roles”A new Slot seeds two roles, ready to use or to change:
| Role | Baseline |
|---|---|
| Administrator | all |
| Operator | standard |
Both are ordinary rows: rename either one, change what it holds, or delete it once no user holds it — a Slot needs at least one role before it can add a user other than root. Nothing is special about these two beyond having been there from the start.
Baselines and overrides
Section titled “Baselines and overrides”Every role has a baseline. The baseline answers for every permission the role has no override for — including a permission an extension you install later declares. There are three:
| Baseline | Gives |
|---|---|
| none | Nothing. |
| standard | View and Change on every row. Manage on something that has an owner: only the rows the caller created. Manage on something with no owner: nothing. |
| all | Everything, on every row. |
An override replaces the baseline for one permission: set it to None, Own (offered only where that permission has an owner) or Any, and that one permission stops following the role’s baseline. A role can hold any mix of overrides — including none at all.
A role automatically covers a new extension. Because the baseline answers for anything without an override, a role with baseline standard or all already reaches whatever permissions an extension you install tomorrow declares — nothing about the role needs editing. A role built entirely out of overrides on today’s permissions (baseline none, everything set by hand) sees nothing from that new extension until you add an override for it.
The Permissions editor
Section titled “The Permissions editor”Editing a role — Add Role, Edit Role, or New Role From an existing one — shows one row per permission the Slot’s extensions and stations declare, grouped by the extension that declares it. Each row shows:
- the permission’s name and whether it can be scoped to Own rows;
- what the role’s saved baseline gives it, naming the baseline — for example “standard gives Own”. This text describes the baseline as it was last saved, not the value currently sitting in the Baseline field: change Baseline and the rows keep showing the saved baseline’s text until you save the role and open it again;
- the row’s override, or Baseline when none is set, and the choices offered for it — a row with no owner never offers Own.
Two rows are special:
- Declarations differ. A station may run a version of an extension that declares a permission at a different level, or with different ownable-ness, than another station or the Slot’s own copy. Such a row is marked “declarations differ”, shows what each distinct declaration gives, and offers Own only when every declaration has an owner. Saving a value the row does not offer refuses the save.
- Not currently declared. An override on a permission no running extension declares right now — left over from an extension the Slot no longer runs, or from a station that has been deleted. A station that is only offline still counts: its permissions stay declared. Such a row is marked “not currently declared”. On Edit Role it offers only Baseline (remove the override) and its stored value; saving anything beyond those two is refused. On Add Role and New Role From, a non-root caller also sees None and their own reach there, so they can save a role that matches their own overrides on such permissions — which the subset rule requires.
One Save commits the whole role: the name, the baseline, the dry-run flag and every override together.
An override keeps the level it was granted at
Section titled “An override keeps the level it was granted at”A permission is declared at a level — View, Change or Manage — and an override grants what it granted on the day you saved it. The Slot records the level each override was saved at. If an extension later declares that permission at a higher level, the override grants nothing there: Any saved for a View permission never quietly becomes Any on a Manage one. A declaration at the same or a lower level still honours the override.
Such a row carries the note “declared at a higher level since this was saved”, and the Slot logs a warning naming the role and the permission. The role’s holders are refused that permission until you decide.
Saving a role re-grants each override at its permission’s current level — the highest level the permission is currently declared at; a “not currently declared” row keeps the level it was granted at. To grant a flagged override at that level, review the row and save the role: the note clears, and, because what the role grants changes, every user holding it is signed out. One exception keeps a save from taking anything away: an override whose value the save leaves unchanged keeps the level it was granted at when that is higher than the current one. So after a permission’s level moves down, a save — a rename, say — leaves the override’s grant, and its holders’ sessions, as they were.
Example: a salary table only HR can see
Section titled “Example: a salary table only HR can see”An extension that keeps a salary table declares a permission for viewing it and a separate one for editing it. Viewing is a View permission, and both the standard and the all baseline give a View permission Any — so a role left on its baseline sees the table. Keeping it to HR takes two steps:
- the HR role reaches “view salaries” at Any, from its baseline or from an override;
- every other role whose baseline is standard or all — Operator and Administrator included — gets an override of None on “view salaries”. A role with baseline none already reaches nothing there and needs no override.
Then only users holding the HR role, and root, ever see that table, however their role’s baseline reads on everything else. A role you add later with baseline standard or all sees salaries until you give it the same None override.
Example: a write-only automation role
Section titled “Example: a write-only automation role”A role with baseline none and a single override of Any on the permission that changes prices holds Change there and nothing else — including no View at all. An automation account built this way can save price updates it can never list or read back through the client. Saving a row you cannot view is not a mistake the Slot corrects for you: it is what a write-only role is for.
The subset rule
Section titled “The subset rule”A non-root caller who can manage roles or users acts only within their own role. Concretely, whatever they touch — the role being saved, the role a user is being assigned, the role a target user currently holds — must stay within their own role: no stronger baseline, and no permission reached further than their own role reaches it, comparing what each role actually grants, permission by permission, whether that comes from an override or, absent one, from the baseline itself, on both sides.
This lets a caller create a role, or assign a user, that reaches less than their own role does — but never more. An HR lead who can manage users, but whose own role reaches no further than HR’s data, can add HR staff and give them a role no stronger than the HR lead’s own — but cannot create, rename, re-role, disable or delete an Administrator.
What this hides, and what it does not. Only the Roles list, the Role detail pane, and the Role field’s offered choices on the Users forms are filtered for a non-root caller — none of them shows a role stronger than the caller’s own, so there is nothing to click on, or to assign, beyond it. The Users list is not filtered. It shows every user in the Slot, Administrators included, each with their actual role name. A non-root caller can open Edit, Disable or Delete on any of them — it is the server that refuses an action on a user whose role is not within the caller’s, the same way it refuses any other save or action outside the subset rule.
Root is never bound by the subset rule: it is the only caller who can grant more than it itself holds, because it holds everything already.
The Roles list stays current. Every role save or delete, and every user command that changes who holds a role, refreshes the Roles list — so its rows, and its count of users per role, are always up to date without needing a manual reload.
Changing what a role holds signs its holders out
Section titled “Changing what a role holds signs its holders out”Saving a role that changes what it grants — its baseline, its dry-run flag, or any override — signs out every user currently holding it, the editor included if they hold it themselves. Their next sign-in picks up the new grants; nothing changes underneath a session already open. Renaming a role signs no one out — a name is not something a role grants.
Assigning a user a different role signs that user out, whatever the new role grants relative to the old one. Their next sign-in picks up the new role’s grants.
Deleting a role
Section titled “Deleting a role”A role can be deleted only once no user holds it. Move every holder to a different role first (or delete those users), then delete the role. Root can delete every role, and every user other than its own row — root’s own row can never be deleted; at that point, adding a user again needs a role to exist first.
Delete User
Section titled “Delete User”Deleting a user needs its own permission, separate from managing users, the way any action that cannot be undone does. Delete User:
- refuses to delete root;
- refuses to delete the account you are currently signed in as;
- ends the deleted user’s sessions immediately.
Dry run
Section titled “Dry run”A role can be marked dry run. Reading still works, so a dry-run user can open every list, form and detail pane, and every button is there to press, but nothing it does ever changes the Slot’s data. A save or action from a dry-run role is checked as a real one would be, and reports the same errors — a name already taken, a role still held. One that would succeed changes nothing and says “Dry run: nothing was changed”. Deploying, running and stopping tasks are refused, and so are enabling, disabling and deleting extensions. The demo Slot has a Demo role, with baseline all and dry run set, so a visitor exploring it can reach anything in the product without being able to change anything in it.
Plan limits
Section titled “Plan limits”A Slot’s owner can cap how many users and how many roles a Slot may hold —
users.maxUsers and roles.maxRoles in slotd.conf; the seeded roles
count toward the roles cap the same way root counts toward the users cap.
Both are unset, and so unlimited, on every plan except the Free plan, which
allows root only: users.maxUsers is 1 there, so no other user can be
added.