RBAC Module Options

EnterpriseBeta

In this guide, you'll learn about the options of the RBAC Module, and the configuration of the Medusa application that affects it.

actors#

The actors option tells Medusa which of your actor types can hold roles, and which entities hold those roles.

You only need this option when you add roles to actor types of your own, such as a vendor_admin on a marketplace, or when you change how existing actor types resolve their roles. The RBAC Module always sets entries for the user actor type, which is the admin user, and the api-key actor type, so admin roles work without any configuration.

For example:

medusa-config.ts
module.exports = defineConfig({
  // ...
  modules: [
    {
      resolve: "@medusajs/medusa/rbac",
      options: {
        actors: {
          vendor_admin: {
            grantees: [
              {
                entity: "vendor_admin",
                path: "id",
              },
            ],
          },
        },
      },
    },
  ],
})

The actors option is an object whose keys are actor types. Each actor type accepts the following properties:

  • grantees: An array of objects, each specifying an entity that can hold role assignments for that actor type. Each object accepts the following properties:
    • entity: A string indicating the name of the entity that holds the assignments. Medusa matches it against the reference property of a role assignment.
    • path: A string indicating the path from the actor to the entity's ID, such as id or vendors.id.
  • actor_entity: An optional string indicating the name of the entity Medusa retrieves the actor from with Query to resolve the path of each grantee. It defaults to the actor type, so you only need it when the actor type and the entity have different names, such as the api-key actor type and the api_key entity.

An actor type without an entry resolves to no roles at all.

Refer to the RBAC Scopes guide to learn how to configure a custom actor type for scoped roles, and how a request enters a scope.

user Actor Type#

The RBAC Module merges the user entry of the actors option you pass with its default entry. It keeps the grantees you configure, and it always adds the admin user itself as a grantee with { entity: "user", path: "id" }.

So, you can add grantees to admin users without losing their own role assignments. For example, if admin users belong to teams that hold role assignments:

medusa-config.ts
module.exports = defineConfig({
  // ...
  modules: [
    {
      resolve: "@medusajs/medusa/rbac",
      options: {
        actors: {
          user: {
            grantees: [
              {
                entity: "team",
                path: "teams.id",
              },
            ],
          },
        },
      },
    },
  ],
})

In this example, an admin user's effective policies include the policies of their own role assignments and the role assignments of their teams.

api-key Actor Type#

Requests authenticated with a secret API key have the api-key actor type. By default, a secret API key acts with the roles of the admin user who created it. You don't need to configure anything for this behavior.

Under the hood, the RBAC Module applies a default api-key entry equivalent to the following configuration:

Default configuration
module.exports = defineConfig({
  // ...
  modules: [
    {
      resolve: "@medusajs/medusa/rbac",
      options: {
        actors: {
          "api-key": {
            actor_entity: "api_key",
            grantees: [
              {
                entity: "user",
                path: "created_by",
              },
            ],
          },
        },
      },
    },
  ],
})

In this entry:

  • actor_entity tells Medusa to retrieve the actor from the api_key entity, since the actor type's name, api-key, differs from the entity's name.
  • The grantee follows the API key's created_by property to the admin user who created the key. So, Medusa resolves the key's roles from that user's role assignments.

To give each secret API key its own role assignments instead, override the entry so that the API key itself is the grantee:

medusa-config.ts
module.exports = defineConfig({
  // ...
  modules: [
    {
      resolve: "@medusajs/medusa/rbac",
      options: {
        actors: {
          "api-key": {
            actor_entity: "api_key",
            grantees: [
              {
                entity: "api_key",
                path: "id",
              },
            ],
          },
        },
      },
    },
  ],
})

Then, assign roles to an API key with a role assignment whose reference is api_key and whose reference_id is the API key's ID. Unlike the user entry, the RBAC Module doesn't merge this entry with its default, so the API key no longer acts with its creator's roles.


rbacActorTypes Configuration#

The RBAC API routes live under the /rbac prefix, and they aren't admin routes. They reuse the admin CORS configuration by default, since the Medusa Admin dashboard consumes them, but they don't restrict authentication to the user actor type the way the /admin routes do.

Use the http.rbacActorTypes configuration in medusa-config.ts to set the actor types allowed to authenticate against these routes. It defaults to ["user"], so only admin users reach them out of the box. Medusa rejects a request authenticated as any other actor type with a 401 error.

medusa-config.ts
module.exports = defineConfig({
  projectConfig: {
    http: {
      rbacActorTypes: ["user", "vendor_admin"],
    },
    // ...
  },
  // ...
})

Pass ["*"] to allow every authenticated actor type:

medusa-config.ts
module.exports = defineConfig({
  projectConfig: {
    http: {
      rbacActorTypes: ["*"],
    },
    // ...
  },
  // ...
})

The /rbac routes only accept bearer tokens and sessions, so you can't authenticate requests to them with a secret API key.

Learn more about these routes, and how to use them with a custom actor type, in the RBAC API Routes guide.


rbacCors Configuration#

The /rbac routes use the http.adminCors configuration by default. If another client, such as a custom dashboard for a non-user actor type, calls these routes from a different origin, set the http.rbacCors configuration in medusa-config.ts:

medusa-config.ts
module.exports = defineConfig({
  projectConfig: {
    http: {
      rbacCors: process.env.RBAC_CORS,
    },
    // ...
  },
  // ...
})

It accepts the same format as adminCors. When you set it, it replaces adminCors for the /rbac routes rather than extending it. So, if the Medusa Admin dashboard also uses the /rbac routes, include its origin as well.

Was this page helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Docs MCP server in Cursor, VSCode, etc...FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break
⇧↵