User Management
User management is where you add people to your tenant, set what they can do by assigning a role, and remove them when they leave. Each person's access to a tenant is a membership: a link between a user and a tenant that carries exactly one role. A single user can hold memberships in several tenants (for example a parent tenant and its children), each with its own role.
The membership list lives at /admin/members. Inviting, changing roles, and revoking all happen here.
Who can manage users. Managing users requires user-management capabilities (user.invite, user.view, user.assign_role, user.revoke_membership). These belong to the user_admin, builder_admin, and system_admin roles. See Governance and permissions.
The members page
Open /admin/members to see everyone with a membership in the current tenant. The table shows each member's name and email, their role (as an inline dropdown), whether this tenant is their home tenant, and when the membership was created. The list is paginated and searchable — typing in the search box filters by name or email across the whole tenant, not just the current page.
A member's home tenant is the one their account is anchored to. It matters when revoking — see Revoking a membership.
Inviting a user
Select Invite member to open the invite dialog. Enter the person's email address; as you type, Ema looks up whether that email already exists in your tenant subtree and adapts the form:
- Already in your tenant tree. If the email belongs to a user who already has a membership somewhere in your tenant or its children, Ema only needs to create the membership here. You pick a role and send — name and password are ignored because the identity already exists.
- New to your tenant tree. If the email is unknown, the form asks for a display name. When the tenant uses password sign-in (rather than SSO), it also asks for an initial password. Ema creates the user account and a home membership in your tenant in one step.
- Already a member of this tenant. If the user already has a membership in this exact tenant, the invite is rejected with an
already_memberconflict.
Pick a role from the dropdown — only roles you are allowed to assign are selectable (see role assignment rules) — and confirm.
Email domain gate
The invitee's email domain must be claimed by your tenant or one of its ancestor tenants. If it isn't, the invite is rejected with invitee_domain_not_allowed. This gate applies to everyone, with no role-based bypass. Claim the domain first under email domains, then retry the invite.
Inviting into a child tenant
If you administer a parent tenant, you can add a user to one of its child tenants without switching context. The same dialog is used; the membership is created in the child tenant instead of your current one. This requires the tenant.view_children capability.
How invited users sign in
How a new user first signs in depends on the tenant's sign-in method:
- SSO tenants. The user signs in through your identity provider; their role on first sign-in comes from the SSO default role unless you invited them with an explicit role. See Tenant management and SSO.
- Password tenants. The user signs in with the email and initial password set at invite time.
Assigning and changing roles
A member's role is shown as a dropdown directly in the members table. Pick a new role to change it immediately — there is no separate save step. Ema records the change in the audit log as user.role_changed.
Each membership carries one role. Changing a role replaces it; roles are not additive.
Role assignment rules
You can only assign a role whose capabilities are a subset of your own. The platform enforces this on both invite and role change: if the target role includes any capability you do not hold, the assignment is rejected. In practice:
- A
user_admincan assignuser,user_admin,builder(only if they also hold builder capabilities), andno_access, but notbuilder_adminorsystem_admin. - A
builder_admincan assign anything up tobuilder_admin. - A
system_admincan assign any role.
In the role dropdown, roles you cannot assign are disabled. This prevents privilege escalation — no admin can grant access beyond their own.
Revoking a membership
To remove someone from a tenant, open the actions menu on their row and select Revoke. The revoke dialog adapts to the member's situation:
- Cascade. If the user also holds memberships in child tenants below the current one, you can check cascade to revoke those in the same operation. The dialog lists which child tenants would be affected.
- Home-tenant warning. If you are revoking the user's home membership, the dialog warns you. When the user has other memberships, one is promoted to home automatically.
- Last membership. If this is the user's only membership anywhere, revoking it deactivates their account. The dialog warns you before you confirm.
The result reported back is authoritative — the success message reflects what actually happened (revoked, home changed, or account deactivated), which can differ from the prediction when the user holds memberships in ancestor tenants the dialog can't see.
You cannot revoke your own home membership in the tenant you are currently in; revoking another user's home is always allowed.
Reference: endpoints
User management is backed by the auth service. The capability that gates each route is noted.
| Action | Endpoint | Capability |
|---|---|---|
| List memberships (with search) | GET /memberships?q= | user.view |
| Invite a user into the current tenant | POST /memberships | user.invite |
| Invite a user into a child tenant | POST /tenants/{id}/memberships | user.invite + tenant.view_children |
| Look up an email in the subtree | GET /memberships/lookup-email | user.invite |
| Change a membership's role | PUT /memberships/{id} | user.assign_role |
| Revoke a membership | DELETE /memberships/{id} | user.revoke_membership |
| List a user's memberships in your subtree | GET /users/{id}/memberships | user.view |
A membership returned by these endpoints looks like this:
{
"id": "8b1f...",
"user_id": "3c92...",
"tenant_id": "a07d...",
"role_id": "1f44...",
"role_name": "builder",
"is_home": true,
"created_at": "2026-05-30T14:22:10Z",
"updated_at": "2026-05-30T14:22:10Z"
}
What's next
- Governance and permissions — what each role can do.
- Tenant management and SSO — configure sign-in and claim email domains.
- Audit log — review invites, role changes, and revocations.