Better Auth in Rust

Organization

Multi-tenancy with organizations, members, invitations, and RBAC.

The OrganizationPlugin provides multi-tenancy support with organizations, membership management, invitation workflows, and role-based access control (RBAC).

Setup

These examples assume you've already defined AppAuthSchema. If you want a complete setup from entity definitions through Axum mounting, start with the Axum integration guide.

use better_auth::plugins::OrganizationPlugin;

let auth = BetterAuth::<AppAuthSchema>::new(config)
    .store(store)
    .plugin(OrganizationPlugin::new())
    .build()
    .await?;

Configuration

use better_auth::plugins::organization::OrganizationConfig;

let auth = BetterAuth::<AppAuthSchema>::new(config)
    .store(store)
    .plugin(
        OrganizationPlugin::new()
            .allow_user_to_create_organization(true)
            .organization_limit(5)
            .membership_limit(50)
            .creator_role("owner")
            .invitation_expires_in(172800) // 48 hours
            .invitation_limit(100)
    )
    .build()
    .await?;
OptionTypeDefaultDescription
allow_user_to_create_organizationbooltrueAllow users to create organizations
organization_limitOption<usize>NoneMax organizations per user
membership_limitOption<usize>Some(100)Max members per organization
creator_roleString"owner"Role assigned to organization creator
invitation_expires_inu64172800 (48h)Invitation expiration in seconds
invitation_limitOption<usize>Some(100)Max pending invitations per org
disable_organization_deletionboolfalsePrevent organization deletion

Configure invitation delivery with OrganizationPlugin::custom_send_invitation_email(Arc<dyn SendInvitationEmail>). Implement SendInvitationEmail::send using the invitation, organization, member, and inviter in InvitationEmail. The plugin logs delivery failures and still returns the stored invitation, matching upstream behavior.

Inviting an email with a pending invitation returns USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION. Send resend: true to renew that invitation and send the email again. Resending preserves the invitation ID, role, and original inviter.

RBAC (Role-Based Access Control)

Default Roles

RoleOrganizationMemberInvitationAPI key
ownerupdate, deletecreate, update, deletecreate, cancel—
adminupdatecreate, update, deletecreate, cancel—
member————

The apikey resource governs organization-owned keys from the API Key plugin. Matching upstream, no default role is granted any action on it; the creator role (creator_role, "owner" by default) is allowed everything implicitly, and other roles need an explicit grant through a custom role.

Custom Roles

Extend the default roles with custom permissions:

use better_auth::plugins::organization::config::{OrganizationConfig, RolePermissions};
use std::collections::HashMap;

let mut roles = HashMap::new();
roles.insert("editor".to_string(), RolePermissions {
    organization: vec!["read".to_string()],
    member: vec!["read".to_string()],
    invitation: vec![],
    api_key: vec!["read".to_string(), "create".to_string()],
});

let config = OrganizationConfig {
    roles,
    ..Default::default()
};

let auth = BetterAuth::<AppAuthSchema>::new(auth_config)
    .store(store)
    .plugin(OrganizationPlugin::with_config(config))
    .build()
    .await?;

Resources and Actions

Resources: organization, member, invitation, apikey

Actions: create, read, update, delete, cancel

API Endpoints

For full request/response details, see the OpenAPI Reference.

Organization CRUD

EndpointMethodDescription
/organization/createPOSTCreate a new organization
/organization/updatePOSTUpdate organization details
/organization/deletePOSTDelete an organization
/organization/listGETList user's organizations
/organization/get-organizationGETGet organization metadata without members or invitations
/organization/get-full-organizationGETGet organization with members and invitations
/organization/check-slugPOSTCheck slug availability
/organization/set-activePOSTSet active organization on session
/organization/leavePOSTLeave an organization

Member Management

EndpointMethodDescription
/organization/get-active-memberGETGet current member record
/organization/get-active-member-roleGETGet the current member role
/organization/list-membersGETList organization members (with pagination)
/organization/remove-memberPOSTRemove a member (requires member:delete)
/organization/update-member-rolePOSTUpdate member role (requires member:update)

Invitations

EndpointMethodDescription
/organization/invite-memberPOSTInvite a user by email
/organization/get-invitationGETGet invitation details
/organization/list-invitationsGETList organization invitations
/organization/list-user-invitationsGETList invitations for current user (requires a verified email)
/organization/accept-invitationPOSTAccept an invitation
/organization/reject-invitationPOSTReject an invitation
/organization/cancel-invitationPOSTCancel an invitation (requires invitation:cancel)

Permission Check

EndpointMethodDescription
/organization/has-permissionPOSTCheck if user has specific permissions

Errors

StatusCondition
400Invalid slug format or missing required fields
403Insufficient permissions for the operation, or EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION when listing invitations with an unverified email
404Organization, member, or invitation not found
409Slug already taken or user already a member

On this page