Building and Publishing a Secure Salesforce App — Step-by-Step
A complete practical guide for Salesforce developers to go from idea to AppExchange-ready managed package — with a focus on FLS compliance, security review, and packaging best practices.
1. Plan the App
Every successful Salesforce app starts with clarity of purpose and clean architecture.
Key planning actions:
- Define use cases and target profiles early.
- Model your data around least privilege access.
- Use Custom Metadata Types for configuration instead of hardcoding.
- Decide whether your app will be 1GP or 2GP (more on this below).
A well-structured data model simplifies testing, upgrades, and packaging later.
2. Build Securely
Security is not optional — every Apex, LWC, and SOQL must enforce Salesforce security layers: CRUD, FLS, and Sharing.
Use
1with sharing1@AuraEnabled(cacheable=true) 2public static List<Account> getAccounts() { 3 List<Account> accs = [SELECT Id, Name, Phone FROM Account]; 4 return (List<Account>) Security.stripInaccessible(AccessType.READABLE, accs); 5}
UI (LWC) best practices:
- Show or hide controls based on access metadata.
1uiRecordApi - Use with
1@wireto minimize load.1cacheable=true - Avoid hardcoded field names — reference schema dynamically when possible.
3. Test and Automate
Before packaging, validate functional and permission behavior.
Checklist:
- Use to simulate user profiles in tests.
1System.runAs() - Add positive and negative test cases for CRUD/FLS.
- Ensure ≥ 75% code coverage (required for deployment).
- Automate CI/CD with SFDX CLI + GitHub Actions or Bitbucket Pipelines.
- Include automated PMD or SFDX Scanner runs in your build.
4. Understand 1GP vs 2GP
Salesforce supports two packaging generations. Choosing the right one impacts maintainability and upgrade path.
| Feature | First-Generation (1GP) | Second-Generation (2GP) |
|---|---|---|
| Packaging Location | Developer Org | Dev Hub + Scratch Orgs |
| Source Control | Metadata API files | SFDX Source format |
| Namespace | Assigned manually | Defined in Dev Hub |
| Versioning | Manual | Semantic + Automated |
| Dependencies | Not supported | Supported (cross-package) |
| Security Review | Mandatory | Mandatory |
| Deployment | Uploaded via Packaging UI | CLI-driven (sfdx force:package:version) |
| Upgrade Path | Manual | Seamless via Subscriber Package Version |
Recommendation:
Always use 2GP for new apps — it’s modern, source-driven, and DevOps-friendly.
5. Migrating from 1GP to 2GP
Many legacy apps still use 1GP. Migrating unlocks CI/CD, dependency management, and simplified version control.
Migration Steps:
- Set up a Dev Hub and enable Second-Generation Packaging.
- Create a new namespace (must match or alias the old one).
- Convert metadata to SFDX source format:
1sfdx force:source:convert -r force-app -d mdapi_output_dir - Create a package in Dev Hub:
1sfdx force:package:create -n "MyApp" -t Managed -r force-app - Create package versions using scratch orgs:
1sfdx force:package:version:create -p "MyApp" -x -w 10 - Test installation in a fresh org.
- Request namespace connection (if same namespace was used in 1GP).
- Submit for security review under the new managed package.
⚙️ Tip: Treat migration as a re-packaging process — your business logic remains the same; only the delivery model changes.
6. Secure for Review
Before submitting to AppExchange:
- Run SFDX Scanner and Checkmarx (if available).
- Verify all APIs use HTTPS.
- Remove hardcoded credentials or endpoints.
- Provide security review documents — Data Flow, Permission Sets, Integration Overview.
- Ensure your app gracefully handles permission denials.
Example:
1if(!Schema.sObjectType.Account.isAccessible()) { 2 throw new SecurityException('Access denied to Account'); 3}
7. Prepare the Listing
The AppExchange listing is your storefront.
Must-haves:
- Clear value proposition and screenshots.
- Demo video or animated walkthrough.
- Installation guide and support email.
- Transparent pricing (even if free).
- SEO-friendly description and keywords.
8. Submit for Salesforce Security Review
Salesforce reviews every managed package to ensure:
- CRUD/FLS compliance
- Proper permission set usage
- Secure data handling
- Authentication flow adherence
Expect minor iterations after initial submission. Once approved, your app becomes publicly available.
✅ Case Study — Record Marker
To demonstrate the entire process, our team built Record Marker, a lightweight Salesforce utility to tag and organize records with a single click.
Highlights:
- Developed using 2GP managed package.
- CRUD/FLS enforced via .
1Security.stripInaccessible - Custom LWC for marking and viewing tagged records on the home page.
- Minimal setup — works with any standard or custom object.
- Passed Salesforce Security Review and published live.
AppExchange Listing:
Record Marker
Conclusion
Salesforce app development goes beyond Apex and Lightning — it’s about building secure, scalable, and review-ready software.
By adopting 2GP, enforcing CRUD/FLS compliance, and automating your pipeline, your team can confidently move from concept to AppExchange listing — exactly as we did with Record Marker.
Ready to Build Your Own App?
Tirnav Solutions specializes in Salesforce product engineering and AppExchange packaging.
Book a quick 30-minute consultation — we’ll help you evaluate architecture, namespace setup, and review readiness.






