Permission Metadata
Define access control with permission sets — object CRUD, field security, tab visibility, and row-level security
Permission Metadata
A Permission Set defines what a user can do within the application. It controls object-level CRUD operations, field-level visibility, tab/app access, and row-level security policies.
Basic Structure
const salesUserPermission = {
name: 'sales_user',
label: 'Sales User',
isProfile: false,
objects: {
account: {
allowCreate: true,
allowRead: true,
allowEdit: true,
allowDelete: false,
viewAllRecords: false,
modifyAllRecords: false,
},
opportunity: {
allowCreate: true,
allowRead: true,
allowEdit: true,
allowDelete: true,
viewAllRecords: false,
modifyAllRecords: false,
},
report: {
allowCreate: false,
allowRead: true,
allowEdit: false,
allowDelete: false,
viewAllRecords: true,
modifyAllRecords: false,
},
},
fields: {
account: {
annual_revenue: { readable: true, editable: false },
internal_notes: { readable: false, editable: false },
},
},
tabPermissions: {
crm: 'visible',
admin: 'hidden',
reports: 'default_on',
},
};Permission Set Properties
| Property | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Machine name (snake_case) |
label | string | optional | Display label |
isProfile | boolean | optional | Is this a user profile (vs. permission set) |
objects | Record<string, ObjectPermission> | ✅ | Object-level permissions |
fields | Record<string, Record<string, FieldPermission>> | optional | Field-level security |
systemPermissions | string[] | optional | System-level capabilities |
tabPermissions | Record<string, TabVisibility> | optional | Tab/app visibility |
rowLevelSecurity | RLSPolicy[] | optional | Row-level security policies |
contextVariables | Record<string, any> | optional | RLS context variables |
Object Permissions
Control CRUD operations on each object:
objects: {
account: {
allowCreate: true, // Can create records
allowRead: true, // Can view records
allowEdit: true, // Can update records
allowDelete: false, // Can delete records
allowTransfer: false, // Can change record ownership
allowRestore: false, // Can restore deleted records
allowPurge: false, // Can permanently delete (GDPR)
viewAllRecords: false, // Bypass sharing rules for read
modifyAllRecords: false, // Bypass sharing rules for write
},
}| Permission | Description |
|---|---|
allowCreate | Create new records |
allowRead | View records (subject to sharing rules) |
allowEdit | Update records (subject to sharing rules) |
allowDelete | Soft-delete records |
allowTransfer | Transfer record ownership |
allowRestore | Restore records from trash |
allowPurge | Permanently delete records (GDPR compliance) |
viewAllRecords | View all records regardless of sharing rules |
modifyAllRecords | Edit all records regardless of sharing rules |
Field Permissions
Control visibility and editability of individual fields:
fields: {
// Object name → Field name → Permission
account: {
annual_revenue: { readable: true, editable: false }, // Read-only
internal_notes: { readable: false, editable: false }, // Hidden
name: { readable: true, editable: true }, // Full access
},
contact: {
ssn: { readable: false, editable: false }, // Restricted
salary: { readable: true, editable: false }, // Read-only
},
}| Permission | Description |
|---|---|
readable | User can see the field value |
editable | User can modify the field value |
Note: editable: true requires readable: true. A field that is not readable is completely hidden from the user.
Tab Permissions
Control which apps/tabs are visible to users:
tabPermissions: {
crm: 'visible', // Always shown
admin: 'hidden', // Never shown
reports: 'default_on', // Shown by default, user can hide
analytics: 'default_off', // Hidden by default, user can show
}| Visibility | Description |
|---|---|
visible | Always visible, user cannot hide |
hidden | Always hidden, user cannot show |
default_on | Visible by default, user can toggle off |
default_off | Hidden by default, user can toggle on |
System Permissions
Grant system-level capabilities:
systemPermissions: [
'manage_users',
'customize_application',
'view_all_data',
'modify_all_data',
'manage_sharing',
'export_data',
'api_access',
'manage_integrations',
]Row-Level Security
Define policies that restrict which records a user can access:
rowLevelSecurity: [
{
name: 'own_records_only',
object: 'opportunity',
condition: "owner = {$currentUser.id}",
},
{
name: 'same_department',
object: 'account',
condition: "department = {$currentUser.department}",
},
]Context Variables
Provide dynamic values for RLS policies:
contextVariables: {
region: '{$currentUser.region}',
department: '{$currentUser.department}',
role: '{$currentUser.role}',
}Profile vs. Permission Set
| Aspect | Profile (isProfile: true) | Permission Set (isProfile: false) |
|---|---|---|
| Assignment | One profile per user | Multiple permission sets per user |
| Purpose | Baseline access level | Additional capabilities |
| Example | standard_user, admin | sales_analytics, export_data |
A user's effective permissions = Profile permissions ∪ All assigned Permission Set permissions.
Complete Example
const salesManagerPermission = {
name: 'sales_manager',
label: 'Sales Manager',
isProfile: false,
objects: {
account: {
allowCreate: true,
allowRead: true,
allowEdit: true,
allowDelete: true,
allowTransfer: true,
allowRestore: true,
allowPurge: false,
viewAllRecords: true,
modifyAllRecords: false,
},
opportunity: {
allowCreate: true,
allowRead: true,
allowEdit: true,
allowDelete: true,
allowTransfer: true,
allowRestore: true,
allowPurge: false,
viewAllRecords: true,
modifyAllRecords: true,
},
contact: {
allowCreate: true,
allowRead: true,
allowEdit: true,
allowDelete: false,
viewAllRecords: true,
modifyAllRecords: false,
},
},
fields: {
account: {
annual_revenue: { readable: true, editable: true },
internal_rating: { readable: true, editable: true },
},
contact: {
salary: { readable: true, editable: false },
},
},
tabPermissions: {
crm: 'visible',
reports: 'visible',
admin: 'hidden',
},
systemPermissions: [
'export_data',
'api_access',
],
rowLevelSecurity: [
{
name: 'team_accounts',
object: 'account',
condition: "team = {$currentUser.team}",
},
],
};Related
- Object Metadata — Objects that permissions control access to
- Field Metadata — Fields that field permissions control
- App Metadata — Apps that tab permissions control visibility for