Skip to content

IAM Middleware Integrations

Extracting the userId, IP Address, and User-Agent manually on every single API route is tedious. Volidator’s SDK provides lightweight, drop-in middleware for popular frameworks and IAM providers that automates this entirely.


The Universal plugin allows you to integrate any authentication provider (Auth0, BetterAuth, NextAuth, Kinde, Supabase, or custom JWTs) by simply providing a getUserId callback.

lib/volidator-auth.ts
import { createUniversalAudit } from "@volidator/sdk/plugins/universal";
import { volidator } from "@/lib/volidator";
import { auth } from "@/lib/auth"; // Your Auth instance
export const withBetterAuthAudit = createUniversalAudit({
client: volidator,
// Works universally: extract the ID from the Request or Context
getUserId: async (req, session) => session?.user.id,
// Optional: Pass the full session down to your route handler
getSession: async (req) => auth.api.getSession({ headers: req.headers }),
// Optional: Seamlessly map avatar and email to the encrypted metadata!
getMetadata: async (req, session) => ({
avatar_url: session?.user.image,
email: session?.user.email
})
});

Now, wrap any Next.js Route Handler:

app/api/invoice/route.ts
import { withBetterAuthAudit } from "@/lib/volidator-auth";
export const POST = withBetterAuthAudit(async (req, { volidator, session }) => {
// Your business logic
const invoice = await db.invoices.create({ userId: session.user.id });
// Actor, IP, Location, and Device are fully automated!
await volidator.log({
action: "invoice.created",
target: invoice.id
});
return Response.json({ success: true });
});

For Clerk users, we provide a pre-built plugin that requires zero configuration.

lib/volidator-clerk.ts
import { createClerkAudit } from "@volidator/sdk/plugins/clerk";
import { auth } from "@clerk/nextjs/server";
import { volidator } from "@/lib/volidator";
export const withClerkAudit = createClerkAudit({
client: volidator,
getAuth: auth
});

Wrap your handlers:

app/api/invoice/route.ts
import { withClerkAudit } from "@/lib/volidator-clerk";
export const POST = withClerkAudit(async (req, { volidator, session }) => {
// session is perfectly typed as Clerk's auth() output
const userId = session.userId;
await volidator.log({ action: "invoice.created" });
return Response.json({ success: true });
});

If you aren’t using an IAM provider but still want automated IP and User-Agent extraction, use the base Next.js middleware:

import { withVolidator } from "@volidator/sdk/middleware/next";
import { volidator } from "@/lib/volidator";
export const POST = withVolidator(volidator, async (req, { volidator }) => {
// IP and User-Agent are automatically extracted from the Request
await volidator.log({
actor: "anonymous",
action: "page.view"
});
});

If your IAM provider returns a profile picture (e.g. Google Avatar, Clerk Profile Image), you can render it securely in the Volidator Dashboard without violating Zero-Knowledge rules.

Simply pass the avatar_url into the encrypted metadata dictionary:

await volidator.log({
action: "user.login",
metadata: {
avatar_url: session.user.imageUrl // Securely encrypted client-side
}
});

The Volidator Dashboard UI will automatically decrypt this URL client-side and render the rich avatar in your activity feed. If the image link ever expires (e.g. Google rotates the URL 2 years from now), the UI will gracefully fall back to displaying the user’s initials.