AuthRailAuthRail

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.

shared/policies.ts
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.

Express Middleware
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.

Next.js Server Action
"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.

Edge Middleware
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.

On this page