Members
Roles and the permission matrix, inviting a teammate, and what happens when someone is removed.
A workspace has one shared permission matrix and four roles. Quoin checks every write against the matrix in one shared function. The write can be a flag edit, a change to the lifecycle of an experiment, or a member invite. Quoin never duplicates the check for each endpoint.
Built end to end
The tables, the roles API and the security guarantees on this page are real, tested code as of QN-11a. The
Members & roles screen (/settings/members), the invite-your-team onboarding step (/invite-team) and the
accept-invite page (/invite/:token) are also real, tested screens. They are built on top of the same API that this
page describes.
Roles
| Role | View flags & reports | Edit rules & rollouts | Start / stop / conclude experiments | Manage API keys & members | Delete workspace & billing |
|---|---|---|---|---|---|
| viewer | yes | – | – | – | – |
| editor | yes | yes | yes | – | – |
| admin | yes | yes | yes | yes | – |
| owner | yes | yes | yes | yes | yes |
Some changes touch the owner role itself: promote someone to owner, demote an owner, or remove an owner. For these
changes, the caller must already be an owner. The same shared function checks this. An admin can manage keys and
members. An admin cannot create a second owner.
Inviting someone
An invite is a members row with no joinedAt yet. It points to a user row. Quoin creates that row for the invited
email if it does not already exist. The invited person claims the row at the moment that they sign in with that
address. Nothing that is pending authorises anything before that.
- Invites have a rate limit of 20 each hour, for each workspace. The limit is not for each caller. Two admins in the same workspace share the bucket. A resend of an invite counts against the same bucket.
- An invite link is good for 7 days and single-use. If the invited person accepts the invite, or if someone revokes it, the link becomes invalid immediately. Quoin keeps an expired invite in the pending list. It does not delete it. A resend of the invite re-arms the same row.
- If you invite an address that is already a member, Quoin refuses with
"<email> is already a member.". If you invite an address that already has a pending invite, Quoin refuses with"<email> already has a pending invite. Resend it from the list below."
Removing someone
Removal of a member is immediate. Quoin deletes the operator-scope API keys of the member for this workspace (the
CLI keys of each member) in the same atomic write as the removal itself. Quoin does not soft-revoke them. An operator
key belongs to a membership, and a key with no member has no one to be "yours" to. Quoin also signs the member out
everywhere. There is one exception. If the member is still a joined member of another workspace, the session survives.
Only the access of the member to this workspace ends. A workspace always keeps at least one owner. The server refuses
the removal or demotion of the sole owner. This is true whether or not the request came from a disabled button.
What removal does not do
The removal of a member does not revoke the knowledge that the member has of a shared client or server
environment key. Those keys belong to an environment, not to a member. Today, the rotation of the environment keys
that a departing member knows is a manual offboarding step. It is not automatic.