Understand Apex Metadata API and Security
As you’ve seen, Apex Metadata API gives you the power to automate changes to an org’s configuration. But changing the structure of an org has security implications for the data in that org. What if an unauthorized app modifies your org? We won’t keep you in suspense—that can’t happen! Trust is our number one value at Salesforce, and the Apex Metadata API is built to be a trusted interface.
Three features of Apex Metadata API safeguard your orgs and data.
- Restrictions on the types of metadata that can be created or modified.
- Restrictions on the apps that can deploy changes.
- Detailed audit histories that track metadata changes.
With these features, you can “trust, but verify.” The first two features let you trust the functionality of apps that use Apex Metadata API. The third feature lets you verify the app’s behavior. Let’s look at how these features work.
To ensure security, Salesforce restricts the types of metadata that can be created or modified with Apex Metadata API. The initial release of Apex Metadata API allows you to work with two metadata types: page layouts and records of custom metadata types. Although we intend to support more metadata types in the future, we won’t expose the entire Metadata API in Apex. This careful approach to supporting metadata ensures that installed packages can work only with safe metadata types, which can be modified in predictable ways.
Salesforce also doesn’t allow creating Apex classes, Visualforce pages, or Lightning components via Apex. As you can imagine, if managed packages could write code in a subscriber org, it would be difficult for Salesforce to enforce security for the package. In addition, to ensure that installed apps only modify metadata types in predictable ways, Salesforce doesn’t support automated code generation.
In addition to restricting the types of metadata that can be created or modified, Salesforce limits which packages can deploy metadata via Apex. Apex Metadata API can execute deployments in only three scenarios:
- From certified managed packages that are provided by known, registered ISVs.
- From uncertified managed packages, but only if the subscriber org enables a specific Apex setting, which we discuss shortly.
- From unmanaged packages, which means that the code is owned by the org that executes it.
Feeling better? These restrictions ensure that the deployment is coming from a trusted entity.
Salesforce provides an Apex setting that allows uncertified managed packages (which Salesforce hasn’t approved via security review) to execute metadata deployments. It goes by the catchy name of Deploy Metadata from Non-Certified Package Versions via Apex, and it’s located under Setup | Apex Settings. Apex classes in an uncertified package can’t access metadata (public or protected) unless this setting is enabled.
By enabling this setting, ISVs can test managed packages that aren’t yet certified, and enterprises can use managed packages to test or update their apps. But as long as it’s turned off for your org, you can rest assured that no uncertified package can modify your org.
The following table shows how this setting controls deployment for different package types.
|Deploy Metadata Apex setting on||Yes||Yes||Yes|
|Deploy Metadata Apex setting off||Yes||No||Yes|
You can verify the behavior of managed packages in the Setup audit trail log. All metadata operations that use the Apex Metadata API are tracked in the log. The namespace of the code performing the deployment is recorded, which means that you always know which namespace made changes and when the changes were made. The Setup audit trail log is located under.
We’ve seen how Salesforce ensures that Apex Metadata API is a trusted interface by:
- Restricting the types of metadata that can be modified.
- Controlling the types of packages that have access to metadata.
But a managed package operating within these constraints can modify metadata outside its own namespace. So, as a developer, there are a few more things to know, so that you can modify metadata responsibly.
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 managed packages, so you can track these changes.
- Protected metadata in a managed package is accessible by Apex code in the same namespace, but it isn’t visible to the subscriber org or other namespaces.
All metadata created by a managed package’s Apex is created in the subscriber namespace. You can think of the managed package as creating metadata on the subscriber org’s behalf. The following table shows how the namespace of a managed package, a subscriber org, or a different managed package can access metadata.
|My namespace||Subscriber namespace||A different managed package|
|Developer-controlled public metadata||Read||Create, Read, Update||Read|
|Developer-controlled protected metadata||Read||No Access||No Access|
|Subscriber-controlled public metadata||Create, Read, Update||Create, Read, Update||Create, Read, Update|
|Subscriber-controlled protected metadata||Create, Read, Update||No Access||No Access|
Keep the following points in mind when working with metadata in Apex. A managed package’s Apex can:
- Update any public subscriber-controlled metadata, whether it’s in the same package, the subscriber org, or a different managed package.
- Update protected subscriber-controlled metadata in its own namespace. This ability to access protected metadata makes Apex Metadata API a great tool for securing more of your app. You can hide your app configurations as protected metadata and still manipulate them with Apex.
- Update developer-controlled metadata only if it’s in the namespace of the subscriber org. For example, if Apex in the managed package creates a record of a custom metadata type, that record is in the subscriber namespace. Code in the managed package can update any of the fields.
A managed package’s Apex can’t 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.
Still with us? Don’t worry, there won’t be a quiz. Oh wait, this is Trailhead, there will be a quiz!
The Metadata API itself adds a layer of trust. Apex Metadata API deployments always respect Metadata API permissions. Although you can write Apex code that lets end users enqueue a deployment, that deployment fails if the users don’t have the correct Metadata API permissions.
In contrast, retrieve calls from the Apex Metadata API work for any users your app has granted access to. As more metadata types are exposed in Apex, retrieve calls can be a handy way to provide read access to information not available in describe requests.
If you’re a developer in an ISV, there are a few things to keep in mind as you use Apex Metadata API:
- To pass security review, you must include a notice letting customers know that the app can modify their metadata.
- When testing an uncertified managed package, you must enable the Apex Deploy Metadata setting in the subscriber org.
- Only page layouts and records of custom metadata types are supported.
- Delete is not supported.
You now understand how Apex Metadata API enables you to build automation for many types of metadata changes. You can create scripts and setup experiences that update metadata using the power of Apex. We’ve only scratched the surface of what Apex Metadata API can do, and we hope you build great things with Apex Metadata API. Come visit us in the Apex Metadata API Chatter group in the Trailblazer Community.
- Apex Developer Guide: Security Considerations