Everything we’ve built so far — objects, fields, page layouts, apps, tabs — is available to every user in the org by default. That’s fine for a developer sandbox, but in a production org with dozens of teams and hundreds of users, unrestricted access is a disaster waiting to happen.
Profiles and permission sets are Salesforce’s answer to the question: “What is this user allowed to do?” They control access to objects, fields, tabs, apps, Apex classes, system features, and more. Getting the permission model right is one of the most important jobs in Salesforce administration.
What Is a Profile?
A profile is a collection of settings and permissions that defines a user’s baseline capabilities in Salesforce. Every user must be assigned exactly one profile — no more, no less.
What a Profile Controls
Profiles control a wide range of settings:
Object Permissions:
- Which objects the user can Read, Create, Edit, Delete, View All, Modify All
Field-Level Security (FLS):
- Which fields the user can see (Visible) and edit (Editable) on each object
Tab Settings:
- Which tabs are Default On, Default Off, or Tab Hidden
App Visibility:
- Which Lightning apps the user can access
Page Layout Assignments:
- Which page layout is shown for each object (combined with record type)
Record Type Access:
- Which record types the user can select when creating records
Login Settings:
- Login hours (restrict when users can log in)
- Login IP ranges (restrict where users can log in from)
System Permissions:
- Hundreds of individual permissions like “API Enabled,” “Manage Users,” “View Setup and Configuration,” “Modify All Data,” etc.
Apex Class Access:
- Which Apex classes the user can execute
Visualforce Page Access:
- Which Visualforce pages the user can view
Connected App Access:
- Which connected apps the user can use
Standard Profiles vs. Custom Profiles
Salesforce includes several standard profiles:
| Profile | Purpose |
|---|---|
| System Administrator | Full access to everything. The “god mode” profile. |
| Standard User | Basic CRUD on most standard objects. No admin access. |
| Standard Platform User | Similar to Standard User but for Platform licenses. |
| Read Only | Can view records but can’t create, edit, or delete. |
| Marketing User | Standard User + campaign management permissions. |
| Contract Manager | Standard User + contract management. |
| Solution Manager | Standard User + solution management. |
| Minimum Access - Salesforce | Virtually no permissions. The recommended base for custom profiles. |
Critical limitation: Standard profiles cannot be fully edited. You can modify some settings (page layouts, record types, tab visibility, app access), but you CANNOT modify object permissions, field-level security, or system permissions on standard profiles.
This is why you always create custom profiles:
- Clone a standard profile
- Name it something meaningful
- Customize it fully
Best practice: Clone the “Minimum Access - Salesforce” profile and add permissions from there. This follows the principle of least privilege — start with nothing, grant only what’s needed.
How to Create and Assign a Profile
Creating a Profile
- Setup → Quick Find → “Profiles”
- Click “New Profile”
- Existing Profile — Select a profile to clone (choose “Minimum Access - Salesforce” for a clean start, or “Standard User” for a quick setup)
- Profile Name — Use a clear, role-based name:
- Good: “Sales Representative,” “Support Agent Level 1,” “Project Manager”
- Bad: “Custom Profile 1,” “New Profile,” “John’s Profile”
- Click “Save”
You’re now on the profile detail page. Configure:
Object Permissions: Navigate to “Object Settings” and click each object to set CRUD permissions:
- Read — View records
- Create — Create new records
- Edit — Modify existing records
- Delete — Delete records
- View All — View all records regardless of sharing rules (bypasses sharing)
- Modify All — Edit and delete all records regardless of sharing/ownership
Field-Level Security: Within each object’s settings, configure field visibility:
- Visible — User can see the field
- Read-Only — User can see but not edit the field
- Neither checked — Field is completely hidden from the user
Tab Settings: Set each tab to Default On, Default Off, or Tab Hidden.
System Permissions: Scroll to “System Permissions” (or use the Enhanced Profile Interface) to toggle individual permissions.
Assigning a Profile to a User
- Setup → Quick Find → “Users”
- Click on the user’s name
- Click “Edit”
- Change the “Profile” dropdown to the desired profile
- Click “Save”
Each user has exactly one profile. Changing it takes effect immediately.
The Enhanced Profile User Interface
Salesforce offers two interfaces for editing profiles:
Original Interface — A long, scrolling page with all settings. Hard to navigate.
Enhanced Interface — A tabbed, searchable interface. Much better for complex profiles.
To enable: Setup → Quick Find → “User Interface” → Check “Enable Enhanced Profile User Interface”
With the enhanced interface, the profile page has tabs:
- Assigned Apps — App visibility
- Object Settings — Object CRUD + FLS for each object
- App Permissions — App-level permissions
- System Permissions — System-level permissions
- Custom Permissions — Custom permissions
- Assigned Connected Apps
- Login Hours / Login IP Ranges
Use this. It’s significantly easier to work with.
What Is a Permission Set?
A permission set is a collection of permissions that can be assigned to users on top of their profile. While a profile is the baseline, permission sets are additive layers.
Why Permission Sets Exist
Profiles have a fundamental limitation: one per user. If you have a Sales Rep who also needs to manage campaigns, you can’t assign them both the “Sales Rep” profile and the “Marketing User” profile. Without permission sets, you’d need to create a “Sales Rep + Marketing” hybrid profile. Scale that to an org with 10 roles and various permission combinations, and you end up with dozens of profiles.
Permission sets solve this by letting you create modular permission bundles that can be mixed and matched:
- Profile: “Sales Rep” (base permissions)
- Permission Set: “Campaign Management” (adds campaign permissions)
- Permission Set: “Report Builder” (adds report creation permissions)
- Permission Set: “API Access” (adds API Enabled permission)
Any combination of these can be assigned to any user, without creating a new profile for each combination.
What Permission Sets Can Control
Permission sets can grant most of the same permissions as profiles:
- Object permissions (CRUD)
- Field-level security
- Tab settings
- App assignments
- System permissions
- Apex class access
- Visualforce page access
- Custom permissions
- Connected app access
- Record type assignments
What Permission Sets CANNOT Do
- Remove permissions — They can only ADD permissions on top of the profile. If a profile grants Edit access to Accounts, a permission set cannot revoke it.
- Set login hours or IP ranges — These are profile-only settings.
- Assign page layouts — Page layout assignment is profile + record type only.
The Additive Model
Salesforce permissions are additive. A user’s effective permissions are:
Profile Permissions + Permission Set 1 + Permission Set 2 + ... = Effective Permissions
If the profile says “No Edit on Cases” but a permission set says “Edit on Cases,” the user CAN edit Cases. The most permissive setting wins.
This is why starting with a minimum access profile is important. If you start with a permissive profile, you can’t use permission sets to take permissions away.
How to Create and Assign a Permission Set
Creating a Permission Set
-
Setup → Quick Find → “Permission Sets”
-
Click “New”
-
Fill in:
- Label — e.g., “Campaign Management Access”
- API Name — Auto-generated
- Description — What this permission set grants and who it’s for
- License — Select a specific license if this permission set should only be assignable to users with that license, or leave as “—None—” for no restriction
-
Click “Save”
-
Configure permissions:
- Click “Object Settings” to set CRUD and FLS per object
- Click “System Permissions” for system-level permissions
- Click “App Permissions” for app-level permissions
- Click “Apex Class Access” for Apex classes
- Click “Assigned Connected Apps” for connected apps
Assigning a Permission Set to a User
Individual Assignment:
- Setup → Users → Click on a user
- Scroll to “Permission Set Assignments”
- Click “Edit Assignments”
- Move permission sets from Available to Enabled
- Click “Save”
From the Permission Set:
- Setup → Permission Sets → Click on the permission set
- Click “Manage Assignments”
- Click “Add Assignments”
- Search and select users
- Click “Assign”
A user can have multiple permission sets assigned simultaneously.
What Is a Permission Set Group?
A permission set group bundles multiple permission sets into a single assignable unit. Instead of assigning 5 individual permission sets to every new sales rep, you assign one permission set group.
Why Permission Set Groups Exist
Permission sets are granular and modular — which is powerful but can become cumbersome. A “Sales Rep” might need:
- “Account & Contact Access”
- “Opportunity Management”
- “Report Builder”
- “Email Integration”
- “Mobile Access”
Assigning 5 permission sets to every new sales rep is error-prone. What if someone forgets #4? Permission set groups let you create a “Sales Rep Permissions” group that includes all 5, and assign it as a single unit.
How to Create a Permission Set Group
- Setup → Quick Find → “Permission Set Groups”
- Click “New Permission Set Group”
- Fill in:
- Label — e.g., “Sales Rep Permissions”
- API Name — Auto-generated
- Description — List the included permission sets and the role this group serves
- Click “Save”
- Click “Permission Sets in Group”
- Click “Add Permission Set”
- Select the permission sets to include
- Click “Add” → “Done”
Assigning a Permission Set Group
Same process as assigning a permission set:
- Setup → Users → Click on a user
- Scroll to “Permission Set Group Assignments”
- Click “Edit Assignments”
- Move groups from Available to Enabled
- Click “Save”
Muting Permissions in a Group
Here’s a feature unique to permission set groups: muting permissions.
Sometimes a permission set in the group grants a permission you don’t want this specific group to have. Instead of creating a separate permission set without that permission, you create a muting permission set within the group.
- Open the Permission Set Group
- Click “Muting Permission Sets in Group”
- Click “New”
- Name the muting permission set
- Select the permissions to mute (disable within this group only)
- Save
Example: The “Report Builder” permission set grants “Export Reports.” But you don’t want Sales Reps exporting data. Create a muting permission set in the “Sales Rep Permissions” group that mutes “Export Reports.”
The muting only applies within this group — users who have “Report Builder” assigned directly (not through this group) still keep the export permission.
Object and Field Permissions
Object Permissions (CRUD)
Object permissions control what a user can do with records of a specific object:
| Permission | What It Allows |
|---|---|
| Read | View records in list views, reports, search results, and record detail pages |
| Create | Create new records |
| Edit | Modify fields on existing records (that the user owns or has sharing access to) |
| Delete | Delete records (that the user owns or has sharing access to) |
| View All | View ALL records of this object, regardless of sharing rules or ownership |
| Modify All | Edit and delete ALL records, regardless of sharing rules or ownership. Also grants View All. |
Permission dependencies:
- Create requires Read
- Edit requires Read
- Delete requires Read and Edit
- View All requires Read
- Modify All requires Read, Edit, Delete, and View All
View All and Modify All are powerful — they bypass the entire sharing model for that object. Use them sparingly, typically only for admins or data stewards.
Field-Level Security (FLS)
FLS controls access to individual fields on an object:
| Setting | What It Means |
|---|---|
| Visible ✓ Read-Only ✗ | User can see AND edit the field |
| Visible ✓ Read-Only ✓ | User can see but NOT edit the field |
| Visible ✗ | Field is completely hidden — not on page layouts, not in reports, not in list views, not via API |
FLS always wins over page layouts. If FLS hides a field, it doesn’t matter if the field is on the page layout — it won’t be visible. This is a critical concept:
Page Layout says: Show the field
FLS says: Hide the field
Result: Field is HIDDEN (FLS wins)
Page Layout says: Don't show the field
FLS says: Field is visible
Result: Field is NOT shown (page layout doesn't include it)
For a field to be visible to a user:
- FLS must grant visibility (profile or permission set)
- The field must be on the page layout (or the user accesses it via report/API)
Best Practices for Object and Field Permissions
-
Start restrictive, grant as needed. Use “Minimum Access” profile as the base. Add permissions through permission sets.
-
Use FLS to protect sensitive data. Social Security numbers, salary information, internal notes — hide them from profiles that don’t need them.
-
Don’t confuse object permissions with record access. Object permissions say “you can read Accounts.” Record access (sharing) says “you can read THESE specific Accounts.” Both must allow access for a user to see a record.
-
Audit FLS regularly. When you add new fields, they may default to visible for all profiles. Review and restrict as needed.
System and Application Permissions
Beyond object and field access, profiles and permission sets control hundreds of system permissions and application permissions.
System Permissions (Selected Important Ones)
| Permission | What It Grants |
|---|---|
| API Enabled | Access Salesforce via API (Data Loader, integrations, etc.) |
| Modify All Data | Full CRUD on ALL objects, ALL records. The nuclear option. |
| View All Data | Read access to ALL objects, ALL records. |
| View Setup and Configuration | Can view (but not modify) Setup pages |
| Manage Users | Create, edit, deactivate users and assign profiles/perm sets |
| Customize Application | Modify metadata — objects, fields, page layouts, etc. (admin permission) |
| Author Apex | Write and deploy Apex code |
| Manage Flows | Create and modify Flows |
| Run Flows | Execute Flows (most users need this) |
| View All Users | See all users in the org (vs. only users in the same role hierarchy) |
| Manage Public Reports/Dashboards | Create reports/dashboards in public folders |
| Export Reports | Export report data to CSV/Excel |
| Manage Sandboxes | Create and refresh sandbox orgs |
Application Permissions
Application permissions control access to specific Salesforce features:
- Manage Cases — Access to case management features
- Manage Knowledge — Create and publish Knowledge articles
- Mass Email — Send mass emails
- Create and Customize Reports / Dashboards
- Edit Events / Tasks — Manage calendar and task features
The Dangerous Permissions
Some permissions should be restricted to administrators only:
- Modify All Data — Can do anything to any record. Only System Admins.
- View All Data — Can see everything. Only when genuinely needed.
- Customize Application — Can change the org’s configuration. Admins only.
- Manage Users — Can change other users’ access. Admins only.
- Author Apex — Can deploy code. Developers in sandbox, admins in production.
Apex Class Access
Apex classes can be restricted by profile or permission set. If an Apex class is not enabled for a user’s profile (or a permission set they have), the user cannot execute that class.
Where This Matters
- Visualforce pages backed by Apex controllers — the user needs access to the controller class
- Lightning components backed by Apex — the user needs access to the Apex class
- REST/SOAP API endpoints implemented as Apex — API consumers need class access
- Invocable actions called from Flows — the user running the Flow needs access to the invocable class
How to Grant Apex Class Access
Via Profile:
- Setup → Profiles → Select profile
- Click “Apex Class Access” (in enhanced interface)
- Click “Edit”
- Move classes from Available to Enabled
- Save
Via Permission Set:
- Setup → Permission Sets → Select permission set
- Click “Apex Class Access”
- Click “Edit”
- Move classes from Available to Enabled
- Save
Best Practice
Don’t grant access to all Apex classes by default. Only enable the classes that the user’s workflows require. This is both a security measure (limiting what code can run) and a troubleshooting aid (if a class isn’t enabled, you know immediately why it’s failing for a user).
Custom Permissions
Custom permissions are admin-defined boolean flags that can be assigned via profiles or permission sets. They don’t grant any Salesforce capability on their own — they’re markers that your custom code, Flows, or Lightning components can check.
Why Use Custom Permissions?
Instead of checking a user’s profile name in code (fragile — what if the profile is renamed?), you create a custom permission and check for that:
// Bad — fragile, breaks if profile is renamed
if (UserInfo.getProfileId() == '00e...') { ... }
// Good — checking a custom permission
if (FeatureManagement.checkPermission('Can_Approve_Discounts')) { ... }
How to Create a Custom Permission
- Setup → Quick Find → “Custom Permissions”
- Click “New”
- Fill in:
- Label — e.g., “Can Approve Discounts”
- Name — API name
- Description — What this permission enables
- Connected App — Leave blank unless it’s for a specific connected app
- Click “Save”
How to Assign
Add the custom permission to a permission set or permission set group, then assign that to users.
Where to Check Custom Permissions
- Flows: Use the
$Permission.Can_Approve_Discountsglobal variable - Apex:
FeatureManagement.checkPermission('Can_Approve_Discounts') - Lightning App Builder: Component visibility rules can filter on custom permissions
- Validation Rules:
$Permission.Can_Approve_Discountsin the formula - Formula Fields:
$Permission.Can_Approve_Discounts
Common Use Cases
- Feature gating — Show/hide Lightning components based on a custom permission
- Bypass rules — Allow specific users to bypass a validation rule:
AND(NOT($Permission.Bypass_Validation), ...your_rule...) - Conditional actions — Show a “Approve Discount” quick action only to users with the custom permission
- License management — Use custom permissions to control access to features that aren’t tied to a Salesforce license
When to Use Profiles vs. Permission Sets vs. Permission Set Groups
This is the strategy question. Here’s the modern best practice:
Profiles: The Minimum Base
Use profiles for:
- Login settings — Login hours and IP ranges (only available on profiles)
- Page layout assignments — Profile + record type → page layout mapping
- The baseline minimum — Use “Minimum Access” as the starting point
Do NOT use profiles for: Granting object access, field access, or system permissions (use permission sets instead).
Permission Sets: Modular Permission Bundles
Use permission sets for:
- Object and field permissions — CRUD and FLS for specific objects
- System permissions — API access, Flow access, report permissions
- Feature access — Apex classes, custom permissions, connected apps
- Any permission that might need to be granted to users across different profiles
Design permission sets around capabilities, not roles:
- Good: “Account & Contact Management,” “Report Export,” “API Access”
- Bad: “Sales Rep Permissions” (that’s what groups are for)
Permission Set Groups: Role-Based Bundles
Use permission set groups for:
- Role-based assignment — Bundle the permission sets that a specific role needs
- Onboarding simplification — Assign one group instead of 5 permission sets
- Muting edge cases — When a group needs most but not all of a permission set’s grants
Design permission set groups around roles:
- “Sales Rep Permissions” = Account Management + Opportunity Management + Report Builder
- “Support Agent Permissions” = Case Management + Knowledge Access + Omni-Channel
- “Project Manager Permissions” = Project Access + Deliverable Management + Report Builder
The Modern Permission Model
User ← Profile (Minimum Access)
← Permission Set Group ("Sales Rep Permissions")
├── Permission Set: Account & Contact Management
├── Permission Set: Opportunity Management
├── Permission Set: Report Builder
└── Permission Set: Email Integration
← Permission Set: API Access (additional, direct assignment)
This model is:
- Modular — Permission sets can be reused across groups
- Auditable — Easy to see what a user can do by checking their group assignment
- Scalable — Adding a new capability = creating a new permission set and adding it to relevant groups
- Maintainable — Changing what “Sales Rep” means = updating one group, not 50 user assignments
Section Notes
-
Salesforce is moving away from profile-based permissions. The long-term direction is for profiles to handle only login settings and page layouts, with ALL functional permissions managed through permission sets and groups. Start building this way now.
-
“Minimum Access” is your friend. Always start with the most restrictive profile and add permissions through sets. If you start with “Standard User” and add permission sets, you can never take away what the profile grants.
-
Audit regularly. Use Setup → “Permission Set Assignments” and “Profile” reports to understand who has what. Salesforce also provides the “User Access and Permissions Assistant” tool in recent releases.
-
FLS is the most commonly misconfigured setting. New fields default to visible for most profiles. Create a process: every time you create a new field, explicitly set FLS for each profile. Don’t rely on defaults.
-
Test with a non-admin user. Admins have “View All Data” and “Modify All Data” — they can see and do everything. Always test permissions by logging in as (or proxy into) a non-admin user with the target profile.
-
Permission set groups replaced the need for “hybrid profiles.” If you have profiles like “Sales Rep + Marketing” or “Support + Knowledge,” that’s a sign you should be using permission set groups instead.
-
Document your permission model. Create a spreadsheet or diagram that maps: Role → Profile → Permission Set Group → Permission Sets. When someone asks “why can’t I see this field?” you can trace the answer in seconds.
Project: Set Up Permissions for 2 User Personas
The Scenario
Your org has the Project and Deliverable custom objects from previous sections. You need to set up permissions for two user personas:
Persona 1: Project Manager
What they need:
- Full CRUD on Projects and Deliverables
- Can see all Project fields including Budget
- Can create and edit Reports
- Can export report data
- Can run Flows
- App access: Project Management app
Persona 2: Team Member
What they need:
- Read + Edit on Projects (no Create, no Delete)
- Read + Create + Edit on Deliverables (no Delete)
- Cannot see Budget field on Projects
- Can view Reports but not create or export
- Can run Flows
- App access: Project Management app
Your Tasks
1. Create the Base Profile:
- Clone “Minimum Access - Salesforce” → Name: “Project Team Member”
- Set login hours: Monday–Friday, 7 AM–8 PM
- No object permissions yet (we’ll use permission sets)
2. Create Permission Sets:
“Project Full Access”
- Project__c: Read, Create, Edit, Delete
- Deliverable__c: Read, Create, Edit, Delete
- All Project fields visible and editable (including Budget)
- All Deliverable fields visible and editable
“Project Limited Access”
- Project__c: Read, Edit
- Deliverable__c: Read, Create, Edit
- All Project fields visible EXCEPT Budget (set Budget to not visible)
- All Deliverable fields visible and editable
“Report Builder”
- System Permission: Create and Customize Reports
- System Permission: Create and Customize Dashboards
- System Permission: Export Reports
“Report Viewer”
- System Permission: Run Reports (usually on by default, verify it’s enabled)
- No create/export permissions
“Flow Runner”
- System Permission: Run Flows
3. Create Permission Set Groups:
“Project Manager Permissions”
- Includes: Project Full Access, Report Builder, Flow Runner
“Team Member Permissions”
- Includes: Project Limited Access, Report Viewer, Flow Runner
4. Assign:
- Create two test users (or use existing ones)
- Assign both the “Project Team Member” profile
- Assign “Project Manager Permissions” group to User 1
- Assign “Team Member Permissions” group to User 2
5. Test:
-
Log in as (or proxy into) the Project Manager user:
- Can create a Project? ✓
- Can see Budget field? ✓
- Can export a report? ✓
- Can delete a Deliverable? ✓
-
Log in as the Team Member user:
- Can create a Project? ✗ (should fail)
- Can see Budget field? ✗ (should be hidden)
- Can export a report? ✗ (option should not appear)
- Can edit a Deliverable? ✓
- Can delete a Deliverable? ✗ (should fail)
Next up: Record Access — the sharing model that controls which specific records a user can see, beyond object-level permissions.
This is Part 10 of the Salesforce series. Next: Record Access — understanding the record access pyramid, OWD, roles, sharing rules, and manual sharing.