---
schema_version: "1"
id: 7c9aaa8a252ebfffc046836fa151d088593b6f43e37f9add8d40206c97af9c12
title: Protection and Privacy Options for Custom Metadata Types
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/platform/264-0-0/custommetadatatypes_protection.md
canonical_url: https://help.salesforce.com/s/articleView?id=platform.custommetadatatypes_protection.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: efb3493c6aa9e1d3ae37dcbb0ab6dc5f5d0033d0f496f6714f0ab340f8535dcc
description: Manage the visibility and permissions of custom metadata types.
products:
  - Salesforce Platform
release: "264"
---
# Protection and Privacy Options for Custom Metadata Types

Manage the visibility and permissions of custom metadata types.

### Required Editions

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small edition">
      <colgroup>
        <col>
      </colgroup>
      <tbody>
        <tr class="">
          <td class="slds-cell-wrap" style="vertical-align:top;">Available in: Salesforce Classic and Lightning Experience</td>

        </tr>
        <tr class="">
          <td class="slds-cell-wrap" style="vertical-align:top;">
            <p>Available in: <strong>Enterprise</strong>, <strong>Performance</strong>,
              <strong>Unlimited</strong>, and <strong>Developer</strong> Editions
            </p>
            <p style="margin-bottom:0;">You can create, edit,
              and delete custom metadata type records from installed packages in:
              <strong>Group</strong> and <strong>Professional</strong> Editions
            </p>
          </td>

        </tr>
      </tbody>
    </table>

## Packages

For sensitive data, like application secrets, it’s important that custom metadata types are included in a managed package. When contained in a managed package and set to protected or package protected, they’re not visible to subscribing orgs, making it a good place to store certain kinds of secrets.

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-platform-extend_code-264-0-0-production-enus/789bc523-706b-4ae4-8fe9-be6322e38b6b/images/icon_note.png)

Note

Protected custom metadata types in an unmanaged package behave like public custom metadata types. Make sure that secrets, personally identifying information, or any private data is stored in protected custom metadata types that are installed as part of a managed package.

## Visibility

You can create protected custom metadata types in developer and scratch orgs. These options for custom metadata types are available.

- PackageProtected—When in a second-generation managed package, only Apex code in the same managed package can see the type. The name of the type and the record are visible if they’re referenced in a formula.
- Protected—When in a managed package, only Apex code in the same namespace can see the type. The name of the type and the record are visible if they’re referenced in a formula.
- Public—Regardless of the type of package (managed or unmanaged), these have access.
    - Apex
    - Formulas
    - Flows
    - API for users with Customize Application permission or permissions granted through profiles or permission sets. The custom metadata type, fields, and unprotected records are visible in Setup.

## Schema Settings

The Schema Settings option, Restrict access to custom metadata types, is an org-wide preference that limits access to custom metadata types. This preference is enabled by default, and API Read access to custom metadata types must be explicitly granted. Admins with Customize Application permission can grant access to users through profiles and permission sets.

## Behavior of Apex, Visualforce, and Aura

There are different execution code modes within Salesforce that affect the accessibility of custom metadata types.

Apex code that runs in system mode ignores user permissions, and your Apex code has access to all objects and fields. Object permissions, field-level security, and sharing rules aren't applied for the current user. Running in system mode ensures that the code doesn’t fail because of hidden fields or objects for a user.

In user mode, functionality such as Visualforce Components, Visualforce Email templates, and Aura, runs with respect to the user's permissions and sharing of records.

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-platform-extend_code-264-0-0-production-enus/789bc523-706b-4ae4-8fe9-be6322e38b6b/images/icon_note.png)

Note Functionality that runs in system mode, such as Apex, isn’t affected by the Restrict access to custom metadata types org preference. Also, the `with sharing` modifier in the Apex class, doesn’t affect query behavior such as, `isAccessible()` and `isCreatable()`. If a field value is retrieved in Apex and assigned to a non-sObject variable, the behavior is the same whether or not the preference is enabled.

When functionality is run in user mode, such as Visualforce Components, Visualforce Email templates, and Aura, you must have permission to access the custom metadata types. For example, without permission, the fields on Visualforce pages that you don't have access to aren’t displayed. The `$Setup` global variable (available in Visualforce and formulas) continues to load values by direct reference (meaning, data that’s assigned to an sObject type) regardless of the running user.

Consider this scenario:

- (1) Apex loads a record that’s a row included in a variable such as `MyCMT__c`.
- (2) What Visualforce displays is `MyCMT__c.MyPath__c`.
- (3) Access checks run when the page is loaded.
- (4) But the checks aren’t run in system mode, which is the standard Visualforce behavior. Users without permission to the custom metadata type can’t display the Visualforce page because Visualforce reinitiates the access check.

In this scenario, if a user isn’t allowed permission to the custom metadata type, there are two workarounds. You can create a string for each object, which can be passed through, or create a wrapper class. Use these options instead of assigning a variable such as `MyCMT__c`, then rendering `myCMT.Path__c myCMT.Name`. For example,

```java
class DataHolder{
public string path {get;set;}
public boolean active {get;set;}
}
```

When you load the rows into a collection, the Visualforce checks are bypassed because the type is a data type instead of an sObject.

Here’s an example that includes the `@AuraEnabled` annotation for an Aura or Lightning component controller.

```java
class with sharing MyController {
    @AuraEnabled
    public static List<My__mdt> thisWillNotWork() {
         return [select developername from my__mdt];
    }
    @AuraEnabled
    public static List<String> thisWill() {
        List<String> retVal = new List<String>();
        for(My__mdt config: [select developername from my__mdt]) {
            retVal.add(config.DeveloperName);
        }
        return retVal;
    }
}
```

## Retrieving Custom Metadata Type Information

When you retrieve custom metadata type records or a count of custom metadata types, the number returned by SOQL, Apex, formulas, flows, or APIs can differ from the number in the user interface. This difference is because of the custom metadata type visibility settings and the access that a user has to the type based on profiles and permissions.

#### See Also

- [Control Read Access to Custom Metadata Types](https://help.salesforce.com/s/articleView?id=platform.custommetadatatypes_permissions.htm&release=264.0.0&type=5 "Admins with the Customize Application permission can grant Read access to specific custom metadata types through profiles and permission sets.")