Skip to main content

Salesforce Basics: Custom Permission in Salesforce

๐Ÿ’ฌ In plain words: A Custom Permission is a simple yes/no flag you attach to users, which your code and flows can check — like a feature switch per person. Use it instead of hardcoding profile names in logic.
๐Ÿ“Œ Example: Validation rule blocks editing closed Cases — but the audit team must edit them. Create Custom Permission Edit_Closed_Cases, add NOT($Permission.Edit_Closed_Cases) to the rule, and assign it to auditors via a permission set. No profile checks in formulas!
๐ŸŽฌ Real-Life Example: Bypassing a Validation Rule

Imagine you have a rule: no one can discount an Opportunity by more than 20%. But the VP of Sales needs to override this rule when closing major deals.

The Old/Bad Way (hardcoding): Write a validation rule checking profile names: Discount__c > 0.20 && $Profile.Name != 'System Administrator' && $Profile.Name != 'VP of Sales'.

Why this is bad: If Regional Managers later need this capability, you must rewrite formula rules across the org. If a user changes roles, you must update their profile. It quickly becomes a maintenance nightmare.

The New/Good Way (Custom Permissions):

  1. Create a Custom Permission named Can_Approve_Large_Discounts.
  2. Create a Permission Set called "Discount Approvers" and add that Custom Permission to it.
  3. Assign the Permission Set to the VP of Sales — and anyone else who needs it.
  4. Write the validation rule to look for the capability, not the person: Discount__c > 0.20 && NOT($Permission.Can_Approve_Large_Discounts).

The payoff: The system no longer cares who the user is or what profile they carry. It only checks if they hold the "VIP pass". Need a new manager to have access? Simply assign the Permission Set.

Concept

A Custom Permission is a named flag that you define, assign, and check. You can evaluate it in Apex, formulas, validation rules, and flows to decouple "can this user do X" from rigid profile name checks.

Assign Custom Permissions via Permission Sets and Permission Set Groups. Evaluate them declaratively using $Permission.MyPerm or in Apex using FeatureManagement.checkPermission('MyPerm'). It provides a maintainable answer to rule-override requirements without relying on brittle, hardcoded profile strings. Custom Permissions can also be shipped inside Managed Packages or tied to Connected Apps.

๐Ÿง  Custom Permission = named flag you CHECK, not a profile-name hardcode. $Permission.X (formula/VR/flow) · FeatureManagement.checkPermission('X') (Apex). Assign via permission set.

Core Q&A

Q: You need a validation rule that everyone must pass EXCEPT a small group of override users. How do you implement it maintainably?
๐ŸŽฏ Say this first: Create a Custom Permission. Check it in the validation rule with $Permission. Assign it to the override group through a permission set.

A: Define a Custom Permission (e.g., Bypass_Amount_Limit). Assign it through a Permission Set to users permitted to bypass the rule, then write the Validation Rule formula to fire only when NOT($Permission.Bypass_Amount_Limit).

  • Common Mistake: Hardcoding profile names in the formula. This breaks if a profile is renamed or cloned, and requires formula updates whenever new roles are onboarded.
  • Custom Permissions travel across profiles seamlessly and produce a clean audit trail — whoever holds the permission set possesses the override.
  • The exact same flag evaluates consistently in Apex via FeatureManagement.checkPermission and inside Flows.
  • Adding or removing an override user requires a simple Permission Set assignment with zero rule edits.
// Validation Rule formula: AND( Amount__c > 10000, NOT($Permission.Bypass_Amount_Limit) ) // Apex check: if (FeatureManagement.checkPermission('Bypass_Amount_Limit')) { // allow the privileged path }

Follow-ups (Scenario-Based)

Q1: Custom Permission vs. a checkbox on a Custom Setting vs. checking the profile name — when each?

A1: Use a Custom Permission to gate a specific user capability. Assign it via permission sets and evaluate it in code or declarative tools — this is the standard answer for "which users can do X".

  • Use a Hierarchy Custom Setting checkbox when an override requires a value or flag that resolves hierarchically at the Org, Profile, or User level (e.g., "skip all triggers for this integration user during data loads" via $Setup).
  • Checking Profile Names: Avoid hardcoding profile names. It breaks on rename or clone, creates maintenance technical debt, and fails to scale.
Q2: How do Custom Permissions help package or feature-gate functionality?

A2: A Custom Permission provides a clean, user-agnostic flag. Automation and Apex code evaluate the permission directly, making feature activation a simple assignment task via Permission Sets shipped inside packages.

  • Dark Deployments: Deploy underlying code inactive, gated behind an unassigned permission.
  • Pilot Rollouts: Enable features for specific test groups purely through Permission Set assignments.
  • Package Monetization: Gate premium managed package capabilities by binding Custom Permissions to Permission Set Licenses.
Q (compare): If we can assign a permission set, why do custom permissions exist at all?

A: A Permission Set GRANTS access, while a Custom Permission is a specific FLAG inside it that your custom logic can TEST. Declarative tools like Validation Rules or Flows cannot query "does this user hold Permission Set X?", but they can check a Custom Permission in a single line (e.g., $Permission.Override_Delivery_Price). This decouples logic from packaging: the underlying permission flag can move across various permission sets without breaking the rule formula.

Recommended Reading: Master-Detail vs Lookup in Salesforce