All metafields and metaobjects have permissions that control who can read or write to them. > Note > Metafield and metaobject [permissions are being simplified](/changelog/simplifying-how-metafield-and-metaobject-permissions-work) in the first half of 2025. ## How it works Both metafields and metaobjects offer permissions based on their [ownership type](/docs/apps/build/custom-data/ownership) with the following defaults: - **Merchant owned**: Readable and writeable by anyone in the Shopify admin. Not available by default in storefronts or customer accounts. - **App owned**: Readable by only merchants and the owning app in the Shopify admin. Not available by default in storefronts or customer accounts. Overriding default permissions requires a definition to exist. With that, you can set permissions in the `access` input with the [`MetafieldAccessInput`](/docs/api/admin-graphql/latest/input-objects/MetafieldAccessInput) and [`MetaobjectAccessInput`](/docs/api/admin-graphql/latest/input-objects/MetaobjectAccessInput) input objects respectively. The following explains the permissions for each surface: ### Admin `admin` controls permissions for both the Shopify admin and the [GraphQL Admin API](/docs/api/admin-graphql). For app-owned metafields and metaobjects:
Permission Description
MERCHANT_READ The metafield or metaobject will be readable by merchants through the Shopify admin.

Only the owning app can read and write to it using the GraphQL Admin API.
MERCHANT_READ_WRITE The metafield or metaobject will be readable and writable by merchants via the Shopify admin.

Only the owning app can read and write to it via the GraphQL Admin API.
For merchant-owned metafields and metaobjects:
Permission Description
PUBLIC_READ_WRITE The metafield or metaobject will be readable and writable by merchants via the Shopify admin.

All apps with the `metaobject` access scope can read and write to it via the GraphQL Admin API.
### Storefront `storefront` controls permissions for the [Storefront API](/docs/api/storefront). All metafields and metaobjects are always available in [Liquid](/docs/api/liquid) templates and the [theme editor](/docs/storefronts/themes/tools/online-editor). For both app-owned and merchant-owned metafields and metaobjects:
Permission Description
NONE The metafield or metaobject will be hidden from the Storefront API.
PUBLIC_READ The metafield or metaobject will be accessible in the Storefront API by any app with the `unauthenticated_metaobjects` access scope.
### Customer Accounts `customer_accounts` controls permissions for the [Customer Accounts API](/docs/api/customer). > Note > Only **metafields** can be connected to the Customer Accounts API. For both app-owned and merchant-owned metafields:
Permission Description
NONE The metafield will be hidden from the Customer Accounts API.
CUSTOMER_READ The metafield will be readable in the Customer Accounts API.
CUSTOMER_READ_WRITE The metafield will be readable and writable in the Customer Accounts API.
## Examples Requirements for these examples: - Your app can make [authenticated requests](/docs/api/admin-graphql#authentication) to the GraphQL Admin API. ### Define an app-owned metafield and metaobject that merchants can create values for Your app brings testimonials to a merchants store. You need to control the structure, but want to give merchants the ability to create and read values from within the Shopify admin. Start by creating a metaobject definition with the [`metaobjectDefinitionCreate`](docs/api/admin-graphql/latest/mutations/metaobjectDefinitionCreate) mutation:

Now you can create a metafield definition that references this metaobject using the [`metafieldDefinitionCreate`](docs/api/admin-graphql/latest/mutations/metafieldDefinitionCreate) mutation. We take advantage of the default namespace of the app to create the metafield.

### Define a merchant-owned metafield that merchants can fully manage themselves Let's create a `packing_number` metafield that merchants can fully manage themselves. Again, using the [`metafieldDefinitionCreate`](docs/api/admin-graphql/latest/mutations/metafieldDefinitionCreate) mutation. Because you want the merchant to have full control, you must use a non-reserved namespace.