npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

auth-agent-better-auth

v0.1.0

Published

Better Auth plugin for Auth Agent - OAuth 2.1 authentication for AI agents

Readme

@auth-agent/better-auth-plugin

Better Auth plugin for Auth Agent - OAuth 2.1 authentication for AI agents.

npm version License: MIT

What is this?

This plugin enables websites using Better Auth to add AI agent authentication via Auth Agent in just a few lines of code.

Instead of building two separate authentication systems (one for humans, one for agents), you get:

  • Unified authentication - Humans and AI agents use the same Better Auth session system
  • One-line setup - Add Auth Agent as a Better Auth plugin
  • Production ready - Full OAuth 2.1 with PKCE, rate limiting, error handling
  • Type-safe - Complete TypeScript support with type inference
  • React components - Pre-built <AuthAgentButton /> component

Quick Start

Installation

npm install @auth-agent/better-auth-plugin better-auth

Server Setup

// lib/auth.ts
import { betterAuth } from "better-auth";
import { authAgent } from "@auth-agent/better-auth-plugin/server";

export const auth = betterAuth({
  database: {
    provider: "postgres",
    url: process.env.DATABASE_URL!,
  },

  plugins: [
    authAgent({
      clientId: process.env.AUTH_AGENT_CLIENT_ID!,
      clientSecret: process.env.AUTH_AGENT_CLIENT_SECRET!,
    }),
  ],
});

// app/api/auth/[...all]/route.ts
import { auth } from "@/lib/auth";
export const { GET, POST } = auth.handler;

Client Setup

// lib/auth-client.ts
import { createAuthClient } from "better-auth/react";
import { authAgentClient } from "@auth-agent/better-auth-plugin/client";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_APP_URL!,
  plugins: [authAgentClient()],
});

React Component

import { AuthAgentButton } from "@auth-agent/better-auth-plugin/client/react";

export default function Page() {
  return (
    <div>
      <h1>Sign In</h1>

      {/* For humans */}
      <button onClick={() => signIn.social({ provider: "google" })}>
        Sign in with Google
      </button>

      {/* For AI agents */}
      <AuthAgentButton callbackURL="/dashboard" />
    </div>
  );
}

That's it! Your app now supports both human and AI agent authentication.

How It Works

Authentication Flows

Human Users (Better Auth Native):

User → Google/Email/etc → Better Auth → Session Created

AI Agents (Auth Agent Plugin):

Agent → "Sign in with Auth Agent" Button
      → OAuth 2.1 Authorization (Auth Agent Server)
      → Agent Authenticates (back-channel with agent_id + agent_secret)
      → Authorization Code Returned
      → Better Auth Plugin Exchanges Code for Tokens
      → Session Created in Better Auth
      → Agent Accesses Website

Why This Integration?

Before:

  • Website builds custom auth system
  • Separately integrates Auth Agent OAuth
  • Manages two different session systems
  • Complex configuration

After:

  • Install Better Auth (handles human auth)
  • Add Auth Agent plugin (handles agent auth)
  • One unified session system
  • Production-ready in minutes

API Reference

Server Plugin Options

interface AuthAgentPluginOptions {
  /**
   * Auth Agent authorization server URL
   * @default "https://auth-agent-workers.hetkp8044.workers.dev"
   */
  authServerUrl?: string;

  /**
   * OAuth client ID (registered with Auth Agent)
   */
  clientId: string;

  /**
   * OAuth client secret (for server-side token exchange)
   */
  clientSecret: string;

  /**
   * OAuth scopes
   * @default "openid profile email"
   */
  scopes?: string;

  /**
   * Auto-create users if agent authenticates for unknown user
   * @default true
   */
  autoCreateUser?: boolean;

  /**
   * Custom user mapping from agent auth response
   */
  mapAgentToUser?: (agentData: AgentAuthData) => {
    email: string;
    name?: string;
    emailVerified?: boolean;
    image?: string;
  };

  /**
   * Custom callback to run after successful authentication
   */
  onSuccess?: (data: {
    user: any;
    session: any;
    agentData: AgentAuthData;
  }) => Promise<void> | void;
}

React Component Props

interface AuthAgentButtonProps {
  /**
   * Button text
   * @default "Sign in with Auth Agent"
   */
  text?: string;

  /**
   * CSS class name
   */
  className?: string;

