
Security News
Feross on the 10 Minutes or Less Podcast: Nobody Reads the Code
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.
@agentuity/auth
Advanced tools
First-class authentication for Agentuity projects, powered by BetterAuth.
ctx.auth available on AgentContext and Hono routesuseAuth() for client-side auth statebun add @agentuity/auth
agentuity project auth init
This will:
src/auth.ts with default configuration# Create a database and get connection URL
agentuity cloud database create --region use
# Run auth migrations
agentuity project auth setup
// src/auth.ts
import { createAuth, createSessionMiddleware, mountAuthRoutes } from '@agentuity/auth';
export const auth = createAuth({
connectionString: process.env.DATABASE_URL,
// Uses AGENTUITY_AUTH_SECRET env var by default
});
export const authMiddleware = createSessionMiddleware(auth);
export const optionalAuthMiddleware = createSessionMiddleware(auth, { optional: true });
// src/api/index.ts
import { createRouter } from '@agentuity/runtime';
import { auth, authMiddleware } from '../auth';
import { mountAuthRoutes } from '@agentuity/auth';
const api = createRouter();
// Mount auth routes (sign-in, sign-up, sign-out, session, etc.)
api.on(['GET', 'POST'], '/api/auth/*', mountAuthRoutes(auth));
// Protect API routes
api.use('/api/*', authMiddleware);
api.get('/api/me', async (c) => {
const user = await c.var.auth.getUser();
return c.json({ id: user.id, email: user.email });
});
export default api;
// src/web/auth-client.ts
import { createAuthClient } from '@agentuity/auth/react';
export const authClient = createAuthClient();
export const { signIn, signUp, signOut, useSession } = authClient;
// src/web/frontend.tsx
import { AgentuityProvider } from '@agentuity/react';
import { createAuthClient, AuthProvider } from '@agentuity/auth/react';
import { App } from './App';
const authClient = createAuthClient();
<AgentuityProvider>
<AuthProvider authClient={authClient}>
<App />
</AuthProvider>
</AgentuityProvider>;
# Database connection
DATABASE_URL=postgresql://user:pass@host:5432/dbname
# Auth secret (generate with: openssl rand -hex 32)
AGENTUITY_AUTH_SECRET=your-secret-here
Auth is native on AgentContext - no wrappers needed:
import { createAgent } from '@agentuity/runtime';
export default createAgent('my-agent', {
handler: async (ctx, input) => {
// ctx.auth is available when using auth middleware
if (!ctx.auth) {
return { error: 'Please sign in' };
}
const user = await ctx.auth.getUser();
const org = await ctx.auth.getOrg();
// Check organization roles
if (org && (await ctx.auth.hasOrgRole('admin'))) {
// Admin-only logic
}
return { userId: user.id, orgId: org?.id };
},
});
import { createSessionMiddleware, createApiKeyMiddleware } from '@agentuity/auth';
// Session-based auth
api.get('/api/profile', authMiddleware, async (c) => {
const user = await c.var.auth.getUser();
return c.json({ email: user.email });
});
// API key auth
api.use('/api/v1/*', createApiKeyMiddleware(auth));
api.get('/api/v1/data', async (c) => {
// Check API key permissions
if (!c.var.auth.hasPermission('data', 'read')) {
return c.json({ error: 'Forbidden' }, 403);
}
return c.json({ data: '...' });
});
import { useAuth } from '@agentuity/react';
import { useAuth } from '@agentuity/auth/react';
function Profile() {
// Basic auth state from @agentuity/react
const { isAuthenticated, authLoading } = useAuth();
// Full auth context from @agentuity/auth
const { user, isPending } = useAuth();
if (authLoading || isPending) return <div>Loading...</div>;
if (!isAuthenticated) return <div>Please sign in</div>;
return <div>Welcome, {user?.name}!</div>;
}
import { createAuth } from '@agentuity/auth';
export const auth = createAuth({
connectionString: process.env.DATABASE_URL,
});
Merge auth schema with your app schema:
import { drizzle } from 'drizzle-orm/bun-sql';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import * as authSchema from '@agentuity/auth/schema';
import * as myAppSchema from './schema';
const schema = { ...authSchema, ...myAppSchema };
const db = drizzle(process.env.DATABASE_URL!, { schema });
export const auth = createAuth({
database: drizzleAdapter(db, { provider: 'pg', schema: authSchema }),
});
Use any BetterAuth-compatible adapter:
import { prismaAdapter } from 'better-auth/adapters/prisma';
export const auth = createAuth({
database: prismaAdapter(new PrismaClient()),
});
createAuth(options)Creates an auth instance with Agentuity defaults.
Options:
connectionString?: string - PostgreSQL connection URL (simplest path)database?: Adapter - BetterAuth database adapter (for advanced use)secret?: string - Auth secret (defaults to AGENTUITY_AUTH_SECRET env var)basePath?: string - API path prefix (default: /api/auth)emailAndPassword?: { enabled: boolean } - Email auth (default: { enabled: true })skipDefaultPlugins?: boolean - Skip organization, JWT, bearer, API key pluginsapiKey?: ApiKeyPluginOptions | false - API key configurationplugins?: Plugin[] - Additional BetterAuth pluginscreateSessionMiddleware(auth, options?)Hono middleware for session-based auth.
Options:
optional?: boolean - If true, don't 401 on missing authotelSpans?: { email?: boolean, orgName?: boolean } - Control PII in spanscreateApiKeyMiddleware(auth, options?)Hono middleware for API key auth.
Options:
optional?: boolean - If true, don't 401 on missing API keyotelSpans?: { email?: boolean } - Control PII in spansmountAuthRoutes(auth, options?)Handler for BetterAuth routes with cookie merging.
Options:
allowList?: string[] - Headers to forward from auth responsescreateAuthClient(options?)Import from @agentuity/auth/react.
Options:
baseURL?: string - API base URL (default: window.location.origin)basePath?: string - Auth path prefix (default: /api/auth)skipDefaultPlugins?: boolean - Skip organization and API key pluginsplugins?: Plugin[] - Additional client pluginsReturns: BetterAuth client with signIn, signUp, signOut, useSession, etc.
AuthProviderReact provider that bridges auth state to Agentuity context.
import { AuthProvider } from '@agentuity/auth/react';
<AuthProvider authClient={authClient} refreshInterval={3600000}>
{children}
</AuthProvider>;
Props:
authClient - Auth client instance (required)refreshInterval - Token refresh interval in milliseconds (default: 3600000 / 1 hour)tokenEndpoint - Token endpoint path or false to disable (default: '/token')// High-security: refresh every 30 seconds
<AuthProvider authClient={authClient} refreshInterval={30000}>
// Sensitive features: refresh every 5 minutes
<AuthProvider authClient={authClient} refreshInterval={300000}>
// Default: refresh every hour
<AuthProvider authClient={authClient}>
See the refreshInterval JSDoc for detailed security recommendations.
useAuth()Hook for full auth context. Import from @agentuity/auth/react.
Returns:
user: AuthUser | nullisPending: booleanerror: Error | nullisAuthenticated: booleanauthClient: AuthClientImport from @agentuity/auth/schema:
import { user, session, organization, apikey, authSchema } from '@agentuity/auth/schema';
Tables:
user - User accountssession - Active sessionsaccount - OAuth/credential accountsverification - Email verification tokensorganization - Organizationsmember - Organization membershipsinvitation - Pending invitationsjwks - JWT signing keysapikey - API keysCombined:
authSchema - All tables and relations for easy spreadingimport type {
AuthUser,
AuthSession,
AuthContext,
AuthOrgContext,
AuthApiKeyContext,
AuthMethod,
AuthInterface,
} from '@agentuity/auth';
# Initialize auth in a project
agentuity project auth init
# Run database migrations
agentuity project auth setup
# Generate Drizzle schema
agentuity project auth generate
# Generate a secure secret
agentuity project auth secret
.env files or expose AGENTUITY_AUTH_SECRETAGENTUITY_AUTH_SECRET on a regular scheduleotelSpans: { email: false } to exclude sensitive data from telemetryhasPermission() for API key routesGet started quickly:
bunx agentuity create my-app --template agentuity-auth
Agentuity Auth is the recommended solution. For Clerk, Auth0, or other providers, see:
MIT
FAQs
Authentication for Agentuity projects using Agentuity Auth
The npm package @agentuity/auth receives a total of 3,221 weekly downloads. As such, @agentuity/auth popularity was classified as popular.
We found that @agentuity/auth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.

Research
/Security News
Campaign of 108 extensions harvests identities, steals sessions, and adds backdoors to browsers, all tied to the same C2 infrastructure.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.