NewkavachOS v0.1.0 -- edge runtime, D1 provider, Web CryptoSee releases →
kavachOS
Comparison

Best open source auth libraries for AI agents (2026)

I needed auth for 50+ agents talking to MCP tool servers. Most libraries assume you're building a login page. Here's what actually worked.

GD

Gagan Deep Singh

Founder, GLINCKER

March 30, 202612 min read

I hit this problem a few months back. About 50 agents, each talking to different MCP tool servers, and I couldn't answer a basic question: which agent did what, and who said it could?

Most auth libraries didn't help. They were built for humans logging into web apps. Sessions, cookies, redirect flows. My agents don't have browsers. They need their own tokens, scoped permissions, and when one spins up a sub-agent, I need some way to track that chain. Without it you're just staring at logs guessing which agent made which call.

I tried five libraries. Here's what I found.

TL;DR

KavachOS is the only one on this list built for agents. Quickstart here. Read on if you want the full picture.

At a glance

LibraryAgent identityMCP OAuthDelegation chainsSelf-hostEdge runtimeLicense
Better AuthMIT
KavachOSMIT
LuciaMIT
KeycloakApache 2.0
Supabase AuthApache 2.0

Agent capabilities

This is where things get thin. Only one library was actually built with agents in mind.

FeatureBetter AuthKavachOSLuciaKeycloakSupabase
Agent identity tokens
Per-agent permission scopingPartial
Delegation chains
Trust scoring
Agent audit trail
MCP OAuth 2.1 (PKCE, RFC 9728)

Human auth (all roughly equal here)

FeatureBetter AuthKavachOSLuciaKeycloakSupabase
Email/password
Social OAuth
Passkeys
Magic link
MFA
Enterprise SSO (SAML)Paid

Infrastructure and DX

FeatureBetter AuthKavachOSLuciaKeycloakSupabase
TypeScript native
Edge runtime (Workers, Deno)
SQLite / D1
PostgreSQL
npm install setupDockerHosted

The core problem, visualized

diagram
Human auth (what most libraries give you):

  Browser ──> Login page ──> Session cookie ──> API calls
                                 └── expires, user re-authenticates

Agent auth (what you actually need):

  Orchestrator Agent
       │
       ├── Token (kv_abc..., scoped, 24h TTL)
       │     └── Permissions: [repo:read, pr:comment]
       │
       ├── Delegates to Sub-Agent
       │     └── Token (kv_xyz..., subset, 1h TTL)
       │           └── Permissions: [repo:read] only
       │
       └── Audit Trail
             └── Every authorize() logged: agent, action, result, timestamp

See the gap? Most libraries only handle the top half.

Better Auth

github.com/better-auth/better-auth

Best TypeScript auth library for regular apps, full stop. The plugin system covers basically anything you'd want for human auth. I've used it on two other projects and never had complaints.

typescript
import { betterAuth } from "better-auth";

const auth = betterAuth({
  database: { provider: "sqlite", url: "./auth.db" },
  emailAndPassword: { enabled: true },
  plugins: [twoFactor(), organization()],
});

I tried making it work for agents by creating "service users" with restricted roles. Got basic tokens going within a day. But then I needed delegation — agent A passing a subset of its permissions to agent B — and there's just no clean way to do that. The abstractions assume a human on the other end.

Also no MCP OAuth support. If you're running MCP tool servers, you'd need to build that layer yourself.

Perfectly good library. Wrong problem.

KavachOS

github.com/kavachos/kavachos

This is what I ended up using. I'll be upfront: I'm biased because it solved my problem. But I'll be honest about the rough edges too.

The difference is that agents are the primary concept here, not users. You create an AgentIdentity with scoped permissions, not a session with a cookie.

typescript
import { createKavach } from "kavachos";

const kavach = await createKavach({
  database: { provider: "sqlite", url: "./kavach.db" },
});

const agent = await kavach.agent.create({
  ownerId: "user-123",
  name: "code-reviewer",
  type: "autonomous",
  permissions: [
    { resource: "mcp:github:*", actions: ["read"] },
    { resource: "mcp:github:pull_requests", actions: ["read", "comment"] },
  ],
});

// logged to audit trail automatically
const result = await kavach.authorize(agent.id, {
  action: "read",
  resource: "mcp:github:repos",
});

// delegate a subset to a sub-agent, 1h expiry, max 2 hops
await kavach.delegate({
  fromAgent: agent.id,
  toAgent: subAgent.id,
  permissions: [{ resource: "mcp:github:issues", actions: ["read"] }],
  expiresAt: new Date(Date.now() + 3600_000),
  maxDepth: 2,
});

The delegation part is what got me. My orchestrator creates sub-agents for specific tasks, each gets a time-limited slice of permissions that auto-expires. When a compliance person asked "show me every action this agent took last Tuesday" I exported the CSV in about 10 seconds. That felt good.

MCP OAuth 2.1 works out of the box. PKCE S256, resource indicators, server metadata discovery, dynamic client registration. I'm running the whole thing on Cloudflare Workers.

Now the bad parts. Community is small. If you hit a weird edge case you're reading source code, not Stack Overflow. The plugin ecosystem is thin compared to Better Auth. Docs are getting better but there are still gaps. If you only need human auth, don't use this — it's more machinery than the job needs.

Lucia

github.com/lucia-auth/lucia

I'd used Lucia before and always liked the simplicity. Small API, clean types, no magic. The creator deprecated it in late 2024 in favor of oslo and arctic, but plenty of projects still run it.

typescript
import { Lucia } from "lucia";
import { DrizzleSQLiteAdapter } from "@lucia-auth/adapter-drizzle";

const adapter = new DrizzleSQLiteAdapter(db, sessionTable, userTable);
const lucia = new Lucia(adapter, {
  sessionCookie: { attributes: { secure: true } },
});

const session = await lucia.createSession(userId, {});

For what it does, nothing to criticize. Clean session auth with no extra weight.

For agents it's a dead end. Sessions are a browser concept. There's no token model for background agents, no permissions, no audit trail. I thought about storing agent tokens in the session table for about five minutes before realizing I'd be fighting the library the whole way. And since it's deprecated, nothing new is coming.

Good for simple human auth. Wrong tool for agents.

Keycloak

github.com/keycloak/keycloak

The enterprise standard. Java, Red Hat-backed, been around since 2014. If you work at a company with more than 500 people, there's a decent chance Keycloak is running somewhere.

java
Keycloak keycloak = KeycloakBuilder.builder()
    .serverUrl("http://localhost:8080")
    .realm("master")
    .clientId("admin-cli")
    .username("admin")
    .password("admin")
    .build();

ClientRepresentation client = new ClientRepresentation();
client.setClientId("my-agent-service");
client.setServiceAccountsEnabled(true);
keycloak.realm("my-realm").clients().create(client);

You can model agents as service accounts with client credentials grants. I've seen teams do it and it works fine for basic cases. But there's no delegation, no agent-specific audit, no MCP support. And you can't run it on edge infrastructure because JVM.

The real barrier is complexity. Setting up Keycloak takes a week if you're doing it properly. Minimum 512MB RAM. Config happens through an admin UI, not code. For a team of three building an agent system, it felt like way too much.

If your company already runs Keycloak, use it. If you're starting from scratch, don't.

Supabase Auth

github.com/supabase/auth

GoTrue under the hood, written in Go, deeply integrated with Supabase and PostgreSQL. Free tier gives you 50K MAU. If you're already on Supabase, auth comes for free.

typescript
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

const { data, error } = await supabase.auth.signUp({
  email: "dev@example.com",
  password: "secure-password-123",
});

Row-level security is the interesting part. Policies on Postgres tables, enforced automatically. For data authorization this works well.

For agents, not so much. Auth is coupled to PostgreSQL, so if you're using SQLite or D1, you're importing a whole database engine just for auth. The service role key is all-or-nothing. RLS handles "can this user read this row" but not "can this agent run a deployment." No delegation, no MCP support.

Good if you're already on Supabase. Not worth adopting just for auth.

The short version

Your situationUse this
Regular web app, no agentsBetter Auth
Agent infrastructure, MCP serversKavachOS
Enterprise with Java/SSO alreadyKeycloak (service accounts)
Already on SupabaseSupabase Auth + KavachOS
Need MCP OAuth 2.1KavachOS (only option right now)

The tradeoff with KavachOS is a smaller community and docs that are still catching up. If that's a dealbreaker, you'll end up building agent auth on top of Better Auth or Keycloak yourself. Most teams are doing that right now, honestly.

Agent auth tooling is early. Most of the industry is duct-taping human auth onto agent systems and hoping nobody asks hard questions. That works for a while.

Share this post

Get started

Try kavachOS Cloud free

Free up to 1,000 MAU. Agent identity, MCP OAuth, and audit trail on every plan.