
ld-permissions
by lightdash
Self-serve BI to 10x your data team ⚡️
SKILL.md
name: ld-permissions description: Guide for Lightdash's CASL-based authorization system. Use when working with scopes, custom roles, abilities, permissions, ForbiddenError, authorization, or access control. Helps with adding new scopes, debugging permission issues, understanding the permission flow, and creating custom roles. allowed-tools: Read, Grep, Glob, Task
Permissions & Authorization Guide
This skill helps you work with Lightdash's CASL-based permissions system, including scopes, custom roles, and authorization enforcement.
What do you need help with?
- Add a new scope/permission - Step-by-step guide to add a new permission
- Debug a permission issue - Troubleshoot why a user can't access something
- Understand the permission flow - Learn how permissions work end-to-end
- Work with custom roles - Create or modify custom roles with specific scopes
Quick Reference
Key Files
| Purpose | Location |
|---|---|
| Scope definitions | packages/common/src/authorization/scopes.ts |
| CASL types | packages/common/src/authorization/types.ts |
| Ability builder | packages/common/src/authorization/index.ts |
| System role abilities | packages/common/src/authorization/projectMemberAbility.ts |
| Role-to-scope mapping | packages/common/src/authorization/roleToScopeMapping.ts |
| Scope-to-CASL conversion | packages/common/src/authorization/scopeAbilityBuilder.ts |
Common Patterns
Backend permission check:
import { subject } from '@casl/ability';
import { ForbiddenError } from '@lightdash/common';
if (user.ability.cannot('manage', subject('Dashboard', { projectUuid }))) {
throw new ForbiddenError('You do not have permission');
}
Frontend permission check:
const { user } = useUser();
if (user?.ability.can('manage', 'Dashboard')) {
return <EditButton />;
}
or wrap in a CASL component:
import { Can } from '../../providers/Ability';
<Can I="manage" a="Dashboard">
<EditButton />
</Can>
Full Documentation
For comprehensive documentation, read: .context/PERMISSIONS.md
This includes:
- Architecture diagram showing the complete permission flow
- All scope groups and modifiers (@self, @public, @space, etc.)
- Database schema for custom roles
- Step-by-step guide to add new scopes
- Troubleshooting guide
Adding a New Scope (Quick Guide)
- Define scope in
packages/common/src/authorization/scopes.ts:
{
name: 'manage:NewFeature',
description: 'Description for custom role UI',
isEnterprise: false,
group: ScopeGroup.PROJECT_MANAGEMENT,
getConditions: (context) => [addUuidCondition(context)],
}
-
Add subject (if new) in
packages/common/src/authorization/types.ts -
Add to system role in
packages/common/src/authorization/roleToScopeMapping.ts -
Update ability builder in
packages/common/src/authorization/projectMemberAbility.ts -
Enforce in service with
user.ability.cannot()check -
Add frontend check with
user?.ability.can()
Debugging Permission Issues
When a user gets "ForbiddenError":
- Check scope exists - Is the scope defined in
scopes.ts? - Check role assignment - Does the user's role include this scope?
- Check conditions - Do the CASL conditions match the resource?
- Check enterprise flag - Is
isEnterprise: truebut deployment isn't enterprise? - Check subject name - Case-sensitive match in
CaslSubjectNames?
Use grep to find where the permission is checked:
grep -r "ability.cannot.*'manage'.*'YourSubject'" packages/backend/src/services/
Please describe what you're trying to accomplish, or ask me to explain any aspect of the permissions system.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 1000以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon

