ObjectStackObjectStack

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

PropertyTypeRequiredDescription
namestringMachine name (snake_case)
labelstringoptionalDisplay label
isProfilebooleanoptionalIs this a user profile (vs. permission set)
objectsRecord<string, ObjectPermission>Object-level permissions
fieldsRecord<string, Record<string, FieldPermission>>optionalField-level security
systemPermissionsstring[]optionalSystem-level capabilities
tabPermissionsRecord<string, TabVisibility>optionalTab/app visibility
rowLevelSecurityRLSPolicy[]optionalRow-level security policies
contextVariablesRecord<string, any>optionalRLS 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
  },
}
PermissionDescription
allowCreateCreate new records
allowReadView records (subject to sharing rules)
allowEditUpdate records (subject to sharing rules)
allowDeleteSoft-delete records
allowTransferTransfer record ownership
allowRestoreRestore records from trash
allowPurgePermanently delete records (GDPR compliance)
viewAllRecordsView all records regardless of sharing rules
modifyAllRecordsEdit 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
  },
}
PermissionDescription
readableUser can see the field value
editableUser 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
}
VisibilityDescription
visibleAlways visible, user cannot hide
hiddenAlways hidden, user cannot show
default_onVisible by default, user can toggle off
default_offHidden 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

AspectProfile (isProfile: true)Permission Set (isProfile: false)
AssignmentOne profile per userMultiple permission sets per user
PurposeBaseline access levelAdditional capabilities
Examplestandard_user, adminsales_analytics, export_data

A user's effective permissions = Profile permissionsAll 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}",
    },
  ],
};

On this page