In my last post I introduced the all-new Apex Metadata API. In this post we will take a look at the security aspects of this new feature.
When discussing this new API with customers, partners, and Salesforce employees, security is often the first topic raised. The Apex Metadata API empowers developers to automate changes to an org’s configuration. Changing the structure of an org is a big deal, and also has big implications for the data in that org.
Trust is our number one value at Salesforce, and the Apex Metadata API is built to be a trusted interface. Three features provide secure access to an orgs’ metadata:
- Restrictions on the types of metadata that can be created or modified
- Restrictions on the apps that can execute a deploy
- Detailed audit history to track metadata changes
With these features you can “trust, but verify.” The first two help you trust the functionality of apps using the Apex Metadata API. The third lets you verify the app’s behavior.
Trust safe metadata types
While we intend to support many more types of metadata than the two in this debut of the Apex Metadata API, we will not expose the entire Metadata API in Apex. This assures customers that packages they install can only modify safe metadata types — types that get modified in predictable ways.
For example, we will not provide the ability to create Apex classes, Visualforce pages, or Lightning components via Apex. If managed packages have the ability to write code in a subscriber org, it becomes difficult for Salesforce to review their security profile. To assure customers that apps they install only modify metadata types in predictable ways, we will not support automated code generation.
Protect your org from unknown apps
In addition, we’re limiting which packages can execute a metadata deploy via Apex. The Apex Metadata API can be executed in three scenarios:
- The code that does the deploy is in a certified managed package.
- The subscriber org has turned on a setting to allow execution by uncertified managed packages.
- The code is unmanaged and thus owned by the org that executes the code.
These restrictions ensure that the deploy is coming from a trusted entity. Metadata changes can be made by a certified managed package, which is provided by a known, registered ISV. Partner apps in AppExchange that can make metadata changes in a subscriber org will alert subscribers. Partner apps must include this notification to pass the AppExchange security review.
Metadata changes can also be made by code that is known to the org in question. The latter can be unmanaged code developed or installed and vetted in the org itself. Or it can be uncertified managed code, but only if the subscriber has explicitly allowed it. Uncertified managed packages can only do metadata operations if the subscriber has set the Apex setting shown on the right.
With this setting ISVs can test managed packages that aren’t yet certified, and enterprises can use managed packages to manage their apps.
These scenarios are summarized in the following table that shows which permissions and settings are needed to use Apex Metadata API.
Verify app behavior with setup audit trail
All metadata operations using the Apex Metadata API are tracked and the namespace of the code performing the deploy is recorded in the setup audit trail. You always know which namespace made what changes and when. This is where you verify the behavior of your trusted apps.
Use your great power responsibly
Apex Metadata API deploys can modify metadata outside its own namespace. This is necessary to support many important use cases. But it makes some people nervous, so let’s look at the implications.
Knowing what metadata can get updated and how will help you make the right choices about how to use this API. But before we dig into the details, it’s important to understand that managed Apex manipulates metadata in a subscriber org in the same way that unmanaged Apex does, with two exceptions:
- Setup audit trail logs include the namespace of the managed package.
- Protected metadata inside of a managed package is accessible by Apex code in the same namespace, even though it isn’t visible to the subscriber org or other namespaces.
A managed package’s code does a deploy on behalf of the subscribing org. If you remember this, everything else is intuitive.
All metadata created by a managed package’s Apex is created in the subscriber namespace. Managed Apex never creates metadata that has the same namespace as the package the code is running from.
A managed package’s Apex can update any metadata in the org where the metadata is subscriber-controlled and the metadata is visible from within the managed package’s namespace. Therefore, it can update any public subscriber-controlled metadata, whether it’s in the same package, the subscriber org, or a different managed package.
It can also update private subscriber-controlled metadata in its own namespace. If you are a managed package developer, this makes the Apex Metadata API a great tool for securing more of your app. You can now hide your app configurations as protected metadata and still manipulate them with Apex.
Apex in a managed package can update developer-controlled metadata only if it’s in the subscriber org namespace. For example, if Apex in the managed package creates a record of a custom metadata type, that record will be in the subscriber namespace. Code in the managed package can update any of the fields. However, Apex cannot update developer-controlled fields of records contained in its own package, even though they’re in the same namespace. That metadata can only be updated with a package upgrade.
Some of this may seem counterintuitive. If so, remember that aside from its ability to access protected metadata, the code acts like non-namespaced code, but with an audit trail showing the namespace of the Apex that made the change. With the exception of protected metadata, all the capabilities and limitations I just described are the same capabilities and limitations an admin in the subscriber org has.
Here’s how that plays out in all the scenarios you may encounter:
Deploys respect Metadata API permissions
The Metadata API itself adds an additional layer of trust. Metadata API permissions are respected by an Apex Metadata API deployment. While Apex lets you write code that enables end users to enqueue a deployment, that deployment will fail. Only users who can already do a Metadata API by other means will be able to do it in Apex.
In contrast, retrieve calls from the Metadata API work for any users your app has granted access. As more metadata types are exposed in Apex, this will be a handy way to provide read access to info not available in metadata describes.
Rely less on remote site settings
Some developers leverage remote site settings and call the Metadata API from their app. This provides the same capabilities as the Apex Metadata API, but lacks most of the security controls. The Summer ‘17 release marks the beginning of the end to this approach (or the complete end if you only rely on remote site settings to update custom metadata records or page layouts).
Using the Apex Metadata API has many advantages over code that relies on remote site settings. The Apex Metadata API enables you to:
- Keep an org isolated from outside access
- Know that only allowlisted metadata types are being deployed
- Use the setup audit trail to track which namespace made the change
- Access protected metadata in your own namespace so you can hide more of your configuration data from subscriber orgs.
In addition to the security benefits, the Apex Metadata API is much easier to use! Wrapping the Metadata API and calling it from Apex requires a lot more code than using this new native solution. And remote site settings can be challenging for partners with a large, low-touch customer base. It isn’t difficult to guide a few large customers through the remote site setting setup. But if you have thousands of customers, this is a manual step that many admins can overlook or do incorrectly, which can prevent your code from functioning properly.
Prepare for your security review
If you’re a developer in an ISV, there are a few things to keep in mind as you use the Apex Metadata API:
- To pass security review you must put a notice letting customers know that the app can modify their metadata.
- When testing an uncertified managed package you must flip the Apex setting in the subscriber org.
- Only allowlisted types are supported, which at the time of this writing, are limited to page layouts and custom metadata types.
- Delete is not supported.
Be powerful and be safe
As with any great power, this one comes with great responsibility. We have therefore provided many features to maximize the safety of the Apex Metadata API. These features enable you to trust the apps you and others build, but verify their behavior.
Check out my previous post for an overview of the Apex Metadata API. Keep an eye out for follow up posts diving deeper into the setup UI and post install script use cases. And join us at TrailheaDX June 28-29 to see the new Apex Metadata API in action!
Then go forth, build some cool stuff, and tell us all about it in the Success Community’s Apex Metadata API group. And be safe!
About the author
Aaron Slettehaugh is senior director of product management for the Salesforce platform. He has launched several products beloved by Salesforce developers, including custom metadata types and now the Apex Metadata API.
Before joining Salesforce, Aaron helped launch the global operations of an African NGO, led the product team at IaaS provider Joyent, and started a company and led it to acquisition by Citrix. He has an MBA from Stanford University and a bachelor in engineering.