From inai-auth-skills
Integrate InAI Auth SDK into Express applications. Use this skill whenever the user wants to add authentication, login, signup, middleware protection, role-based access control (RBAC), MFA, or session management to an Express app using @inai-dev/express. Also trigger when the user mentions InAI auth with Express, asks about protecting routes in Express, needs auth middleware for Express, wants to set up auth API routes in Express, or is building a Node.js API server that needs authentication. Covers middleware setup, route protection, cookie management, and both app and platform auth modes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/inai-auth-skills:inai-express-sdkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill guides you through integrating InAI Auth into Express 4+ applications using the `@inai-dev/express` package.
This skill guides you through integrating InAI Auth into Express 4+ applications using the @inai-dev/express package.
https://apiauth.inai.dev — hardcoded in the SDK, never configurableINAI_PUBLISHABLE_KEY=pk_live_...@inai-dev/express (depends on @inai-dev/backend and @inai-dev/shared)"app" (end users) and "platform" (admin/developer panels)express >= 4.17.0npm install @inai-dev/express
inaiAuthMiddleware() as global middlewarecreateAuthRoutes() mounted at /api/authrequireAuth() for per-route authorizationimport express from "express";
import { inaiAuthMiddleware } from "@inai-dev/express/middleware";
const app = express();
app.use(express.json());
app.use(
inaiAuthMiddleware({
publicRoutes: ["/", "/health", "/api/public/*"],
signInUrl: "/login",
})
);
publicRoutes — if so, sets req.auth = null and proceedsAuthorization: Bearer <token> header or auth_token cookierefresh_token cookie exists → auto-refreshAuthObject and attaches to req.authonUnauthorized handler (default: 401 JSON response)inaiAuthMiddleware({
authMode: "app", // "app" (default) or "platform"
publicRoutes: ["/", "/health"], // string[] or (req) => boolean
onUnauthorized: (req, res, next) => {
res.status(401).json({ error: "Unauthorized" });
},
beforeAuth: (req, res) => {
// Return true to skip auth entirely
},
afterAuth: (auth, req, res) => {
// Called after successful auth — useful for logging
},
// jwksUrl: "https://apiauth.inai.dev/.well-known/jwks.json", // optional override
})
// Exact match
publicRoutes: ["/health", "/api/public/status"]
// Wildcard
publicRoutes: ["/api/public/*"]
// Function
publicRoutes: (req) => req.path.startsWith("/public/")
import { createAuthRoutes } from "@inai-dev/express/api-routes";
app.use("/api/auth", createAuthRoutes());
Creates these endpoints automatically:
POST /api/auth/login — Login, sets httpOnly cookies. Returns { user } or { mfa_required, mfa_token }POST /api/auth/register — Registration. Returns { user } or { needs_email_verification, user }POST /api/auth/mfa-challenge — TOTP MFA verificationPOST /api/auth/refresh — Token rotation (also called by middleware automatically)POST /api/auth/logout — Invalidate session, clear cookiesFor admin/developer panels, use platform auth mode. No publishable key needed:
app.use(
inaiAuthMiddleware({
authMode: "platform",
publicRoutes: ["/login"],
})
);
Platform mode uses /api/platform/auth/* endpoints internally.
import { requireAuth } from "@inai-dev/express/middleware";
// Require any authenticated user
app.get("/api/profile", requireAuth(), (req, res) => {
res.json({ userId: req.auth!.userId });
});
// Require specific role
app.get("/api/admin", requireAuth({ role: "admin" }), (req, res) => {
res.json({ message: "Admin access granted" });
});
// Require specific permission
app.put("/api/posts/:id", requireAuth({ permission: "posts:write" }), (req, res) => {
// Update post...
});
import { getAuth } from "@inai-dev/express";
app.get("/api/data", (req, res) => {
const auth = getAuth(req);
if (!auth?.userId) {
return res.status(401).json({ error: "Not authenticated" });
}
if (auth.has({ role: "admin" })) {
// Return admin data
}
res.json({ userId: auth.userId });
});
The middleware extends Express's Request type:
// req.auth is available after middleware runs
req.auth?.userId // string | null
req.auth?.tenantId // string | null
req.auth?.orgId // string | null
req.auth?.orgRole // string | null
req.auth?.sessionId // string | null
req.auth?.roles // string[]
req.auth?.permissions // string[]
req.auth?.has({ role: "admin" }) // boolean
req.auth?.has({ permission: "posts:write" }) // boolean
req.auth?.getToken() // Promise<string | null>
| Cookie | Purpose | httpOnly | Path | MaxAge |
|---|---|---|---|---|
auth_token | Access JWT | Yes | / | Token expiry |
refresh_token | Refresh JWT | Yes | / | 7 days |
auth_session | User data (readable by JS) | No | / | Token expiry |
NODE_ENV=production): secure: true on all cookiessecure: false for http://localhostFor custom auth flows or manual token management:
import { setAuthCookies, clearAuthCookies } from "@inai-dev/express";
// After manual authentication
setAuthCookies(res, tokens, user);
// Manual logout
clearAuthCookies(res);
import { getTokenFromRequest, getRefreshTokenFromRequest } from "@inai-dev/express";
// Gets token from Authorization header or auth_token cookie
const token = getTokenFromRequest(req);
// Gets refresh token from cookie only
const refreshToken = getRefreshTokenFromRequest(req);
{
userId: string | null
tenantId: string | null
appId: string | null
envId: string | null
orgId: string | null
orgRole: string | null
sessionId: string | null
roles: string[]
permissions: string[]
getToken(): Promise<string | null>
has(params: { role?: string; permission?: string }): boolean
}
import express from "express";
import { inaiAuthMiddleware, requireAuth, createAuthRoutes, getAuth } from "@inai-dev/express";
const app = express();
app.use(express.json());
// Global auth middleware
app.use(
inaiAuthMiddleware({
publicRoutes: ["/", "/health", "/login", "/register"],
})
);
// Auth routes
app.use("/api/auth", createAuthRoutes());
// Public route
app.get("/health", (req, res) => res.json({ status: "ok" }));
// Protected route
app.get("/api/me", requireAuth(), (req, res) => {
res.json({ userId: req.auth!.userId });
});
// Admin-only route
app.delete("/api/users/:id", requireAuth({ role: "admin" }), (req, res) => {
// Delete user...
});
app.listen(3000);
const res = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
const data = await res.json();
if (data.mfa_required) {
// Show MFA input, then submit:
await fetch("/api/auth/mfa-challenge", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ mfa_token: data.mfa_token, code: totpCode }),
});
}
When you need to check implementation details, the source files are at:
packages/express/src/middleware.ts — inaiAuthMiddleware(), requireAuth()packages/express/src/api-routes.ts — createAuthRoutes()packages/express/src/helpers.ts — Cookie & token management utilitiespackages/express/src/types.ts — TypeScript interfacespackages/backend/src/client.ts — InAIAuthClient (core API client)packages/shared/src/constants.ts — Cookie names, URLs, headerspackages/shared/src/jwks.ts — JWKSClient (JWKS key fetching, caching, error throttling)packages/shared/src/jwt.ts — ES256 verification, JWT decodingnpx claudepluginhub inai-team/inai-auth-skills --plugin inai-auth-skillsIntegrates Auth0 authentication into Express.js web applications using express-openid-connect, enabling session-based login, logout, and route protection.
Scaffold signin and signup authentication endpoints for a project. Use when the user wants to add authentication, create login/register flows, or set up auth from scratch.
Installs Clerk SDK and configures authentication for Next.js, React, or Express apps. Sets up env vars, ClerkProvider, middleware, and verifies initial auth.