  /**
   * Inline styles
   */
  style?: React.CSSProperties;

  /**
   * Callback URL after authentication
   */
  callbackURL?: string;

  /**
   * Callback before sign-in starts
   */
  onSignInStart?: () => void;

  /**
   * Error callback
   */
  onError?: (error: Error) => void;

  /**
   * Show loading state
   * @default true
   */
  showLoading?: boolean;

  /**
   * Disabled state
   */
  disabled?: boolean;
}

Headless Hook

If you want to build your own UI:

import { useAuthAgent } from "@auth-agent/better-auth-plugin/client/react";

function CustomButton() {
  const { signIn, loading, error } = useAuthAgent();

  return (
    <button
      onClick={() => signIn({ callbackURL: "/dashboard" })}
      disabled={loading}
    >
      {loading ? "Loading..." : "Sign in"}
    </button>
  );
}

Advanced Usage

Custom User Mapping

Map agent data to your user schema:

authAgent({
  clientId: process.env.AUTH_AGENT_CLIENT_ID!,
  clientSecret: process.env.AUTH_AGENT_CLIENT_SECRET!,

  mapAgentToUser: (agentData) => ({
    email: agentData.email,
    name: agentData.name || `Agent ${agentData.agent_id}`,
    emailVerified: true,
    image: `https://api.dicebear.com/7.x/bottts/svg?seed=${agentData.agent_id}`,
  }),
});

Success Callback

Run custom logic after authentication:

authAgent({
  clientId: process.env.AUTH_AGENT_CLIENT_ID!,
  clientSecret: process.env.AUTH_AGENT_CLIENT_SECRET!,

  onSuccess: async ({ user, session, agentData }) => {
    // Log authentication
    await logEvent("agent_auth", {
      userId: user.id,
      agentId: agentData.agent_id,
    });

    // Send notification
    await sendSlackNotification(
      `Agent ${agentData.agent_id} authenticated as ${user.email}`
    );
  },
});

Custom Styling

Customize the button appearance:

<AuthAgentButton
  text="AI Agent Sign In"
  className="custom-button"
  style={{
    backgroundColor: "#4A5568",
    borderRadius: "16px",
    padding: "16px 32px",
  }}
/>

Environment Variables

Required environment variables:

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"

# Better Auth
BETTER_AUTH_SECRET="your-secret-key-min-32-chars"
BETTER_AUTH_URL="https://yourapp.com"

# Auth Agent OAuth
AUTH_AGENT_CLIENT_ID="your_client_id"
AUTH_AGENT_CLIENT_SECRET="your_client_secret"

# Public
NEXT_PUBLIC_APP_URL="https://yourapp.com"

Getting Auth Agent Credentials

  1. Sign up at Auth Agent Dashboard
  2. Create a new OAuth client
  3. Add your redirect URIs:
    • Development: http://localhost:3000/api/auth/callback/auth-agent
    • Production: https://yourapp.com/api/auth/callback/auth-agent
  4. Copy your client_id and client_secret

Testing with AI Agents

Using browser-use

from browser_use import Agent
from langchain_openai import ChatOpenAI

agent = Agent(
    task="Go to https://yourapp.com and sign in with Auth Agent",
    llm=ChatOpenAI(model="gpt-4"),
)

result = agent.run()

Using Playwright

from auth_agent_agent_sdk import AuthAgentAgentSDK

sdk = AuthAgentAgentSDK(
    agent_id="your_agent_id",
    agent_secret="your_agent_secret",
)

# Agent will automatically authenticate when it encounters the auth page
status = sdk.complete_authentication_flow("https://yourapp.com")

Examples

See the examples/nextjs-app directory for a complete working example.

Security

This plugin implements:

  • PKCE (RFC 7636) - Proof Key for Code Exchange
  • State Validation - CSRF protection
  • Rate Limiting - Prevent abuse
  • Secure Token Storage - Server-side only
  • Token Expiration - Automatic cleanup
  • HTTPS Enforcement - Secure redirects

Compatibility

  • Better Auth: ^1.4.0
  • React: ^18.0.0 || ^19.0.0
  • Node.js: ^18.0.0 || ^20.0.0 || ^22.0.0

Contributing

Contributions are welcome! Please see CONTRIBUTING.md.

License

MIT © Auth Agent

Links

Support