On 4th Aug 2023 I successfully listed a solution (edf.) on Salesforce AppExchange. Here are my key take aways and detailed guide on the security review process from the experience.
Create a Listing
The UI of partner portal for listing has been completely revamped and now it has much crispier and fluid UX. Navigation is simpler with a clear set of step by step instructions - more like a wizard.
The very first step (after registering with partner portal) is to create a listing. Creating a listing requires details like Logo, Title and Tagline. Below are the screenshots of how each of these information will be shown on AppExchange after it is successfully published.
Thereafter additional details like:
- Brief description
- any pre-requisites viz. mandatory features, licenses to be available beforehand for your solution to work
- what are the clouds, editions and language that your solution is compatible with
- list of components
- and an optional demo video link hosted on platforms like YouTube, vimeo etc.
You can skip the Link Solution section for now and move to the highlights section if your packaging is not ready yet. The highlights sections can be utilised to list the features and link to documentation if any.
Link a Solution
Unmanaged vs. Managed Beta vs. Managed Released package
Once your solution is ready you will have to connect your org with the partner portal under solutions tab. Primarily the below points needs to be noted w.r.t to package types listed above
- You cannot have a public listing of your package if it is Unmanaged (private listing doesn't show up in search results on appexchange). Unmanaged packages obviously cannot be upgraded. Also, you cannot have a paid listing of your package if it is Unmanaged.
- Managed Beta versions of your package won't show up in the portal and so you cannot link them in the listing
- Managed Released version is the ideal option for appexchange. You can have multiple versions released and the same will be available for linking in your listing.
- With the new upgrade once your solution passes security review you need not re-review the later versions. You can directly update your listing with the new released version and the same will be available for download on appexchange.
- For publishing a solution as paid app on appexchange the price of security review is a whopping $999 else it is free. Paid listing by partners will require some more additional info not described in this article.
- In order to be able to push upgrades to customers (who might have already installed your solution prior to upgrades in your solution e.g. bug fixes, new features etc.) your package must have passed security review. After this under package versions tab in package manager option of your org you will have an option to Push Upgrades. The first time you click it you will see an option to request enabling push upgrades from Salesforce. After its enabled you can push upgrades (selectively) to the customer orgs.
If you have apex classes in your code you won't be able to upload and release your package if sufficient coverage from test classes is not present.
Released packages sometime takes 1-2 hrs to reflect in the portal. Also do not delete your initial package or else you will have to repeat the entire review process.
Once you link your solution, it will show info saying it is pending security review and a link to submit the same. Once you click the link you will have to provide the below documents and information.
Static Code Analysis Report
A report of static code analysis of your package in Visual Studio Code using Salesforce static code analyser. This isn't mandatory and you can check a checkbox that read "I did not use the static code analyser". A link to instructions on how to use the static code analyser will be available in the portal.
Checkmarx · Chimera · ZAP
- A scan report from one or more of the above tools.
- ZAP is required only if there are external integrations.
- Do not submit for review if there is even a single High Risk security detected by Checkmarx or Chimera. Fix them, repackage and only then submit for security
- There might be some medium/low risk security detected which you are sure are either incorrect or cannot be fixed because of the way your solution is designed then, in such cases you can submit a False Positive Document (a link to template will be available in the portal). You can describe the component that is incorrectly posed as security threat and give your justifications.
Logins for test environment
Other than the packaging org you will need one more fresh org (Developer Edition (DE) or Enterprise Edition (EE) only) as a testing ground for review team. The login details of any user of this org should be provided in the security review form.
If there are any external systems that you call in your solution, then details of a test environment of that system too should be provided.
Finally my key takeaways
Common Security threats that can be avoided
- Do not use
API Keyin any combination in any of the field names or storage components like metadata etc. even if the actual use is not to store any secrets like passwords, tokens, api keys etc. There are best practices regarding storage of secrets that should definitely be followed and Salesforce is very strict about it. And so the automation will reject the review even if there is a slightest of a hint that it is being violated.
- I had a field api name as
field_api_key__con a custom object and it was just a formula field that had the lowercase of field api name. Thats it no secrets 😐. Yet the review got rejected since the automation possibly identified it as a secret storage. I renamed the field label and api name, resubmitted and this time it was not flagged.
- I had a field api name as
- Do not hardcode any type of keys, tokens or secrets in apex code. Though apex code won't be visible in managed packages it is not allowed.
with sharingin all your apex classes. No excuse here
with sharingonly ensures record sharing. If you have any DMLs in your apex enforce object and field level sharing. More info here
- Dynamic SOQL string should use
String.escapeSingleQuotes()on the query string.
- Finally LWC- the component code will be scrutinised for any malicious or unintentional exposure to injection attacks. E.g. The use of
innerHTML()to dynamically insert an html snippet. Use
htmlencodefunction to escape any special characters in the text before passing it to
Even after all these care, your security review does not pass (chances are it might not) you will receive an email with a report on the security vulnerabilities detected in your solution and possible fixes. If those detection doesn't make any sense or it is just not possible to make those fixes; again because of the way your solution is designed - you can schedule an appointment with the security review team to explain and justify your design (I haven't gone through this step)
Some wisdom. Don't give up
It took 24 days 🤧 from this...
to this 😇