-
Notifications
You must be signed in to change notification settings - Fork 850
Description
Problem
Request for Motia to support secure-by-default API endpoints where authentication middleware is automatically applied to all routes unless explicitly marked as public. This would improve security and reduce the risk of accidentally exposing protected endpoints.
Currently, in Motia, every API step requires explicit middleware configuration:
export const config: ApiRouteConfig = {
type: 'api',
name: 'GetTaskData',
path: '/tasks/query',
method: 'POST',
middleware: [authMiddleware], // ⚠️ Must remember to add this manually
// ... rest of config
}The Problem:
Easy to forget: Developers must remember to add authentication to every protected endpoint
Security risk: A missed middleware means an unprotected endpoint goes to production
Boilerplate: Repetitive code across multiple steps
Maintenance burden: Hard to ensure consistency across a growing codebase
Current Workaround.
I've created a custom solution using a wrapper function, but it requires manual opt-in for every step:
// middlewares/auto-global.middleware.ts
const PUBLIC_ROUTES = [
"/auth/sign-in",
"/auth/sign-up",
"/auth/verify-email",
// ... etc
];
export function withGlobalMiddleware<T extends ApiRouteConfig>(config: T) {
if (config.middleware?.length > 0) {
return config; // Respect custom middleware
}
const middleware = [
errorMiddleware,
corsMiddleware,
requestIdMiddleware,
loggingMiddleware
];
// Apply auth unless it's a public route
if (!isPublicRoute(config.path)) {
middleware.push(authMiddleware);
}
return { ...config, middleware };
}Usage:
import { withGlobalMiddleware } from "../../middlewares/auto-global.middleware";
export const config = withGlobalMiddleware({
type: "api",
name: "GetTaskData",
path: "/tasks/query",
method: "POST",
// No middleware property needed!
});Limitations of this approach:
Still requires wrapping every config manually
Easy to forget the wrapper function
No IDE/type-level enforcement
Workaround feels hacky for what should be a framework feature
Questions for the Team
Is there already a recommended pattern for this that I'm missing?
Would this feature align with Motia's design philosophy?
Tech Stack Context:
Motia backend with TypeScript
BetterAuth for session management
Mixed public (auth endpoints) and protected (task management) routes
Need for consistent CORS, error handling, and authentication across all routes
Proposed Solution
Proposed Solution
Add native framework support for secure-by-default endpoints with explicit opt-out:
Option 1: Config-based approach
// motia.config.ts
export default {
api: {
secureByDefault: true,
globalMiddleware: [errorMiddleware, corsMiddleware, authMiddleware],
publicRoutes: [
"/auth/sign-in",
"/auth/sign-up",
"/health"
]
}
}Option 2: Step-level opt-out
export const config: ApiRouteConfig = {
type: 'api',
name: 'SignIn',
path: '/auth/sign-in',
method: 'POST',
public: true, // ✅ Explicit opt-out
}Option 3: Hybrid approach
// Global config sets defaults
export default {
api: {
defaultMiddleware: [errorMiddleware, corsMiddleware, authMiddleware]
}
}
// Steps can override with `public: true` or custom middleware
export const config: ApiRouteConfig = {
public: true, // Skips defaultMiddleware
// OR
middleware: [customMiddleware] // Replaces defaultMiddleware
}Alternatives Considered
No response
Additional Context
No response
Willing to Help Implement?
- I would like to work/help with this