sf-permissions
Salesforce Permission Set analysis, visualization, and auditing tool
When to Use This Skill
Use sf-permissions when the user needs to:
- •Visualize Permission Set and Permission Set Group hierarchies
- •Find out "who has access to X?" (objects, fields, Apex classes, custom permissions)
- •Analyze what permissions a specific user has
- •Export Permission Set configurations for auditing
- •Generate Permission Set XML metadata
- •Understand permission inheritance through PSG membership
Capabilities
| Capability | Description |
|---|---|
| Hierarchy Viewer | Visualize all PS/PSG in an org as ASCII trees |
| Permission Detector | Find which PS/PSG grant a specific permission |
| User Analyzer | Show all permissions assigned to a user |
| CSV Exporter | Export PS configuration for documentation |
| Metadata Generator | Generate Permission Set XML (delegates to sf-metadata) |
| Tooling API | Query tab settings, system permissions via Tooling API |
Prerequisites
# Python dependencies pip install simple-salesforce rich # Salesforce CLI (for authentication) sf --version # Must be installed and authenticated
Authentication
This skill reuses existing sf CLI authentication. Ensure you're authenticated:
# Check current org sf org display # Authenticate if needed sf org login web --alias myorg
Phase 1: Understanding the Request
When a user asks about permissions, identify which capability they need:
| User Says | Capability | Function |
|---|---|---|
| "Show permission hierarchy" | Hierarchy Viewer | hierarchy_viewer.py |
| "Who has access to Account?" | Permission Detector | permission_detector.py |
| "What permissions does John have?" | User Analyzer | user_analyzer.py |
| "Export Sales_Manager PS to CSV" | CSV Exporter | permission_exporter.py |
| "Generate PS XML with these permissions" | Metadata Generator | permission_generator.py |
Phase 2: Connecting to the Org
Step 1: Determine Target Org
# List available orgs sf org list # Default to current target org, or ask user to specify sf org display --target-org <alias>
Step 2: Get Connection via Python
# Run from sf-permissions/scripts/
python -c "
from auth import get_sf_connection
sf = get_sf_connection('myorg') # or None for default
print(f'Connected to: {sf.sf_instance}')
"
Phase 3: Executing Queries
3.1 Permission Hierarchy Viewer
Purpose: Show all Permission Sets and Permission Set Groups in the org
cd ~/.claude/plugins/marketplaces/sf-skills/sf-permissions/scripts python cli.py hierarchy [--target-org ALIAS] [--format ascii|mermaid]
Output Example:
📦 ORG PERMISSION HIERARCHY
════════════════════════════════════════
📁 Permission Set Groups (3)
├── 🔒 Sales_Cloud_User (Active)
│ ├── View_All_Accounts
│ ├── Edit_Opportunities
│ └── Run_Reports
├── 🔒 Service_Cloud_User (Active)
│ └── Case_Management
└── 🔒 Marketing_User (Outdated)
└── Campaign_Access
📁 Standalone Permission Sets (12)
├── Admin_Tools
├── API_Access
└── ... (10 more)
3.2 Permission Detector ("Who has access to X?")
Purpose: Find which PS/PSG grant a specific permission
Supported Permission Types:
- •
object- Object CRUD (Create, Read, Update, Delete, ViewAll, ModifyAll) - •
field- Field-Level Security (Read, Edit) - •
apex- Apex Class access - •
vf- Visualforce Page access - •
flow- Flow access - •
custom- Custom Permission - •
tab- Tab visibility
cd ~/.claude/plugins/marketplaces/sf-skills/sf-permissions/scripts # Object permissions python cli.py detect object Account --access delete python cli.py detect object Opportunity --access create,read,edit # Field permissions python cli.py detect field Account.AnnualRevenue --access edit # Apex class access python cli.py detect apex MyApexClass # Custom permission python cli.py detect custom Can_Approve_Expenses # Tab visibility python cli.py detect tab Account
Output Example:
🔍 PERMISSION DETECTION RESULTS ════════════════════════════════════════ Query: Delete access to Account Found in 3 Permission Sets: 📋 Permission Set │ Group Membership │ Users ──────────────────────────┼────────────────────────┼─────── System_Administrator │ ✗ Standalone │ 2 Sales_Operations_Manager │ ✓ Sales_Cloud_PSG │ 5 Data_Steward │ ✓ Data_Management_PSG │ 1 Total users with this access: 8
3.3 User Permission Analyzer
Purpose: Show all permissions assigned to a specific user
cd ~/.claude/plugins/marketplaces/sf-skills/sf-permissions/scripts python cli.py user "john.smith@company.com" python cli.py user 005xx000001234AAA # User ID also works
Output Example:
👤 USER PERMISSION ANALYSIS
════════════════════════════════════════
User: John Smith (john.smith@company.com)
Profile: Standard User
📁 Via Permission Set Groups (2)
├── 🔒 Sales_Cloud_User
│ ├── View_All_Accounts ✓
│ ├── Edit_Opportunities ✓
│ └── Run_Reports ✓
└── 🔒 Service_Cloud_User
└── Case_Management ✓
📁 Direct Permission Sets (3)
├── API_Access
├── Custom_App_Access
└── Einstein_Analytics_User
3.4 Permission Set Exporter
Purpose: Export PS configuration to CSV for documentation/auditing
cd ~/.claude/plugins/marketplaces/sf-skills/sf-permissions/scripts python cli.py export Sales_Manager --output /tmp/sales_manager.csv
CSV Output Columns:
- •Category (Object, Field, Apex, Tab, System)
- •Name (Object/Field/Class name)
- •Permission (Create, Read, Edit, Delete, etc.)
- •Value (true/false)
3.5 Metadata Fetcher (Helper)
Purpose: Get available objects, fields, Apex classes for autocomplete/validation
from metadata_fetcher import (
get_available_objects,
get_object_fields,
get_apex_classes,
get_custom_permissions
)
sf = get_sf_connection()
objects = get_available_objects(sf)
fields = get_object_fields(sf, 'Account')
Phase 4: Rendering Output
ASCII Tree (Terminal)
Uses the rich library for professional terminal output:
- •Trees for hierarchy visualization
- •Tables for tabular data
- •Panels for summaries
- •Progress bars for long-running queries
Mermaid Diagrams (Documentation)
For embedding in Markdown/documentation:
python cli.py hierarchy --format mermaid > hierarchy.md
graph TD
subgraph Permission Set Groups
PSG1[Sales_Cloud_User]
PSG2[Service_Cloud_User]
end
subgraph Permission Sets
PS1[View_All_Accounts]
PS2[Edit_Opportunities]
PS3[Case_Management]
end
PSG1 --> PS1
PSG1 --> PS2
PSG2 --> PS3
Phase 5: Generating Metadata (Optional)
If the user wants to create a new Permission Set based on analysis:
# Generate Permission Set XML
python cli.py generate \
--name "New_Sales_PS" \
--label "New Sales Permission Set" \
--objects Account:crud,Opportunity:cru \
--fields Account.AnnualRevenue:rw \
--apex MyApexClass,AnotherClass \
--output /tmp/New_Sales_PS.permissionset-meta.xml
Or delegate to sf-metadata skill for more complex generation.
SOQL Reference
Permission Set Queries
-- All Permission Sets (excluding PSGs)
SELECT Id, Name, Label, Description, IsOwnedByProfile
FROM PermissionSet
WHERE IsOwnedByProfile = false AND Type != 'Group'
-- All Permission Set Groups
SELECT Id, DeveloperName, MasterLabel, Status, Description
FROM PermissionSetGroup
-- PSG Components (which PS are in which PSG)
SELECT PermissionSetGroupId, PermissionSetGroup.DeveloperName,
PermissionSetId, PermissionSet.Name
FROM PermissionSetGroupComponent
-- User's PS Assignments
SELECT AssigneeId, PermissionSetId, PermissionSet.Name,
PermissionSetGroupId, PermissionSetGroup.DeveloperName
FROM PermissionSetAssignment
WHERE AssigneeId = '005...'
Object Permissions
-- Object permissions for a specific PS
SELECT SobjectType, PermissionsCreate, PermissionsRead,
PermissionsEdit, PermissionsDelete,
PermissionsViewAllRecords, PermissionsModifyAllRecords
FROM ObjectPermissions
WHERE ParentId = '0PS...'
-- Find PS with specific object access
SELECT Parent.Name, Parent.Label, SobjectType,
PermissionsCreate, PermissionsRead, PermissionsEdit, PermissionsDelete
FROM ObjectPermissions
WHERE SobjectType = 'Account' AND PermissionsDelete = true
Field Permissions
-- Field permissions for a specific PS SELECT Field, PermissionsRead, PermissionsEdit FROM FieldPermissions WHERE ParentId = '0PS...' -- Find PS with specific field access SELECT Parent.Name, Field, PermissionsRead, PermissionsEdit FROM FieldPermissions WHERE Field = 'Account.AnnualRevenue' AND PermissionsEdit = true
Setup Entity Access (Apex, VF, Flows, Custom Permissions)
-- Setup entity access for a PS SELECT SetupEntityType, SetupEntityId FROM SetupEntityAccess WHERE ParentId = '0PS...' -- Find PS with access to specific Apex class SELECT Parent.Name, Parent.Label FROM SetupEntityAccess WHERE SetupEntityType = 'ApexClass' AND SetupEntityId IN (SELECT Id FROM ApexClass WHERE Name = 'MyClass') -- Custom permissions SELECT Parent.Name FROM SetupEntityAccess WHERE SetupEntityType = 'CustomPermission' AND SetupEntityId IN (SELECT Id FROM CustomPermission WHERE DeveloperName = 'Can_Approve')
Common Workflows
Workflow 1: Audit "Who can delete Accounts?"
User: "Who has delete access to the Account object?" 1. Run permission detector for object:Account with delete access 2. For each PS found, get PSG membership 3. For each PS/PSG, count assigned users 4. Display results in table format
Workflow 2: Troubleshoot User Access
User: "Why can't John edit Opportunities?" 1. Run user analyzer for john@company.com 2. Check if any PS grants Opportunity edit 3. If not, suggest which PS/PSG to assign 4. Check for conflicting profile restrictions
Workflow 3: Document Permission Set
User: "Export the Sales_Manager PS for documentation" 1. Run exporter for Sales_Manager 2. Generate CSV with all permissions 3. Optionally generate Mermaid diagram showing PSG membership
Troubleshooting
"INVALID_SESSION_ID" Error
Re-authenticate with sf CLI:
sf org login web --alias myorg
Slow Queries
Large orgs may have thousands of PS. Use filters:
# Filter by name pattern
sf.query("SELECT Id, Name FROM PermissionSet WHERE Name LIKE 'Sales%'")
Tooling API Limitations
Some metadata (like tab settings) requires Tooling API:
from tooling_api import tooling_query results = tooling_query(sf, "SELECT Name, Visibility FROM PermissionSetTabSetting")
Integration with Other Skills
| Skill | Integration |
|---|---|
sf-metadata | Generate Permission Set XML from analysis results |
sf-apex | Identify Apex classes to grant access to |
sf-deploy | Deploy generated Permission Sets |
sf-data | Query user assignments in bulk |
Examples
Example 1: Full Org Audit
User: "Give me a complete picture of permissions in my org" Claude: 1. Runs hierarchy viewer to show all PS/PSG 2. Identifies PSGs with "Outdated" status 3. Counts users per PS 4. Generates Mermaid diagram for documentation
Example 2: Security Review
User: "Find all PS that grant ModifyAllData" Claude: 1. Queries PermissionSet for PermissionsModifyAllData = true 2. Lists PS names and assigned user counts 3. Flags any non-admin PS with this powerful permission
Example 3: Permission Set Creation
User: "Create a PS for contractors with read-only Account access" Claude: 1. Uses permission_generator.py to create XML 2. Sets Account object to Read-only (no Create/Edit/Delete) 3. Outputs .permissionset-meta.xml file