Medusa authenticates with an actor type plus a method, not with a single key. The actor is `user` (admin), `customer`, or a custom actor type a merchant defines; the method is a JWT bearer token, a session cookie, or — for admin only — a secret API key. Route protection is by path prefix rather than by declared security on each operation, which is why neither published document sets a top-level `security` block: /admin is protected by default, /store/customers/me is protected for customers, and everything else under /store is public but still requires a publishable API key that scopes the request to a sales channel.
Medusa secures its APIs with http and apiKey across 4 declared security schemes, as derived from its OpenAPI definitions.
generated: '2026-08-26'
method: searched
source: >-
Derived from components.securitySchemes in openapi/medusa-store-openapi.yaml and
openapi/medusa-admin-openapi.yaml (2.19.0) by 0-working/derive-authentication.py, then
upgraded from https://docs.medusajs.com/learn/fundamentals/api-routes/protected-routes,
https://docs.medusajs.com/api/store, https://docs.medusajs.com/api/admin and the probed
OAuth metadata in well-known/.
description: >-
Medusa authenticates with an actor type plus a method, not with a single key. The actor is
`user` (admin), `customer`, or a custom actor type a merchant defines; the method is a JWT
bearer token, a session cookie, or — for admin only — a secret API key. Route protection
is by path prefix rather than by declared security on each operation, which is why neither
published document sets a top-level `security` block: /admin is protected by default,
/store/customers/me is protected for customers, and everything else under /store is public
but still requires a publishable API key that scopes the request to a sales channel.
summary:
types: [http, apiKey]
schemes: 4
oauth2: false
openid_connect: false
mutual_tls: false
api_key_in: [cookie, header]
schemes:
- name: jwt_token
type: http
scheme: bearer
display_name: JWT Token
actors: [user, customer]
sources: [openapi/medusa-admin-openapi.yaml, openapi/medusa-store-openapi.yaml]
obtained_via: >-
POST /auth/{actor_type}/{auth_provider} (e.g. /auth/user/emailpass,
/auth/customer/emailpass) returns a token. Third-party providers (Google, GitHub) are
supported through auth provider modules.
header: 'Authorization: Bearer <token>'
- name: cookie_auth
type: apiKey
in: cookie
parameter: connect.sid
display_name: Cookie Session ID
actors: [user, customer]
sources: [openapi/medusa-admin-openapi.yaml, openapi/medusa-store-openapi.yaml]
obtained_via: POST /auth/session after obtaining a JWT; used by browser clients including the Medusa Admin.
- name: api_token
type: http
scheme: basic
display_name: API Token
actors: [user]
sources: [openapi/medusa-admin-openapi.yaml]
obtained_via: >-
A secret API key created in the Admin dashboard or via POST /admin/api-keys with
type=secret. Sent as the HTTP Basic username with an empty password.
note: Admin only. This is the credential a server-to-server integration uses.
- name: reset_password
type: http
scheme: bearer
display_name: Reset Password Token
x_is_auth: false
sources: [openapi/medusa-admin-openapi.yaml, openapi/medusa-store-openapi.yaml]
note: >-
A single-purpose token for the password-reset flow, flagged x-is-auth:false in the
spec — it is not a general authentication scheme and should not be treated as one.
additional_required_header:
name: x-publishable-api-key
applies_to: every /store route
is_credential: false
purpose: >-
Scopes the request to one or more sales channels, so a storefront only sees the products
and inventory of its own channel. Created in the Admin dashboard, via POST
/admin/api-keys with type=publishable, or by createApiKeysWorkflow. Safe to ship in
client-side code.
docs: https://docs.medusajs.com/api/store#publishable-api-key
route_protection:
mechanism: path-prefix defaults plus an `authenticate` middleware
defaults:
- { prefix: /admin, access: authenticated admin users only }
- { prefix: /store/customers/me, access: authenticated customers only }
- { prefix: /store, access: public, but x-publishable-api-key is required }
opt_out: 'export const AUTHENTICATE = false in a route file disables the default requirement.'
custom: >-
authenticate(actorType, methods[, { allowUnauthenticated, allowUnregistered }]) applied
in src/api/middlewares.ts. Methods are session, bearer and — for admin — api-key. A
merchant can define custom actor types (e.g. `manager`) with their own auth flow.
docs: https://docs.medusajs.com/learn/fundamentals/api-routes/protected-routes
mfa:
supported: true
evidence: >-
Multi-Factor Authentication tags in both documents (Store: "Multi-Factor Authentication
(MFA) Factors"; Admin: "Multi-Factor Authentication"), plus auth.mfa_enabled,
auth.mfa_disabled and auth.mfa_recovery_codes_generated events in the published event
reference. Added in the 2.x line and announced in the June 2026 newsletter.
oauth:
rest_api: false
mcp_server: true
note: >-
OAuth appears nowhere in the REST contract. It exists only in front of the Medusa MCP
server, where authorization-code + PKCE (S256) with dynamic client registration is
advertised at https://docs.medusajs.com/.well-known/oauth-authorization-server. See
scopes/medusa-scopes.yml.
scopes:
rest_api: none
note: >-
Neither key type nor token carries scopes. Admin access is all-or-nothing for a `user`
actor; the only scoping mechanism in the product is the publishable key's sales-channel
binding on /store.
gaps:
- No token expiry, refresh or rotation policy is documented for the JWT scheme.
- No per-key permission or scope model on Admin secret keys.
- No published key-prefix convention that would let a leaked credential be recognised by shape.
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.