Skip to main content

Overview

Medusa supports multiple authentication methods depending on the API and use case:
  • JWT Authentication: For admin users and store customers
  • API Keys: For server-to-server admin operations
  • Session Management: For maintaining authenticated state

Admin Authentication

JWT Token Authentication

Admin users authenticate using JWT tokens obtained through the auth endpoints.

Step 1: Authenticate

Obtain a JWT token by authenticating with email and password:
curl -X POST http://localhost:9000/auth/user/emailpass \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "supersecret"
  }'
Response:
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
token
string
The JWT token to use for authenticated requests.

Step 2: Make Authenticated Requests

Include the JWT token in the Authorization header:
curl -X GET http://localhost:9000/admin/products \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

API Key Authentication

API keys provide a secure way for server-to-server communication with the Admin API.

Creating an API Key

Create an API key through the Admin API:
curl -X POST http://localhost:9000/admin/api-keys \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Integration API Key",
    "type": "secret"
  }'
title
string
required
A descriptive name for the API key.
type
string
required
The type of API key. Use "secret" for server-to-server authentication.
Response:
{
  "api_key": {
    "id": "apk_123",
    "token": "sk_...",
    "title": "Integration API Key",
    "type": "secret",
    "created_at": "2024-03-03T10:00:00.000Z"
  }
}
The API key token is only shown once. Store it securely and never expose it in client-side code.

Using API Keys

Include the API key in the x-medusa-access-token header:
curl -X GET http://localhost:9000/admin/products \
  -H "x-medusa-access-token: sk_..."
Or use it as a query parameter:
curl -X GET "http://localhost:9000/admin/products?api_token=sk_..."
Header-based authentication is recommended for better security.

Revoking API Keys

Revoke an API key when it’s no longer needed:
curl -X POST http://localhost:9000/admin/api-keys/{id}/revoke \
  -H "Authorization: Bearer {jwt_token}"
Source: packages/medusa/src/api/admin/api-keys/[id]/revoke/route.ts

Store Authentication

Customer Authentication

Store customers authenticate using JWT tokens.

Step 1: Register a Customer

Create a new customer account:
curl -X POST http://localhost:9000/store/customers \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "password123",
    "first_name": "John",
    "last_name": "Doe"
  }'
email
string
required
The customer’s email address.
password
string
required
The customer’s password.
first_name
string
The customer’s first name.
last_name
string
The customer’s last name.
Source: packages/medusa/src/api/store/customers/route.ts:11

Step 2: Authenticate

Obtain a JWT token:
curl -X POST http://localhost:9000/auth/customer/emailpass \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "password123"
  }'
Response:
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Step 3: Make Authenticated Requests

Include the JWT token in authenticated store requests:
curl -X GET http://localhost:9000/store/customers/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Session Management

Session Context

Authenticated requests automatically create and maintain session context through the req.auth_context object:
req.auth_context = {
  actor_id: "user_123",           // The authenticated user/customer ID
  auth_identity_id: "authid_456", // The auth identity ID
  app_metadata: {}                // Additional metadata
}
Source: packages/medusa/src/api/admin/customers/route.ts:53

Token Expiration

JWT tokens have an expiration time. When a token expires, clients must re-authenticate to obtain a new token.

Logout

To logout, clients should discard the JWT token. Server-side session invalidation may be implemented through custom middleware.

Security Best Practices

  • Store JWT tokens securely (e.g., httpOnly cookies, secure storage)
  • Never expose API keys in client-side code
  • Use environment variables for API keys in server environments
  • Implement token refresh mechanisms for long-lived sessions
  • Rotate API keys periodically
  • Revoke unused or compromised API keys immediately
  • Always use HTTPS in production to prevent token interception
  • Configure secure cookie flags when using session cookies
  • Create separate API keys for different integrations
  • Use role-based access control (RBAC) to limit permissions
  • Assign API keys to specific sales channels when applicable

Error Handling

Unauthorized (401)

Returned when authentication is required but not provided:
{
  "type": "unauthorized",
  "message": "Authentication required"
}

Forbidden (403)

Returned when the authenticated user lacks permissions:
{
  "type": "not_allowed",
  "message": "Insufficient permissions"
}

Invalid Credentials

Returned when authentication credentials are incorrect:
{
  "type": "invalid_data",
  "message": "Invalid email or password"
}

Next Steps

Admin API

Start using the Admin API

Store API

Build your storefront with the Store API

Build docs developers (and LLMs) love