Server Usage
Using the core engine in Node.js, Express, and Serverless environments.
The AuthRail core engine is intentionally framework-neutral and has zero dependencies on React or browser APIs. This makes it a perfect fit for any server-side environment.
1. Shared Policy Pattern
The most effective way to use AuthRail is to define your rails in a shared path (e.g., src/shared/policies.ts) and import them into both your frontend and backend.
import { createRail, requireAuth, requireRole } from "authrail";
export const adminRail = createRail("admin", [
requireAuth("/login"),
requireRole("admin"),
]);2. Express.js Integration
You can use AuthRail inside Express middleware or directly within route handlers.
import { adminRail } from "./shared/policies";
const protectAdmin = async (req, res, next) => {
const result = await adminRail.evaluate({
user: req.user,
ip: req.ip,
});
if (result.decision.type === "redirect") {
return res.redirect(result.decision.to);
}
if (result.decision.type === "deny") {
return res.status(403).json({ error: "Access Denied" });
}
next();
};
app.get("/api/admin/stats", protectAdmin, (req, res) => {
res.json({ stats: "..." });
});3. Next.js Server Components & Actions
AuthRail works seamlessly with Next.js Server Components. Since evaluation is asynchronous, you can simply await the result.
"use server";
import { adminRail } from "@/lib/auth";
import { getSession } from "@/lib/session";
export async function deleteUserAction(targetUserId: string) {
const user = await getSession();
const result = await adminRail.evaluate({ user });
if (result.decision.type !== "allow") {
throw new Error("Unauthorized");
}
// Perform the sensitive operation
await db.user.delete({ where: { id: targetUserId } });
}4. Edge Middleware (Vercel/Cloudflare)
Because the core is lightweight and has no Node.js built-in dependencies, it can run at the Edge.
export default async function middleware(req) {
const user = await verifyJwt(req.cookies.get("token"));
const result = await adminRail.evaluate({ user });
if (result.decision.type === "redirect") {
return Response.redirect(new URL(result.decision.to, req.url));
}
return NextResponse.next();
}Why evaluate on the server?
- Security: Never rely solely on client-side authorization.
- Consistency: Use the exact same Rail and Middleware that your frontend uses.
- Performance: Perform complex checks close to your data source.