Skip to content
Scalekit Docs
Go to Dashboard

Roles and permissions

Applications often include many capabilities. Not every user should be able to perform every action (for example, only owners should manage billing or payments). Scalekit helps you restrict access cleanly with roles and permissions so users get only the access they need.

Scalekit’s Full Stack Auth (FSA) lets your users sign in to your app. Once integrated, Scalekit acts as access middleware: it verifies identity and shares the user’s role and permissions with your application so you can allow or restrict actions.

  • Role: A convenient bundle of actions. Examples: Admin, Manager, Editor, Viewer. Roles state what a user can and cannot do.
  • Permission: A single allowed action in your system, typically rendered as resource:action (for example, projects:create, tasks:read). Use permissions when you need fine-grained control.

Scalekit automatically assigns default roles when setting up your organization:

  • Organization creator: The first user who creates your Scalekit organization gets the creator role automatically
  • New members: When you invite users to your organization, they’re automatically assigned the member role

These default roles provide a starting point for access control. You can customize what permissions these roles have and change the default role assignments at any time.

Design roles that reflect how your users work. For a project management app (similar to Linear), you might define:

RolePermissions
Adminorg:manage, billing:manage, projects:create, projects:write, projects:read, tasks:create, tasks:write, tasks:read, members:manage
Project ownerprojects:create, projects:write, projects:read, tasks:create, tasks:write, tasks:read
Editorprojects:write, projects:read, tasks:create, tasks:write, tasks:read
Memberprojects:read, tasks:create, tasks:read
Viewerprojects:read, tasks:read

Keep headers short and permissions focused. Expand this table to match your product.

You can register roles and permissions from the Scalekit dashboard:

    • Go to User management → Permissions
    • Create granular permissions like projects:create, tasks:read, billing:manage
    • Think about your app’s resources and actions when defining permissions
    • Use consistent naming patterns: resource:action (e.g., projects:create, projects:read, projects:update, projects:delete)

    • Go to Authorization → Roles
    • Click + Add role and provide:
      • Display name: Human-readable name (e.g., “Project Owner”)
      • Name (key): Machine-friendly identifier (e.g., project_owner)
      • Description: Clear explanation of what users with this role can do
    • Use short, machine-friendly keys for the Name field

  1. Understand role inheritance Optional

    Section titled “Understand role inheritance ”

    Role inheritance lets you build permission hierarchies by having one role inherit all permissions from another role, then adding or removing specific permissions. This approach reduces duplication and makes permission management more maintainable.

    How inheritance works:

    • A role automatically gets all permissions from its base role
    • You can then add new permissions specific to the inheriting role
    • You can also remove specific permissions if needed
    • Changes to the base role automatically propagate to all inheriting roles

    Example hierarchy:

    viewer (base role)
    ├── projects:read
    ├── tasks:read
    └── comments:read
    editor (inherits from viewer)
    ├── [inherits all viewer permissions]
    ├── projects:write
    ├── tasks:create
    └── tasks:write
    project_owner (inherits from editor)
    ├── [inherits all editor permissions]
    ├── projects:create
    └── members:invite
    admin (inherits from project_owner)
    ├── [inherits all project_owner permissions]
    ├── org:manage
    ├── billing:manage
    └── members:manage

    Benefits of inheritance:

    • Easier maintenance: Update permissions in one place and they automatically apply to all inheriting roles
    • Consistent access levels: Ensures users with higher roles always have at least the same access as base roles
    • Reduced duplication: No need to repeatedly assign the same permissions to multiple roles
    • Logical structure: Clear progression from basic access to full administrative capabilities

    • Assign the permissions you created to each role
    • Consider using inheritance to build permission sets efficiently
    • Test your permission model to ensure users have appropriate access levels
    • Document your permission structure for your development team
    • Confirm default role for the environment creator is creator
    • Confirm default role for new members is member
    • You can change these defaults at any time in Authorization → Roles

When your app is integrated with Full Stack Auth and a user signs in, Scalekit issues an access token and a refresh token, and creates a session to track access duration.

Token claim availability:

  • Access token: Contains both roles and permissions claims
  • ID token: Contains only the roles claim

The roles claim contains the role name (not the display name). For example, if the role name is editor and the display name is “Content Editor,” the token includes "editor".

The permissions claim contains the permission name (not the description). For example, if the permission name is projects:create and the description is “Create new projects,” the token includes "projects:create".

Here’s an example of decoded tokens containing roles and permissions claims:

idToken.json
{
"amr": ["conn_123456789012345678"],
"aud": ["skc_987654321098765432"],
"azp": "skc_987654321098765432",
"client_id": "skc_987654321098765432",
"email": "john.doe@example.com",
"email_verified": true,
"exp": 1753441845,
"family_name": "Doe",
"given_name": "John",
"iat": 1750849845,
"iss": "http://example.localhost:8889",
"name": "John Doe",
"oid": "org_987654321098765432",
"roles": ["member"],
"sid": "ses_987654321098765432",
"sub": "usr_987654321098765432"
}

With roles and permissions available in tokens, enforce access in your backend and UI. Example checks:

// Example: check role
const isProjectOwner = token.roles?.includes('project_owner');
// Example: check permission
const canCreateProject = token.permissions?.includes('projects:create');