Quoin docs

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

RoleView flags & reportsEdit rules & rolloutsStart / stop / conclude experimentsManage API keys & membersDelete workspace & billing
vieweryes––––
editoryesyesyes––
adminyesyesyesyes–
owneryesyesyesyesyes

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.

On this page