Skip to main content

Access and ownership types

Access configuration options depend on whether your definition is app-owned or merchant-owned. There are three ownership options for metafield and metaobject definitions:

Ownership TypeAdmin AccessLiquid AccessStorefront API
Merchant-ownedRead/Write by merchants and all installed appsReadable in theme templates and app blocksConfigurable (default: NONE)
App-ownedRead by merchants, Write by owning app (configurable)Readable in theme templates and app blocks owned by the same appConfigurable (default: NONE)
Shopify-reservedVaries by definitionVaries by definitionVaries by definition

Anchor to Merchant-owned namespaces and typesMerchant-owned namespaces and types

Merchant-owned metafield namespaces and metaobject types give merchants and their installed apps full control over the data. These use any metafield namespace that isn't reserved for apps (app--) or Shopify (shopify--), with custom being the default merchant-owned namespace.

Anchor to Access considerationsAccess considerations

  • Merchants and all apps installed on the shop can read and write to these resources
  • They're visible in the Shopify admin
  • They can be accessed through Liquid templates and theme app blocks

This access configuration is particularly convenient when data needs to be shared between different apps.

Anchor to App-owned namespaces and typesApp-owned namespaces and types

Apps that need full control over their data and want to prevent other apps from modifying definitions and values can use app-owned metafields and metaobjects. For app-owned metafields, data is stored using a special namespace such as app--12345 or app--12345--some-custom-namespace, where 12345 is the app's ID. For app-owned metaobjects, the special type name follows the same format, such as app--12345--authors.

Anchor to Access considerationsAccess considerations

  • Merchants can read these resources in the Shopify admin
  • The owning app has full read and write access
  • By default, merchants cannot modify this data, but access can be configured for merchant writes
  • Other apps cannot access these resources

Anchor to Shopify-reserved (standard) namespaces and typesShopify-reserved (standard) namespaces and types

Shopify maintains certain reserved namespaces and types for key system functionality.

Anchor to Access considerationsAccess considerations

  • These metafield namespaces and metaobject types are typically prefixed with shopify--
  • They have specific access controls determined by Shopify that vary by definition
  • Apps generally can read and write to these Shopify-owned metafields and metaobjects

Both metafields and metaobjects offer permissions based on their ownership type with the following defaults:

  • Merchant-owned:

    • Admin: Readable and writeable by merchants and all installed apps
    • Liquid: Readable in theme templates
    • Storefront API: Not available by default, can be configured to be readable
    • Customer accounts: Not available by default, can be configured to be readable
  • App-owned:

    • Admin: Readable by merchants, writeable only by owning app (unless configured as MERCHANT_READ_WRITE, in which case merchants will have write access to these app owned metafields through the admin)
    • Liquid: Readable in theme templates and app blocks owned by the same app
    • Storefront API: Not available by default, can be configured to be readable
    • Customer accounts: Not available by default, can be configured to be readable

admin controls permissions for both the Shopify admin and the GraphQL Admin API.

For app-owned metafields and metaobjects:

  • MERCHANT_READ: Merchants can read but not write in the admin
  • MERCHANT_READ_WRITE: Merchants can read and write in the admin

For merchant-owned metafields and metaobjects:

  • PUBLIC_READ_WRITE: Readable and writable by merchants and all apps with the metaobject access scope

Anchor to Storefront permissionsStorefront permissions

storefront controls permissions for the Storefront API. All metafields and metaobjects are always available in Liquid templates and the online store editor.

Available permissions:

  • NONE: Hidden from the Storefront API
  • PUBLIC_READ: Accessible in the Storefront API by apps with the unauthenticated_metaobjects scope
Note

Metafield access depends on its owning resource.

Anchor to Customer accounts permissionsCustomer accounts permissions

customer_accounts controls permissions for the Customer Accounts API (metafields only).

Available permissions:

  • NONE: Hidden from the Customer Accounts API
  • CUSTOMER_READ: Readable in the Customer Accounts API
  • CUSTOMER_READ_WRITE: Readable and writeable in the Customer Accounts API
Note

Customer Account API access levels can only be adjusted via GraphQL Admin API mutation for metafields in an app's reserved namespace (app--). For metafields in public namespaces, Customer Account API access can only be configured through the Shopify Admin.


Anchor to Storing private app dataStoring private app data

  • Generally, private app data should be stored in an app-specific, secure database
  • If app-specific configuration data must be stored in metafields, the best option is to use app-data metafields (also known as AppInstallation metafields), which are not visible to merchants in the admin. You can access app-data metafields using the metafields property on the app object in Liquid
Note

Avoid storing private information in merchant or app-owned metafields and metaobjects as they are always visible to merchants in the admin and online store editor.


Requirements for these examples:

Anchor to Define an app-owned metafield and metaobject that merchants can create values forDefine 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 mutation:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
metaobjectDefinitionCreate(definition: {
name: "Testimonial",
type: "$app:testimonial",
access: {
admin: MERCHANT_READ_WRITE,
storefront: PUBLIC_READ,
},
displayNameKey: "author",
fieldDefinitions: [
{
key: "author",
name: "Author",
type: "single_line_text_field",
},
{
key: "body",
name: "Body",
type: "multi_line_text_field",
},
]
}) {
metaobjectDefinition {
id
type
}
}
}

JSON response

{
"data": {
"metaobjectDefinitionCreate": {
"metaobjectDefinition": {
"id": "gid://shopify/MetaobjectDefinition/1",
"type": "app--123456--testimonial",
},
}
}
}

Now you can create a metafield definition that references this metaobject using the metafieldDefinitionCreate mutation. We take advantage of the default namespace of the app to create the metafield.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
metafieldDefinitionCreate(definition: {
name: "Testimonials",
key: "testimonials",
type: "list.metaobject_reference",
ownerType: "PRODUCT",
access: {
admin: MERCHANT_READ_WRITE,
storefront: PUBLIC_READ,
},
validation: {
metaobjectDefinitionId: "gid://shopify/MetaobjectDefinition/1",
},
}) {
createdDefinition {
namespace
key
}
}
}

JSON response

{
"metafieldDefinitionCreate": {
"createdDefinition": {
"namespace": "app--123456",
"key": "testimonials",
},
}
}

Anchor to Define a merchant-owned metafield that merchants can fully manage themselvesDefine 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 mutation. Because you want the merchant to have full control, you must use a non-reserved namespace.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation {
metafieldDefinitionCreate(definition: {
name: "Packing number",
namespace: "custom",
key: "packing_number",
type: "single_line_text_field",
ownerType: "PRODUCT",
}) {
createdDefinition {
namespace
key
access {
admin
storefront
}
}
}
}

JSON response

{
"metafieldDefinitionCreate": {
"createdDefinition": {
"namespace": "custom",
"key": "packing_number",
"access": {
"admin": "PUBLIC_READ_WRITE",
"storefront": "NONE",
}
},
}
}

Was this page helpful?