When working with a Private Organization-Wide Default (OWD) setting for the Account object in Salesforce, maintaining security and access control is essential. However, it often introduces a challenge: newly created records are visible only to the owner, limiting collaboration across departments or teams. If your use case requires automatic sharing of records—particularly with users on the “Standard User” profile—manual sharing or complex configuration rules are not always the best route.
That’s where this blog comes in.
In this post, you’ll learn how to solve a real-world scenario using a Salesforce Apex Trigger that automatically shares newly created Account records with an active user who holds the Standard User profile, and gives them Edit-level access to both Account and related Opportunity records. The best part? It works flawlessly in orgs where Account OWD is set to Private, without needing any manual intervention, sharing rules, or third-party tools. We’ve also included a clean trigger-handler structure to make this solution scalable, easy to understand, and reusable for other objects or sharing needs.
🚀 Why This Use Case Matters
In enterprise-grade Salesforce orgs, it’s common to restrict Account visibility using private OWD settings. But real-time collaboration is equally important. Imagine a customer success executive or operations user who needs to view and update every new Account created by the sales team. Instead of relying on them to request access or wait for sharing rules to kick in, this automated Apex-based solution grants them access instantly upon record creation. This is a classic example of controlled automation using code, enhancing productivity without compromising on security.
🔍 What You’ll Learn in This Blog
-
How to write an Apex Trigger on the Account object using
after insert
-
How to build a trigger handler class to keep logic separate and clean
-
How to query the Standard User profile and active users
-
How to use the AccountShare object to programmatically grant access
-
How to avoid common pitfalls while inserting share records (e.g., timing, limits)
-
Why choosing the correct RowCause (Manual) is important
-
How this integrates into broader Salesforce record-sharing strategies
🛠️ Technical Implementation Highlights
The core of this solution is a simple after insert
trigger that passes the list of newly created Accounts to a handler class. The handler then:
-
Queries the Standard User profile ID
-
Retrieves an active user from that profile (you can modify this to use a group or multiple users)
-
Loops through the Account list and creates corresponding AccountShare records
-
Sets
AccountAccessLevel
andOpportunityAccessLevel
to Edit -
Inserts the list of share records in bulk, respecting governor limits
The code snippet is lightweight, efficient, and follows best practices—ideal for developers and admins looking to create secure and robust sharing automations.
🎯 Who Should Use This Solution?
-
Salesforce Admins who want to offer more flexibility without relying solely on declarative sharing rules
-
Developers who need to control sharing through Apex in highly secure orgs
-
Salesforce Architects planning scalable sharing strategies in multi-profile environments
-
Consultants building solutions for clients in real estate, healthcare, finance, or any vertical where Account visibility must be tightly controlled but selectively shared
🎥 Learn by Doing – Watch the Walkthrough
To make implementation even easier, we’ve included a YouTube playlist that walks you through this setup step-by-step. Whether you’re a visual learner or want to follow along in your own dev org, this guide ensures that every line of code makes sense and delivers impact.
Solution:
trigger AccountTrigger on Account (after insert) {
if(Trigger.isInsert){ if(Trigger.isAfter){
AccountTriggerHandler.shareAccWithStdUser(Trigger.new);
}
}
}
public class AccountTriggerHandler{ public static void
shareAccWithStdUser(List<Account> accList){
Id standartUserId = [SELECT Id FROM Profile WHERE
Name=’Standard User’].Id;
List<User> listOfUserId = [SELECT Id FROM User WHERE
ProfileId= :standartUserId AND IsActive=True LIMIT 1];
List<AccountShare> accShareList=new List();
for(Account acc:accList){
AccountShare aShare= new AccountShare();
aShare.UserOrGroupId=listOfUserId[0].Id;
aShare.AccountId=acc.Id;
aShare.RowCause=’Manual’;
aShare.AccountAccessLevel=’Edit’;
aShare.OpportunityAccessLevel=’Edit’;
accShareList.add(aShare);
}
if(!accShareList.isEmpty()){ insert accShareList;
}
}
}