Mailmus

Roles and permissions

Decide what each person can do in your application, across your whole project or inside each company, and ask Mailmus before acting.

Your server asks one question before it acts: can this person do this? Mailmus answers with a yes or a no, and says why.

It works the same whether you sign people in with Mailmus Auth or on your own, and whether or not you use organizations.

How it fits together

  • A permission is something a person can do in your application, written resource:action, for example invoice:create.
  • A role groups permissions. It has a scope:
    • a project role is given to a person, for your whole application (support, analyst);
    • an organization role is given to a member, inside one company (billing).
  • A person can have several roles. Their access is everything their roles allow together.

A project role never gives access inside an organization, unless you mark it as applying to all organizations. That is how your own support team can help every company without being added to each one.

Declare your permissions and roles

const api = `https://api.mailmus.app/projects/${projectId}`;
const headers = { Authorization: `Bearer ${secretKey}`, "Content-Type": "application/json" };

await fetch(`${api}/access/permissions`, {
  method: "POST",
  headers,
  body: JSON.stringify({ key: "invoice:create" }),
});

await fetch(`${api}/access/roles`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    key: "billing",
    name: "Billing",
    scope: "ORGANIZATION",
    permissions: ["invoice:create"],
  }),
});

A role that is still given to someone cannot be deleted: remove it from those people first, so that nobody loses access without their session knowing.

Give roles

To a person, for your whole project:

// PUT /projects/{projectId}/customers/{id}/roles
// { "roles": ["support"] }

To a member of an organization:

// POST /projects/{projectId}/b2b/organizations/{id}/members
// { "externalUserId": "user_8291", "roles": ["org:admin", "billing"] }

// PATCH /projects/{projectId}/b2b/organizations/{id}/members/{membershipId}
// { "roles": ["org:member"] }

Changing someone's roles signs out their current Mailmus sessions, so their next token reflects the change.

Check access

const res = await fetch(`${api}/access/check`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    externalUserId: "user_8291",
    organizationExternalId: "cus_acme",
    permission: "invoice:create",
  }),
});
const { allowed, reason, roles } = await res.json();

Identify the person with customerId or with your own externalUserId. Leave out the organization to ask about your whole project.

A refusal is a normal answer, not an error: allowed is false and reason tells you why. Add "explain": true to get each step of the decision.

To answer "why can't Sophie refund this invoice?" without writing code, open Check access in Auth → Roles & permissions or B2B → Access, or use Explain on a Customer or on an organization member. The dashboard asks the same question your server does and shows each step of the answer.

reasonMeaning
PROJECT_ROLEAllowed by one of the person's project roles.
ORGANIZATION_ROLEAllowed by one of the member's roles in this organization.
PROJECT_ROLE_ALL_ORGANIZATIONSAllowed by a project role that applies to all organizations.
NO_ROLE_GRANTSNone of the roles considered includes this permission.
UNKNOWN_PERMISSIONThis permission was never declared in the project.
CUSTOMER_NOT_FOUNDNobody with this ID in the project.
NOT_A_MEMBERThe person does not belong to this organization.
MEMBERSHIP_SUSPENDEDThe person's membership in this organization is suspended.
ORGANIZATION_NOT_FOUNDNo organization with this ID in the project.
ORGANIZATION_SUSPENDEDThe organization is suspended.
ORGANIZATIONS_DISABLEDOrganizations are turned off for this project.

Built-in organization roles

Every project that uses organizations has three roles you cannot delete:

RoleCan
org:ownerEverything below, and transfer ownership.
org:adminInvite people, remove members, change members' roles.
org:memberNothing by default.

You can add your own permissions to them. The permissions that start with mailmus: belong to Mailmus and stay on these roles. Role keys that start with org: are reserved for them.

An organization always keeps at least one org:owner.

In the session token

If you sign people in with Mailmus Auth, the token carries roles (the person's project roles) and, when an organization is active, orgId and orgRoles (their roles in that organization, such as ["org:admin", "billing"]). orgRole (OWNER, ADMIN or MEMBER) is still there for existing integrations; prefer orgRoles. They are a snapshot taken when the token was issued: to decide on something that matters, use the access check.

Next

On this page