DEV Community

Cover image for Integrate an Audit Trail for NextAuth.js in a few lines of code
Pranav Shikarpur for Pangea

Posted on • Originally published at pangea.cloud

4

Integrate an Audit Trail for NextAuth.js in a few lines of code

In the world where hackers are trying to brute force user accounts (23andMe breach 2023) and session tokens are being stolen (OKTA breach 2023) to impersonate authenticated users and run critical user actions, it is highly important for developers to maintain a tamper-proof audit log of all authentication events to keep their apps secure.

An audit log is a log service that’s used to keep track of all critical and sensitive user actions that take place across your applications. Events being logged could include sensitive file access, user logins, deleting or updating database records, etc.

What are the Advantages of an Tamperproof Audit Log?

  • Identify Risk of Exposure
    A robust tamperproof audit log can help quickly assess the risk of exposure after a data breach since you have logs of all user events and critical user actions that occurred in our app.

  • Can’t be Tampered with
    Since message hashes of Pangea Audit Logs have been designed to be stored in a cryptographically secure hash-tree called “Merkle Trees”, the logs are tamperproof and cryptographically verifiable. Thus Pangea Audit Logs can neither be changed nor destroyed once created.

  • Asynchronous Logging
    Since Pangea Audit Logs can be implemented asynchronously with our authentication system and APIs, it doesn’t affect the performance of our web apps.

Adding the Audit Trail to Our NextAuth.js App

In this tutorial, I will demonstrate how easy it is to add a tamper-proof audit log to an authentication setup. For the purposes of this tutorial, I’m going to use NextAuth.js - a popular JavaScript authentication library - to demonstrate how we can add secure audit logging to our JavaScript apps in just a few lines of code.

To follow along, head over to next-auth.js.org and follow the “Getting Started” tutorial. Once we’ve setup our Next.js app with NextAuth, we’re going to update the [...next-auth].ts file to include an events code block that will send data to the Pangea Audit Log API asynchronously on every signIn and signOut event.



import NextAuth from "next-auth"
import { User } from "next-auth"

// Imports to add
import { JWT } from "next-auth/jwt";
import auditLogToPangea from "@/utils/auditLog";

export const authOptions = {
 // Configure one or more authentication providers
 providers: [
   // List all your providers here
// ...
 ],

 // events code block to add
 events: {
   async signIn({ user, isNewUser }: { user: User, isNewUser?: boolean | undefined }) {
       const auditLogData = {
           email: user.email as string,
           name: user.name as string,
           message: isNewUser ? "User signed up" : "User logged in",
           event: isNewUser ? "signup" : "login",
       }

    // Call pangea secure audit log on sign in
       await auditLogToPangea(auditLogData);
   },
    async signOut({token}: {token: JWT}) {
        const auditLogData = {
            email: token.email as string,
            name: token.name as string,
            message: "User logged out",
            event: "logout",
            }

        // Call pangea secure audit log on sign out
        await auditLogToPangea(auditLogData);
       }
   }
// end events code block
}

export default NextAuth(authOptions)


Enter fullscreen mode Exit fullscreen mode

Now that we’ve added code to make an audit log happen on every signIn and signOut event, let’s create the auditLogToPangea function in the src/utils folder that uses the pangea-node-sdk to send log data to the Pangea secure audit log API.

Create the file auditLog.ts



import { PangeaConfig, AuditService, PangeaErrors } from "pangea-node-sdk";

const auditLogToPangea = async (logData: any) => {
   const token = process.env.PANGEA_TOKEN as string;
   const config = new PangeaConfig({ domain: process.env.PANGEA_DOMAIN });
   const audit = new AuditService(token, config);

   const data = {
       "message": logData.message,
       "action": logData.event,
       "email": logData.email,
       "name": logData.name,
       "target": logData.target ? logData.target : "",
   }

   try {
       console.log("Logging: %s", data);
       const logResponse = await audit.log(data as any, { verbose: true });
       console.log("Response: %s", logResponse.result);

       return true;
     } catch (err) {
       if (err instanceof PangeaErrors.APIError) {
         console.log(err.summary, err.pangeaResponse);
         return false;
       } else {
         throw err;
       }
   }
}
export default auditLogToPangea;


Enter fullscreen mode Exit fullscreen mode

You’re all set 🎉, now every time any user logs into our Next.js app using next-auth authentication setup, the user information along with the event is automatically audit logged and if we go to View Logs section in the Pangea User Console, we should see something like the following:

Image description

Further Steps:

Now that we’ve seen how easy it is to add an audit log to our authentication setup, we can go ahead and add audit logging to all the APIs used to perform critical user actions such as fetching PII, updating sensitive user fields, billing transactions, etc. We could either add this directly for each API in the app or run it as middleware to be able to log all user information going in and out of the applications APIs.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay