dist/cursor/medusa-commerce/skills/medusa-security/SKILL.md
Secure Medusa v2 applications — authentication strategies, API key types (publishable vs secret), CORS configuration, JWT and cookie secrets, admin vs store auth, and session management. Use when configuring security.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins medusa-securityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch live docs:
site:docs.medusajs.com authentication for auth strategies and API key setupsite:docs.medusajs.com api key publishable secret for API key typessite:docs.medusajs.com CORS configuration for cross-origin resource sharinghttps://docs.medusajs.com/learn/fundamentals/api-routes/middlewares for middleware and auth configsite:docs.medusajs.com medusa-config auth providers for auth provider registrationMedusa v2 separates admin and storefront authentication into distinct flows:
| Aspect | Admin Auth | Store Auth |
|--------|-----------|------------|
| Actor type | user | customer |
| API scope | /admin/* routes | /store/* routes |
| Default provider | emailpass | emailpass |
| Session cookie | Admin session cookie | Store session cookie |
| API key support | Secret API key (Bearer) | Publishable API key (header) |
| JWT usage | Admin JWT token | Customer JWT token |
| Middleware | authenticate("user", ...) | authenticate("customer", ...) |
Auth Module
├── emailpass — email + password (default)
├── google — OAuth 2.0 via Google
├── github — OAuth 2.0 via GitHub
└── custom — implement AbstractAuthModuleProvider
Auth providers are registered in medusa-config.ts under the auth module configuration. Each provider handles a specific identity verification strategy.
| Key Type | Header | Purpose | Visibility |
|----------|--------|---------|------------|
| Publishable | x-publishable-api-key | Storefront API access, scopes to sales channels | Safe for client-side |
| Secret | Authorization: Bearer <key> | Admin API access, full permissions | Server-side only |
Configure CORS in medusa-config.ts under projectConfig:
| Setting | Purpose | Example |
|---------|---------|---------|
| storeCors | Allowed origins for Store API | http://localhost:8000 |
| adminCors | Allowed origins for Admin API | http://localhost:9000 |
| authCors | Allowed origins for Auth routes | http://localhost:8000,http://localhost:9000 |
* wildcardauthCors must include both storefront and admin origins| Secret | Environment Variable | Purpose |
|--------|---------------------|---------|
| Cookie secret | COOKIE_SECRET | Signs session cookies |
| JWT secret | JWT_SECRET | Signs JSON Web Tokens |
| Admin JWT | Configured per auth provider | Admin token signing |
| Store JWT | Configured per auth provider | Customer token signing |
COOKIE_SECRET and JWT_SECRET must be set in productionSessions are managed via HTTP-only cookies with configurable options:
httpOnly, secure, sameSite, maxAgeApply auth middleware in src/api/middlewares.ts:
// Fetch live docs for authenticate() middleware
// signature and actor type options
import { authenticate } from "@medusajs/medusa"
| Middleware Function | Actor Type | Use Case |
|-------------------|-----------|----------|
| authenticate("user", ...) | Admin user | Admin-only routes |
| authenticate("customer", ...) | Customer | Store auth-required routes |
| authenticate("user", ["bearer","session"]) | Admin | Multiple auth strategies |
src/api/admin/ — auto-protectedsrc/api/store/ — require publishable keyauthenticate() middlewareCustom auth providers extend AbstractAuthModuleProvider:
// Fetch live docs for AbstractAuthModuleProvider
// methods: authenticate, register, validateCallback
| Method | Purpose |
|--------|---------|
| authenticate() | Verify identity (login) |
| register() | Create new identity |
| validateCallback() | Handle OAuth redirect callbacks |
COOKIE_SECRET and JWT_SECRET (never use defaults)DATABASE_URL with SSL mode for PostgreSQL connectionssecure: true and sameSite: "strict" on cookies in productionemailpass for standard flows; add OAuth providers for social login; register providers in medusa-config.ts under the auth modulestoreCors, adminCors, and authCors explicitly; test CORS headers before deploying; avoid wildcard origins in productionhttpOnly, secure, and sameSite flags; use Redis-backed sessions for multi-instance deployments; set reasonable TTLsFetch the Medusa authentication and security documentation for exact provider registration syntax, middleware options, and cookie configuration before implementing.
development
Build with Spree's headless Next.js storefront — the official `spree/storefront` repo (Next.js 16 App Router with Server Actions and Turbopack, React 19 Server Components, Tailwind CSS 4, TypeScript 5, `@spree/sdk`, Sentry), server-only auth (httpOnly JWT cookies + publishable key), MeiliSearch faceted catalog, one-page checkout with Apple/Google Pay/Klarna/Affirm/SEPA, multi-region market routing, GA4 + JSON-LD SEO, and Vercel/Docker deployment. Use when forking or customizing the storefront, or evaluating headless adoption.
tools
Build Spree extensions as Rails engines — gem scaffolding, `bin/rails g spree:extension`, mounting routes/migrations/assets, the modern `prepend` decorator pattern (`*_decorator.rb` with `self.prepended(base)`), generators (`spree:model_decorator`, `spree:controller_decorator`), the four customization surfaces in preference order (Events > Webhooks > Dependencies > Decorators), Spree::Dependencies for swapping service objects, gem release/versioning, and the deprecated Deface engine. Use when building a reusable Spree extension or adding non-trivial customization to an app.
development
Build with Spree's event bus and Webhooks 2.0 — `Spree::Events` publication, `Spree::Subscriber` DSL with `subscribes_to` and `on`, wildcard matching, lifecycle events (`{model}.created/.updated/.deleted` via `publishes_lifecycle_events`), the canonical event catalog (order.*, payment.*, shipment.*, product.*), Webhooks 2.0 endpoints, HMAC-SHA256 signing (`X-Spree-Webhook-Signature`), exponential-backoff retries, and Sidekiq job orchestration. Use when wiring event-driven business logic, building webhook consumers, or replacing ActiveSupport callback chains.
tools
Cross-cutting Spree development patterns — the customization preference hierarchy (Events > Webhooks > Dependencies > Decorators), `Spree::Dependencies` service-object swapping, the `_decorator.rb` + `prepend` + `self.prepended` idiom, idempotent subscribers and webhook receivers, multi-store scoping discipline, prefixed IDs, calculator polymorphism (shipping/promotion/tax share the base), service-object composition with `dry-monads` or simple results, why to avoid `class_eval` reopening and Deface, and Spree-on-Rails idioms (Hotwire/Turbo Stimulus, ActiveStorage, Action Cable, Sidekiq). Use when designing the architecture of a Spree extension or solving cross-cutting concerns.