apex-custom-permissions-check

Custom Permissions in Apex: FeatureManagement.checkPermission, $Permission global variable, permission-set gating of feature code, Custom Permission metadata. NOT for CRUD/FLS enforcement (use security-apex-crud-fls). NOT for standard Salesforce permissions (use permission-set-architecture).

Best use case

apex-custom-permissions-check is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Custom Permissions in Apex: FeatureManagement.checkPermission, $Permission global variable, permission-set gating of feature code, Custom Permission metadata. NOT for CRUD/FLS enforcement (use security-apex-crud-fls). NOT for standard Salesforce permissions (use permission-set-architecture).

Teams using apex-custom-permissions-check should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/apex-custom-permissions-check/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/apex/apex-custom-permissions-check/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/apex-custom-permissions-check/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How apex-custom-permissions-check Compares

Feature / Agentapex-custom-permissions-checkStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Custom Permissions in Apex: FeatureManagement.checkPermission, $Permission global variable, permission-set gating of feature code, Custom Permission metadata. NOT for CRUD/FLS enforcement (use security-apex-crud-fls). NOT for standard Salesforce permissions (use permission-set-architecture).

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Apex Custom Permissions Check

Activate when gating code paths, feature availability, or field-level behavior behind a Custom Permission. Custom Permissions are the platform's feature-flag primitive — declarative on/off tokens assigned via Permission Sets or Profiles that Apex, LWC, formulas, and validation rules can check consistently.

## Before Starting

- **Create the Custom Permission metadata first.** Setup → Custom Permissions or via `-meta.xml` deployment.
- **Assign via Permission Set, not Profile** for maintainability.
- **Use `FeatureManagement.checkPermission`** for runtime checks — not the deprecated Schema describe path.

## Core Concepts

### Custom Permission metadata

```
<CustomPermission xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Approve Big Deals</label>
    <isLicensed>false</isLicensed>
</CustomPermission>
```

API Name is the handle used in Apex / formulas.

### Apex check

```
Boolean canApprove = FeatureManagement.checkPermission('Approve_Big_Deals');
if (!canApprove) throw new AuraHandledException('Not authorized');
```

Per-user, transaction-cached. Safe to call repeatedly.

### Formula / validation rule

`$Permission.Approve_Big_Deals` returns Boolean for declarative gating.

### LWC

```
import hasApprove from '@salesforce/customPermission/Approve_Big_Deals';
```

Returns Boolean at module load — evaluate in getters.

### Testing

```
@IsTest
static void canApprove() {
    User u = TestUserFactory.makeUser();
    insert new PermissionSetAssignment(
        AssigneeId = u.Id,
        PermissionSetId = [SELECT Id FROM PermissionSet WHERE Name = 'Big_Deal_Approvers'].Id
    );
    System.runAs(u) { ... }
}
```

## Common Patterns

### Pattern: Gate Apex service entry point

```
public with sharing class ApprovalService {
    public void approve(Id oppId) {
        if (!FeatureManagement.checkPermission('Approve_Big_Deals')) {
            throw new AuraHandledException('Not authorized');
        }
    }
}
```

### Pattern: LWC conditional render

```
import hasApprove from '@salesforce/customPermission/Approve_Big_Deals';
export default class Approve extends LightningElement {
    get showButton() { return hasApprove; }
}
```

### Pattern: Validation rule gate

`AND(ISCHANGED(Status), Status='Approved', NOT($Permission.Approve_Big_Deals))`

## Decision Guidance

| Need | Mechanism |
|---|---|
| Feature flag for code path | Custom Permission |
| Object CRUD | Object permission on Permission Set |
| Field-level gate | FLS on Permission Set |
| Temporary admin toggle | Custom Setting + check |
| A/B test | Custom Permission + assignment script |

## Recommended Workflow

1. Define the feature boundary — what code runs for privileged users only.
2. Create the Custom Permission metadata.
3. Create a Permission Set granting it; assign to users.
4. Add `FeatureManagement.checkPermission` at service entry points.
5. Mirror the check in LWC and formulas where needed.
6. Write Apex tests using `System.runAs` + PermissionSetAssignment.
7. Document the permission in the feature runbook.

## Review Checklist

- [ ] Custom Permission metadata exists with clear label
- [ ] Assigned via Permission Set (not Profile)
- [ ] Apex uses `FeatureManagement.checkPermission`
- [ ] LWC uses `@salesforce/customPermission/` import
- [ ] Formulas use `$Permission.<API_Name>`
- [ ] Tests cover both granted and denied
- [ ] No hardcoded user Ids in permission checks
- [ ] Permission documented in feature doc

## Salesforce-Specific Gotchas

1. **`isLicensed=true`** requires the user's managed-package license; non-licensed users cannot receive it even if assigned.
2. **`Schema.describe` for Custom Permissions is deprecated** — use `FeatureManagement.checkPermission`.
3. **Custom Permission grants propagate through Permission Set Groups** — audit muting flags on groups.

## Output Artifacts

| Artifact | Description |
|---|---|
| Custom Permission metadata | XML file |
| Permission Set granting the CP | Metadata + assignment plan |
| Apex test class | Positive + negative cases with runAs |

## Related Skills

