Adding Authentication
Add user authentication with Clerk, Auth0, or other identity providers
Protect your agents and routes with user authentication. The @agentuity/auth package provides integrations for identity providers.
Quick Start
A Clerk template is available for new projects:
bunx agentuity create my-app --template clerk
cd my-app
cp .env.example .env
# Add your Clerk keys from https://dashboard.clerk.com
bun run devFor Auth0 or other providers, follow the manual setup guides below.
Clerk
Installation
bun add @agentuity/auth @clerk/clerk-react @clerk/backendClient Setup
Wrap your app with the Clerk and Agentuity providers:
import React from 'react';
import { createRoot } from 'react-dom/client';
import { ClerkProvider, useAuth } from '@clerk/clerk-react';
import { AgentuityProvider } from '@agentuity/react';
import { AgentuityClerk } from '@agentuity/auth/clerk';
import { App } from './App';
const CLERK_KEY = process.env.AGENTUITY_PUBLIC_CLERK_PUBLISHABLE_KEY;
createRoot(document.getElementById('root')!).render(
<ClerkProvider publishableKey={CLERK_KEY!}>
<AgentuityProvider>
<AgentuityClerk useAuth={useAuth}>
<App />
</AgentuityClerk>
</AgentuityProvider>
</ClerkProvider>
);Provider Order
AgentuityClerk must be inside both ClerkProvider and AgentuityProvider. The order matters.
Server Middleware
Protect routes with createMiddleware():
import { createRouter } from '@agentuity/runtime';
import { createMiddleware } from '@agentuity/auth/clerk';
const router = createRouter();
// Protected route - requires authentication
router.get('/profile', createMiddleware(), async (c) => {
const user = await c.var.auth.requireUser();
return c.json({
id: user.id,
name: user.name,
email: user.email,
});
});
// Public route - no auth required
router.get('/public', (c) => {
return c.json({ message: 'Anyone can access this' });
});
export default router;Environment Variables
| Variable | Side | Description |
|---|---|---|
AGENTUITY_PUBLIC_CLERK_PUBLISHABLE_KEY | Client | Clerk publishable key (bundled into frontend) |
CLERK_SECRET_KEY | Server | Clerk secret key (never exposed to client) |
AGENTUITY_PUBLIC_ Prefix
Environment variables prefixed with AGENTUITY_PUBLIC_ are bundled into the frontend build and accessible via process.env. Keep secrets (like CLERK_SECRET_KEY) without this prefix.
Clerk-Specific Data
Access Clerk-specific fields via user.raw:
router.get('/profile', createMiddleware(), async (c) => {
const user = await c.var.auth.requireUser();
// Clerk-specific fields (fully typed)
const imageUrl = user.raw.imageUrl;
const metadata = user.raw.publicMetadata;
const createdAt = user.raw.createdAt;
// Access JWT payload
const payload = c.var.auth.raw;
c.var.logger.debug('JWT payload', { sub: payload.sub });
return c.json({ user, imageUrl });
});Auth0
Installation
bun add @agentuity/auth @auth0/auth0-reactClient Setup
Wrap your app with the Auth0 and Agentuity providers:
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Auth0Provider, useAuth0 } from '@auth0/auth0-react';
import { AgentuityProvider } from '@agentuity/react';
import { AgentuityAuth0 } from '@agentuity/auth/auth0';
import { App } from './App';
const domain = process.env.AGENTUITY_PUBLIC_AUTH0_DOMAIN;
const clientId = process.env.AGENTUITY_PUBLIC_AUTH0_CLIENT_ID;
createRoot(document.getElementById('root')!).render(
<Auth0Provider
domain={domain!}
clientId={clientId!}
authorizationParams={{ redirect_uri: window.location.origin }}
>
<AgentuityProvider>
<AgentuityAuth0 useAuth0={useAuth0}>
<App />
</AgentuityAuth0>
</AgentuityProvider>
</Auth0Provider>
);Server Middleware
Protect routes with Auth0's createMiddleware():
import { createRouter } from '@agentuity/runtime';
import { createMiddleware } from '@agentuity/auth/auth0/server';
const router = createRouter();
router.get('/profile', createMiddleware(), async (c) => {
const user = await c.var.auth.getUser();
return c.json({
id: user.id,
name: user.name,
email: user.email,
});
});
export default router;Environment Variables
| Variable | Side | Description |
|---|---|---|
AGENTUITY_PUBLIC_AUTH0_DOMAIN | Client | Auth0 domain (e.g., your-tenant.auth0.com) |
AGENTUITY_PUBLIC_AUTH0_CLIENT_ID | Client | Auth0 application client ID |
AGENTUITY_PUBLIC_AUTH0_AUDIENCE | Client | Auth0 API audience (optional) |
AUTH0_DOMAIN | Server | Auth0 domain (server-side) |
AUTH0_AUDIENCE | Server | Auth0 API audience (optional) |
User Profile
By default, user info is fetched from Auth0's /userinfo endpoint. For richer profile data, set fetchUserProfile: true in the middleware options and configure AUTH0_M2M_CLIENT_ID and AUTH0_M2M_CLIENT_SECRET for Management API access.
Common Patterns
These patterns work with any supported provider.
Using Auth State in Components
The useAgentuity hook provides authentication state:
import { useAPI, useAgentuity } from '@agentuity/react';
function Dashboard() {
const { isAuthenticated, authLoading } = useAgentuity();
const { data, refetch } = useAPI('GET /api/profile');
if (authLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return <div>Please sign in to continue</div>;
}
return (
<div>
<h1>Welcome, {data?.name}</h1>
<button onClick={() => refetch()}>Refresh Profile</button>
</div>
);
}Once your auth provider is set up, useAPI and useWebsocket automatically include the auth token in requests.
Accessing User Data
All providers expose a common interface:
router.get('/profile', createMiddleware(), async (c) => {
const user = await c.var.auth.requireUser();
// Available on all providers
c.var.logger.info('User authenticated', {
id: user.id,
name: user.name,
email: user.email,
});
return c.json(user);
});Global Middleware
Protect all routes under a path prefix:
import { createRouter } from '@agentuity/runtime';
import { createMiddleware } from '@agentuity/auth/clerk';
const router = createRouter();
// Protect all /api/* routes
router.use('/api/*', createMiddleware());
router.get('/api/profile', async (c) => {
const user = await c.var.auth.requireUser();
return c.json({ email: user.email });
});
router.get('/api/settings', async (c) => {
const user = await c.var.auth.requireUser();
return c.json({ userId: user.id });
});
export default router;Other Providers
For identity providers not yet supported by @agentuity/auth, use JWT middleware to validate tokens from your provider.
Next Steps
- Middleware & Authentication: More middleware patterns
- Provider Setup: AgentuityProvider configuration
- React Hooks: Building custom UIs
Need Help?
Join our Community for assistance or just to hang with other humans building agents.
Send us an email at hi@agentuity.com if you'd like to get in touch.
Please Follow us on
If you haven't already, please Signup for your free account now and start building your first agent!