Skip to main content

Roles

Every account is an admin or a member. Admins bypass grant resolution entirely — they can reach every credential, set, host and group, and they are the only ones who can invite people, change roles, manage users, and review permission requests and rotation reviews. Members start with nothing and act through grants. That asymmetry is the point: admins grant, members exercise.

Inviting someone

This emails a single-use link. The recipient sets their own name and password through POST /invitations/accept, which creates the user, their password identity, and marks the invitation accepted in one transaction — so a half-created account is not a state you can land in. GET /invitations lists the pending ones. Two ways to retract or refresh:
Invitations need CUSTOS_APP_URL set, or there is no origin to build a link against and the endpoint returns 503. In development without RESEND_API_KEY, the link is printed to the control-plane logs instead of emailed.

Changing a role

Two guards: you cannot change your own account, and you cannot demote the last active admin. The second one stops an install from ending up with nobody able to administer it.

Suspending and removing

Suspension is the reversible one.
It kills their sessions and pushes fresh authorized-key snapshots to every affected host, so SSH stops too, not just the API. That works because the snapshot query filters on active user status — sshd never goes through the API’s auth middleware, so the snapshot is the only thing that can enforce it. POST /users/{id}/activate reverses it. Removal is for people who are gone for good:
It deletes their login identities and revokes every grant and session, but keeps the user row, their SSH keys and their log entries. Deleting those would quietly rewrite history: audit entries would lose the name attached to them. The account is marked removed instead. Neither action lets you target yourself.

Rotation reviews

Suspending or removing someone raises a credential rotation review: a checklist of the credentials that person could reach, so somebody decides what actually needs rotating. Cutting access does not un-know a password they already read.
Work through it per credential — PATCH /credential-rotation-reviews/{id}/items/{itemID} with rotated or dismissed — or close the whole review with POST /credential-rotation-reviews/{id}/resolve. Every active admin except the one who triggered it is notified.

Offboarding checklist

  1. POST /users/{id}/suspend — immediate, reversible, cuts API and SSH together.
  2. Work the rotation review that suspension raised.
  3. DELETE /users/{id} once you are sure, keeping the audit trail intact.
  4. Check GET /grant-audit if you need to show what they had and when it ended.