Organizations Plugin
Manage multi-tenant organizations, members and teams. Enables team collaboration, and email-based invitations.
Overview
The Organizations plugin provides multi-tenancy and team management capabilities. It enables users to create organizations, manage members with roles, organize members into teams, and send email-based invitations.
Core Entities
- Organizations: Owner-based organizational units
- Invitations: Email-based invitations for joining organizations
- Members: Users assigned to organizations with roles
- Teams: Group members into teams within organizations
- Team Members: Users assigned to teams within organizations
Features
- Multi-tenant organization management
- Role-based member management within organizations
- Team organization and management within organizations
- Email-based member invitations with configurable expiration
- Team member management
- Full lifecycle management (create, read, update, delete operations)
NOTE
This plugin has a dependency on the Access Control plugin for role-based access control. Make sure to configure the Access Control plugin to utilize all features of the Organizations plugin.
Configuration
Standalone Mode:
[organizations]
enabled = true
organizations_limit = 10 # Optional limit on number of organizations (set to 0 for unlimited)
members_limit = 100 # Optional limit on number of members per organization (set to 0 for unlimited)
invitations_limit = 100 # Optional limit on number of invitations sent to a user (100 by default)
invitation_expires_in = "24h" # Expiration time for organization invitations (24h = 1 day by default)
require_email_verified_on_invitation = true # Whether to require the invited user's email to be verified before accepting or rejecting an organization invitation (false by default)Library Mode:
import (
"time"
organizationsplugin "github.com/authula/authula/plugins/organizations"
organizationsplugintypes "github.com/authula/authula/plugins/organizations/types"
)
organizationsplugin.New(&organizationsplugintypes.OrganizationsPluginConfig{
Enabled: true,
OrganizationsLimit: 10,
MembersLimit: 100,
InvitationsLimit: 100,
InvitationExpiresIn: 24 * time.Hour,
RequireEmailVerifiedOnInvitation: true,
DatabaseHooks: &organizationsplugintypes.OrganizationsDatabaseHooksConfig{
// Optional database hooks for custom logic on organization lifecycle events
},
})API Reference
Organizations
| HTTP Method | Route Path | Description |
|---|---|---|
POST | /organizations | Create organization |
GET | /organizations | List user's organizations |
GET | /organizations/{organization_id} | Get organization |
PATCH | /organizations/{organization_id} | Update organization |
DELETE | /organizations/{organization_id} | Delete organization |
Invitations
| HTTP Method | Route Path | Description |
|---|---|---|
POST | /organizations/{organization_id}/invitations | Create invitation |
GET | /organizations/{organization_id}/invitations | List invitations |
GET | /organizations/{organization_id}/invitations/{invitation_id} | Get invitation |
PATCH | /organizations/{organization_id}/invitations/{invitation_id} | Revoke invitation |
POST | /organizations/{organization_id}/invitations/{invitation_id}/accept | Accept invitation |
POST | /organizations/{organization_id}/invitations/{invitation_id}/reject | Reject invitation |
Members
| HTTP Method | Route Path | Description |
|---|---|---|
POST | /organizations/{organization_id}/members | Add member |
GET | /organizations/{organization_id}/members | List members |
GET | /organizations/{organization_id}/members/{member_id} | Get member |
PATCH | /organizations/{organization_id}/members/{member_id} | Update member |
DELETE | /organizations/{organization_id}/members/{member_id} | Remove member |
Teams
| HTTP Method | Route Path | Description |
|---|---|---|
POST | /organizations/{organization_id}/teams | Create team |
GET | /organizations/{organization_id}/teams | List teams |
PATCH | /organizations/{organization_id}/teams/{team_id} | Update team |
DELETE | /organizations/{organization_id}/teams/{team_id} | Delete team |
Team Members
| HTTP Method | Route Path | Description |
|---|---|---|
POST | /organizations/{organization_id}/teams/{team_id}/members | Add member to team |
GET | /organizations/{organization_id}/teams/{team_id}/members | List team members |
GET | /organizations/{organization_id}/teams/{team_id}/members/{member_id} | Get team member |
DELETE | /organizations/{organization_id}/teams/{team_id}/members/{member_id} | Remove member from team |
Database Schema
This plugin creates the following database tables:
Table: organizations
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the organization |
owner_id | string | FK | Reference to the organization owner (user) |
name | string | - | Organization name |
slug | string | - | URL-friendly organization identifier (unique) |
logo | string? | - | Organization logo URL |
metadata | JSON | - | Additional organization metadata |
created_at | timestamp | - | Record creation time |
updated_at | timestamp | - | Record last update time |
Table: organization_invitations
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the invitation |
email | string | - | Email address being invited |
inviter_id | string | FK | Reference to the user who sent the invitation |
organization_id | string | FK | Reference to the organization |
role | string | - | Role assigned to the invited member |
status | string | - | Invitation status |
expires_at | timestamp | - | Invitation expiration time |
created_at | timestamp | - | Record creation time |
Table: organization_members
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the member record |
organization_id | string | FK | Reference to the organization |
user_id | string | FK | Reference to the user |
role | string | - | Member's role within the organization |
created_at | timestamp | - | Record creation time |
updated_at | timestamp | - | Record last update time |
Table: organization_teams
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the team |
organization_id | string | FK | Reference to the organization |
name | string | - | Team name |
slug | string | - | URL-friendly identifier |
description | string? | - | Description |
metadata | JSON | - | Additional metadata |
created_at | timestamp | - | Record creation time |
updated_at | timestamp | - | Record last update time |
Table: organization_team_members
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the team member record |
team_id | string | FK | Reference to the team |
member_id | string | FK | Reference to the organization member |
created_at | timestamp | - | Record creation time |
Migrations are automatically handled when the plugin is initialized.
Database Hooks
This plugin supports the following database hooks:
Organizations:
BeforeCreate: Before an organization is createdAfterCreate: After an organization is createdBeforeUpdate: Before an organization is updatedAfterUpdate: After an organization is updatedBeforeDelete: Before an organization is deletedAfterDelete: After an organization is deleted
Invitations:
BeforeCreate: Before an invitation is createdAfterCreate: After an invitation is createdBeforeUpdate: Before an invitation is updatedAfterUpdate: After an invitation is updatedBeforeDelete: Before an invitation is deletedAfterDelete: After an invitation is deleted
Members:
BeforeCreate: Before a member is createdAfterCreate: After a member is createdBeforeUpdate: Before a member is updatedAfterUpdate: After a member is updatedBeforeDelete: Before a member is deletedAfterDelete: After a member is deleted
Teams:
BeforeCreate: Before a team is createdAfterCreate: After a team is createdBeforeUpdate: Before a team is updatedAfterUpdate: After a team is updatedBeforeDelete: Before a team is deletedAfterDelete: After a team is deleted
Team Members:
BeforeCreate: Before a team member is createdAfterCreate: After a team member is createdBeforeDelete: Before a team member is deletedAfterDelete: After a team member is deleted
NOTE
Database hooks are only supported in Library Mode.
Plugin Capabilities
This plugin doesn't provide any hooks and capabilities.
Security Recommendations
- Ensure that the Access Control plugin is properly configured to manage permissions for organization-related actions.
- Regularly review organization members and their roles to maintain proper access control.
- Make sure to always require authentication for all organization-related API routes and enforce role-based access control for certain routes.
Client Plugin
If you're using the Authula SDK, add the plugin to the client instance as follows:
import { createClient } from "authula";
import { OrganizationsPlugin } from "authula/plugins";
export const authulaClient = createClient({
url: "http://localhost:8080/auth",
plugins: [new OrganizationsPlugin()],
});