- `security/permission-set-architecture` — permission-set design
- `security/security-apex-crud-fls` — CRUD/FLS enforcement
- `lwc/lwc-user-permission-aware-components` — LWC permission checks

Related Skills

security-health-check

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when running, interpreting, or acting on Salesforce Security Health Check results — reading the score, understanding risk categories, evaluating specific settings, creating or importing a custom baseline, querying the Tooling API programmatically, or planning remediation from findings. Triggers: 'security health check score', 'health check failing settings', 'custom baseline', 'remediate health check findings', 'fix risk'. NOT for org hardening implementation, permission model design, or broad baseline config beyond what Health Check directly measures.

secure-coding-review-checklist

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill to audit Apex, Visualforce, LWC, and Aura code for Salesforce security review readiness — covering CRUD/FLS enforcement, SOQL injection, XSS, CSRF, and open redirects. NOT for network-level penetration testing, Shield Platform Encryption key management, or general org permission set design.

customer-data-request-workflow

8
from PranavNagrecha/AwesomeSalesforceSkills

Implement GDPR/CCPA data subject rights (access, deletion, rectification) using Salesforce Privacy Center and/or custom workflow. NOT for general backup or org-level data retention policy.

apex-managed-sharing-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Grant row-level access programmatically via __Share records when declarative sharing rules cannot express the policy. NOT for OWD, role hierarchy, or criteria-based sharing rule design.

omnistudio-custom-lwc-elements

8
from PranavNagrecha/AwesomeSalesforceSkills

Creating and integrating custom Lightning Web Components within OmniScripts: LWC override patterns, pubsub event handling, custom validation, OmniStudio data passing conventions. Use when a standard OmniScript element cannot meet a UX requirement. NOT for standalone LWC development (use lwc/* skills). NOT for Integration Procedures (use integration-procedures). NOT for embedding an OmniScript inside an LWC (use omnistudio-lwc-integration).

lwc-imperative-apex

8
from PranavNagrecha/AwesomeSalesforceSkills

Call Apex methods imperatively from LWC — on button click, lifecycle hooks, or conditional logic. Covers import syntax, cacheable vs non-cacheable, async/await patterns, error handling, loading states, and Promise.all. NOT for wire service (use wire-service-patterns) and NOT for testing Apex mocks (use lwc-testing).

lwc-custom-lookup

8
from PranavNagrecha/AwesomeSalesforceSkills

Custom lookup component in LWC — typeahead/autocomplete that searches records via Apex SOSL/SOQL, shows pills, supports keyboard navigation, and manages open/close state. Use when lightning-input-field or lightning-record-picker won't work (cross-org search, computed filters, custom result rendering). NOT for in-form lookups inside lightning-record-edit-form (use lightning-input-field) or lookup filters (use admin lookup filter config).

lwc-custom-event-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

When and how to design CustomEvent traffic out of an LWC — bubbles / composed / cancelable flag choices, detail payload shape, naming rules, and propagation control. Trigger keywords: 'event not reaching parent', 'composed shadow DOM', 'CustomEvent detail mutation', 'stopPropagation vs stopImmediatePropagation'. NOT for parent-to-child communication (use `@api` — see `lwc/component-communication`), NOT for sibling fan-out (use Lightning Message Service — see `lwc/lightning-message-service`), NOT for wire-service data plumbing.

lwc-custom-datatable-types

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when you need to extend `lightning-datatable` with custom cell renderings: status pills, progress bars, image thumbnails, action cells, editable pickliststo, rich-text, or any column that `lightning-datatable` does not ship out of the box. Triggers: 'custom cell type lightning datatable', 'progress bar column', 'image column', 'inline edit picklist in datatable', 'rich text column'. NOT for basic datatable usage (see `lwc-data-table`) and NOT for tree-grid or large-dataset virtualization (see `virtualized-lists`).

experience-cloud-search-customization

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when configuring or extending search on an Experience Cloud site — covering Search Manager scope configuration, LWR vs Aura search component selection, federated search setup, guest user search access, and custom search result components. NOT for SOSL/SOQL query development. NOT for internal Salesforce global search or Einstein Search for agents.

custom-property-editor-for-flow

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building or reviewing an LWC Custom Property Editor for Flow screen or action configuration, including the `configurationEditor` metadata hook, builder-side APIs, validation, and value-change events. Triggers: 'custom property editor', 'Flow configuration editor', 'builderContext', 'inputVariables', 'configurationEditor'. NOT for ordinary runtime screen-component behavior when no Flow Builder design-time customization is involved.

dataweave-for-apex

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when transforming structured data inside Apex — CSV → JSON, XML → SObject list, JSON → flattened CSV, or schema-mapping a third-party payload to a Salesforce model — and the existing options (`JSON.deserialize`, `Dom.Document`, hand-written loops) are getting unwieldy. Triggers: 'apex transform csv json xml without external library', 'system.dataweave script', 'salesforce native dataweave apex execute', 'transform xml to sobject apex no mulesoft', 'json reshape salesforce apex script'. NOT for MuleSoft Anypoint DataWeave running off-platform (use mulesoft-anypoint-architecture), NOT for Apex JSON serialization basics (use apex-json-serialization), NOT for Bulk API CSV ingest (use bulk-api-2-patterns).