Codapult
料金プラグインドキュメント
Codapult

開発者のためのSaaSボイラープレート

プロダクト

  • 料金
  • プラグイン
  • ドキュメント

会社情報

  • お問い合わせ
  • GitHub

法的情報

  • プライバシーポリシー
  • 利用規約

© 2026 Codapult. All rights reserved.

全記事

Getting Started

  • Introduction
  • Quick Start
  • Project Structure

Configuration

  • Environment Variables
  • App Configuration

Authentication

  • Authentication
  • OAuth Providers
  • Two-Factor & Passwordless
  • Enterprise SSO (SAML)

Database

  • Database
  • Migrations

Teams

  • Teams & Organizations
  • Permissions & RBAC

Payments

  • Payments & Billing
  • Stripe Setup
  • LemonSqueezy Setup
  • Polar Setup
  • Payment Webhooks

Api

  • API Layer
  • tRPC
  • GraphQL

Ai

  • AI Features

Email

  • Email
  • Email Templates

Infrastructure

  • Infrastructure
  • File Storage
  • Background Jobs

Ui

  • UI & Theming

I18n

  • Internationalization

Content Management

  • Content Management

Admin

  • Admin Panel

Security

  • Security

Monitoring

  • Analytics & Monitoring

Modules

  • Module Architecture

Plugins

  • Plugin System
  • AI Kit Plugin
  • CRM Plugin
  • Helpdesk Plugin
  • Email Marketing Plugin

Deployment

  • Deployment
  • Troubleshooting

Upgrading

  • Upgrading Codapult

Developer Tools

  • MCP Server
  • Testing
Teams

Permissions & RBAC

Role-based access control system — defining permissions, using guards, and adding custom permissions.

Codapult uses a role-based access control (RBAC) system to manage what users can do within organizations.

Roles

Every organization member has one of four roles, ordered from most to least privileged:

RoleLevelCapabilities
Owner4Full control — delete org, manage billing, all actions
Admin3Manage members, settings, billing, resources
Member2Create and edit resources, view billing
Viewer1Read-only access to org resources and settings

Global admins (user.role === 'admin') bypass all organization-level permission checks.

Permission Definitions

Permissions are defined in src/lib/permissions.ts as a map of action to allowed roles:

const permissions = {
  'org:update': ['owner', 'admin'],
  'org:delete': ['owner'],
  'member:invite': ['owner', 'admin'],
  'member:remove': ['owner', 'admin'],
  'member:update-role': ['owner', 'admin'],
  'member:list': ['owner', 'admin', 'member', 'viewer'],
  'billing:manage': ['owner', 'admin'],
  'billing:view': ['owner', 'admin', 'member'],
  'resource:create': ['owner', 'admin', 'member'],
  'resource:read': ['owner', 'admin', 'member', 'viewer'],
  'resource:update': ['owner', 'admin', 'member'],
  'resource:delete': ['owner', 'admin'],
  'settings:manage': ['owner', 'admin'],
  'invitation:create': ['owner', 'admin'],
  'invitation:revoke': ['owner', 'admin'],
} satisfies Record<string, readonly OrgRole[]>;

Helper Functions

import { hasPermission, isRoleAtLeast, canModifyRole } from '@/lib/permissions';

hasPermission('member', 'resource:create'); // true
hasPermission('viewer', 'resource:create'); // false
isRoleAtLeast('admin', 'member'); // true
canModifyRole('admin', 'owner'); // false (must be strictly higher)

Server-Side Guards

Use guards from src/lib/guards.ts to enforce permissions in server actions and API routes:

GuardDescription
requireAuth()User is logged in — throws if not
requireOrgMembership(orgId)User is a member of the organization
requireOrgAdmin(orgId)User is an owner or admin
requireOrgPermission(orgId, permission)User has a specific permission in the organization

All org guards return an OrgAuthContext with the session, orgId, and the user's role.

In Server Actions

'use server';

import { requireOrgPermission } from '@/lib/guards';

export async function updateOrgSettings(orgId: string, data: unknown) {
  const { session, role } = await requireOrgPermission(orgId, 'settings:manage');
  // Only owners and admins reach this point
}

In API Routes

import { requireOrgMembership } from '@/lib/guards';

export async function GET(req: Request) {
  const orgId = req.headers.get('x-org-id');
  if (!orgId) return NextResponse.json({ error: 'Missing org' }, { status: 400 });

  const { session } = await requireOrgMembership(orgId);
  // Return org data...
}

Adding Custom Permissions

  1. Add the permission key to the permissions map in src/lib/permissions.ts:
'project:archive': ['owner', 'admin'],
  1. Use it in your server action or API route:
await requireOrgPermission(orgId, 'project:archive');
  1. Optionally check it on the client for conditional UI rendering:
import { hasPermission } from '@/lib/permissions';

const canArchive = hasPermission(currentRole, 'project:archive');

Checking Permissions in UI

For conditional rendering based on the current user's role, pass the role from the server and use hasPermission on the client:

{
  hasPermission(role, 'member:invite') && <InviteMemberButton orgId={orgId} />;
}
Teams & OrganizationsPayments & Billing