Access and roles
How a person gets a staff role, what each role may do, and how access is removed.
Staff access is a role on a normal Cyrqle account.
Before you start
- Only a superadmin can grant or change a staff role.
- The person must already have a Cyrqle account and have signed in once.
- Every role change needs a written reason. It is recorded permanently.
The four staff roles
The customer role is user. Everyone who signs up gets it. The four staff roles sit above it.
| Role | What it is for | One-line meaning |
|---|---|---|
| support | Tier-1 support | Read-only on every workspace, plus every licence lifecycle action |
| data-ops | Data operations | Support, plus cluster reseed, attribution override, session revoke, paid creator refresh, embedding runs |
| superadmin | Platform owner | Everything, including workspace suspension, account deletion, impersonation and creator erasure |
| admin | Alias | An exact alias for superadmin. It is not a weaker role |
- The admin role is not a middle tier. It grants the same access as superadmin. Do not hand it out as a compromise.
- support currently holds every licence action, including suspend and change plan. A tier-1 agent can suspend a paying customer's licence. Treat licence changes as a tier-1-reachable action until this policy changes.
Capability matrix
Access is checked per capability, written as resource:action, not per rank.
The console renders this matrix live at
/admin/users/roles, computed by the
same check the pages run. Use that page in training when someone asks "can
support do this".
| Capability | support | data-ops | superadmin / admin |
|---|---|---|---|
user:list, user:get | Yes | Yes | Yes |
user:create, user:update | No | No | Yes |
user:set-role | No | No | Yes |
user:ban | No | No | Yes |
user:delete, user:set-password | No | No | Yes |
user:impersonate | No | No | Yes |
session:list | Yes | Yes | Yes |
session:revoke | No | Yes | Yes |
session:delete | No | No | Yes |
workspace:read | Yes | Yes | Yes |
workspace:suspend, workspace:delete | No | No | Yes |
license:read | Yes | Yes | Yes |
license:suspend, license:reinstate, license:extend-trial | Yes | Yes | Yes |
license:change-plan, license:convert-mode, license:set-overrides | Yes | Yes | Yes |
license:issue-invoice, license:stripe-resync | Yes | Yes | Yes |
payout:read | Yes | Yes | Yes |
payout:reverse | No | No | Yes |
campaign:read | Yes | Yes | Yes |
attribution:read | Yes | Yes | Yes |
attribution:override | No | Yes | Yes |
cluster:read | Yes | Yes | Yes |
cluster:reseed | No | Yes | Yes |
embedding:read | Yes | Yes | Yes |
embedding:trigger | No | Yes | Yes |
creatorRefresh:trigger | No | Yes | Yes |
creator:read | Yes | Yes | Yes |
creator:erase | No | No | Yes |
opsConfig:read | Yes | Yes | Yes |
opsConfig:write | No | No | Yes |
audit:read | Yes | Yes | Yes |
adminSearch:run | Yes | Yes | Yes |
A few pages need only "any staff role" because they have no single subject: the overview, health, stats, analytics, the jobs list and the data spend page.
Granting staff access
There are two ways, and only two.
Find the person
Open /admin/users and search their email address. Click open.
Pick the role
In the set role panel, choose the role from the select.
Write the reason
Enter a reason in the field placeholdered "reason (required, written to audit log)".
Apply
Click apply. The change takes effect on their next page load.
The second way is the bootstrap list. A small number of account identifiers are listed in the deployment configuration and treated as superadmin whatever their role says.
A bootstrap superadmin cannot be removed from the console. No role change takes their access away. Removal needs an engineering change and a redeploy.
Removing staff access
Do all three steps. Two of the three leave the person with access.
Set the role back
Open their user page, set the role to user, and give the leaving reason.
Revoke their sessions
In the revoke sessions panel, give a reason and click revoke all. A signed-in tab keeps working until you do this.
Check the bootstrap list
Open /admin/users/staff. If the bootstrap ids tile is above zero, ask engineering whether the leaver is in it.
Nothing stops you demoting the last superadmin. The bootstrap list is the only recovery path. Keep at least one bootstrap identifier populated.
Step-up re-authentication
Six actions need a session that was created in the last 30 minutes:
- payout retry
- payout reversal
- workspace suspension
- workspace archiving
- account deletion
- setting a password for an account
The check reads when the session was created, not when you last used it. A tab left open all week is not fresh. The refusal reads: "This action needs a session established in the last 30 minutes. Yours is N minutes old, sign out and back in, then retry."
The only remedy is to sign out and sign back in. Cyrqle never shows a password box inside the app, because that is exactly what an attacker would show. Plan the sign-out before you start, not halfway through.
Both outcomes are recorded: the grant and the refusal.
What is recorded
The record is append-only. Nobody can edit or delete an entry.
| Recorded | Detail |
|---|---|
| Who | Your account, your address, your browser |
| What | The action, in the form resource.verb |
| Which record | The row you acted on, with its before and after state |
| Why | Your reason text |
| Reads | Every page load, including the search terms you typed |
A reason is required for every change. If you leave it blank the entry still gets written, marked as unspecified, and it is your name on it.
Pitfalls
- The apply button is disabled when the selected role equals the current role. You cannot re-apply the same role to leave a note. Use /admin/notes instead.
- Session revoke is granted to data-ops, not only to superadmin. That is looser than the rest of the destructive set. Use it for compromised credentials, not as a support habit.
- Staff accounts cannot be impersonated, and you cannot impersonate yourself. Both buttons are disabled with an explanation.