@agentuity/auth 0.0.108 → 0.0.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/AGENTS.md +82 -28
  2. package/README.md +259 -236
  3. package/dist/agentuity/config.d.ts +2386 -0
  4. package/dist/agentuity/config.d.ts.map +1 -0
  5. package/dist/agentuity/config.js +220 -0
  6. package/dist/agentuity/config.js.map +1 -0
  7. package/dist/agentuity/plugins/api-key.d.ts +152 -0
  8. package/dist/agentuity/plugins/api-key.d.ts.map +1 -0
  9. package/dist/agentuity/plugins/api-key.js +21 -0
  10. package/dist/agentuity/plugins/api-key.js.map +1 -0
  11. package/dist/agentuity/plugins/index.d.ts +23 -0
  12. package/dist/agentuity/plugins/index.d.ts.map +1 -0
  13. package/dist/agentuity/plugins/index.js +10 -0
  14. package/dist/agentuity/plugins/index.js.map +1 -0
  15. package/dist/agentuity/plugins/jwt.d.ts +34 -0
  16. package/dist/agentuity/plugins/jwt.d.ts.map +1 -0
  17. package/dist/agentuity/plugins/jwt.js +11 -0
  18. package/dist/agentuity/plugins/jwt.js.map +1 -0
  19. package/dist/agentuity/plugins/organization.d.ts +355 -0
  20. package/dist/agentuity/plugins/organization.d.ts.map +1 -0
  21. package/dist/agentuity/plugins/organization.js +12 -0
  22. package/dist/agentuity/plugins/organization.js.map +1 -0
  23. package/dist/agentuity/react.d.ts +1375 -0
  24. package/dist/agentuity/react.d.ts.map +1 -0
  25. package/dist/agentuity/react.js +206 -0
  26. package/dist/agentuity/react.js.map +1 -0
  27. package/dist/agentuity/server.d.ts +220 -0
  28. package/dist/agentuity/server.d.ts.map +1 -0
  29. package/dist/agentuity/server.js +505 -0
  30. package/dist/agentuity/server.js.map +1 -0
  31. package/dist/agentuity/types.d.ts +172 -0
  32. package/dist/agentuity/types.d.ts.map +1 -0
  33. package/dist/agentuity/types.js +7 -0
  34. package/dist/agentuity/types.js.map +1 -0
  35. package/dist/index.d.ts +31 -8
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +33 -8
  38. package/dist/index.js.map +1 -1
  39. package/dist/schema.d.ts +2922 -0
  40. package/dist/schema.d.ts.map +1 -0
  41. package/dist/schema.js +223 -0
  42. package/dist/schema.js.map +1 -0
  43. package/dist/types.d.ts +14 -18
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/types.js +1 -1
  46. package/package.json +15 -39
  47. package/src/agentuity/config.ts +401 -0
  48. package/src/agentuity/plugins/api-key.ts +158 -0
  49. package/src/agentuity/plugins/index.ts +35 -0
  50. package/src/agentuity/plugins/jwt.ts +30 -0
  51. package/src/agentuity/plugins/organization.ts +345 -0
  52. package/src/agentuity/react.tsx +328 -0
  53. package/src/agentuity/server.ts +734 -0
  54. package/src/agentuity/types.ts +201 -0
  55. package/src/index.ts +76 -8
  56. package/src/schema.ts +270 -0
  57. package/src/types.ts +14 -22
  58. package/test/agentuity/config.test.ts +621 -0
  59. package/test/agentuity/server.test.ts +537 -0
  60. package/test/schema.test.ts +147 -0
  61. package/tsconfig.json +3 -2
  62. package/tsconfig.tsbuildinfo +1 -1
  63. package/dist/auth0/client.d.ts +0 -44
  64. package/dist/auth0/client.d.ts.map +0 -1
  65. package/dist/auth0/client.js +0 -79
  66. package/dist/auth0/client.js.map +0 -1
  67. package/dist/auth0/index.d.ts +0 -35
  68. package/dist/auth0/index.d.ts.map +0 -1
  69. package/dist/auth0/index.js +0 -38
  70. package/dist/auth0/index.js.map +0 -1
  71. package/dist/auth0/server.d.ts +0 -91
  72. package/dist/auth0/server.d.ts.map +0 -1
  73. package/dist/auth0/server.js +0 -237
  74. package/dist/auth0/server.js.map +0 -1
  75. package/dist/clerk/client.d.ts +0 -42
  76. package/dist/clerk/client.d.ts.map +0 -1
  77. package/dist/clerk/client.js +0 -65
  78. package/dist/clerk/client.js.map +0 -1
  79. package/dist/clerk/index.d.ts +0 -37
  80. package/dist/clerk/index.d.ts.map +0 -1
  81. package/dist/clerk/index.js +0 -35
  82. package/dist/clerk/index.js.map +0 -1
  83. package/dist/clerk/server.d.ts +0 -55
  84. package/dist/clerk/server.d.ts.map +0 -1
  85. package/dist/clerk/server.js +0 -111
  86. package/dist/clerk/server.js.map +0 -1
  87. package/docs/adding-providers.md +0 -261
  88. package/src/auth0/client.tsx +0 -109
  89. package/src/auth0/index.ts +0 -40
  90. package/src/auth0/server.ts +0 -378
  91. package/src/clerk/client.tsx +0 -86
  92. package/src/clerk/index.ts +0 -37
  93. package/src/clerk/server.ts +0 -168
  94. package/test/clerk-client.test.tsx +0 -21
  95. package/test/clerk-server.test.ts +0 -51
package/README.md CHANGED
@@ -1,15 +1,16 @@
1
1
  # @agentuity/auth
2
2
 
3
- Drop-in authentication helpers for popular identity providers (Clerk, WorkOS, Auth0, Better Auth, etc.).
3
+ First-class authentication for Agentuity projects, powered by [BetterAuth](https://better-auth.com).
4
4
 
5
5
  ## Features
6
6
 
7
- - ✅ **Zero Configuration**: Drop-in components that work out of the box
8
- - ✅ **Provider Agnostic**: Generic interfaces allow routes to be provider-independent
9
- - ✅ **Tree Shakeable**: Import only the providers you use (`@agentuity/auth/clerk`)
10
- - ✅ **Type Safe**: Full TypeScript support with proper type inference
11
- - ✅ **Automatic Token Injection**: Seamless integration with `useAPI` and `useWebsocket`
12
- - ✅ **Server Validation**: Easy middleware for token validation and user context
7
+ - ✅ **Zero Configuration**: Works out of the box with just a database connection
8
+ - ✅ **Native Integration**: `ctx.auth` available on AgentContext and Hono routes
9
+ - ✅ **Organizations**: Multi-tenancy with roles and permissions
10
+ - ✅ **API Keys**: Programmatic access with fine-grained permissions
11
+ - ✅ **JWT Tokens**: Stateless auth for API calls
12
+ - ✅ **Drizzle Schema**: Type-safe database schema with migrations
13
+ - ✅ **React Hooks**: `useAuth()` for client-side auth state
13
14
 
14
15
  ## Installation
15
16
 
@@ -17,354 +18,376 @@ Drop-in authentication helpers for popular identity providers (Clerk, WorkOS, Au
17
18
  bun add @agentuity/auth
18
19
  ```
19
20
 
20
- ## Supported Providers
21
+ ## Quick Start
21
22
 
22
- - **Clerk** - `@agentuity/auth/clerk`
23
- - WorkOS - Coming soon
24
- - Auth0 - Coming soon
25
- - Better Auth - Coming soon
23
+ ### 1. Setup with CLI
26
24
 
27
- ## Quick Start
25
+ ```bash
26
+ agentuity project auth init
27
+ ```
28
28
 
29
- ### Clerk Integration
29
+ This will:
30
30
 
31
- #### 1. Install Clerk
31
+ - Install required dependencies
32
+ - Generate `src/auth.ts` with default configuration
33
+ - Set up environment variables
34
+
35
+ ### 2. Configure Database
32
36
 
33
37
  ```bash
34
- bun add @clerk/clerk-react @clerk/backend
38
+ # Create a database and get connection URL
39
+ agentuity cloud database create --region use
40
+
41
+ # Run auth migrations
42
+ agentuity project auth setup
35
43
  ```
36
44
 
37
- #### 2. Client Setup (React)
45
+ ### 3. Server Setup (Hono)
38
46
 
39
- ```tsx
40
- import React from 'react';
41
- import ReactDOM from 'react-dom/client';
42
- import { ClerkProvider, useAuth } from '@clerk/clerk-react';
43
- import { AgentuityProvider } from '@agentuity/react';
44
- import { AgentuityClerk } from '@agentuity/auth/clerk';
45
- import { App } from './App';
47
+ ```typescript
48
+ // src/auth.ts
49
+ import { createAuth, createSessionMiddleware, mountAuthRoutes } from '@agentuity/auth';
46
50
 
47
- ReactDOM.createRoot(document.getElementById('root')!).render(
48
- <React.StrictMode>
49
- <ClerkProvider publishableKey={process.env.AGENTUITY_PUBLIC_CLERK_PUBLISHABLE_KEY!}>
50
- <AgentuityProvider>
51
- <AgentuityClerk useAuth={useAuth}>
52
- <App />
53
- </AgentuityClerk>
54
- </AgentuityProvider>
55
- </ClerkProvider>
56
- </React.StrictMode>
57
- );
58
- ```
51
+ export const auth = createAuth({
52
+ connectionString: process.env.DATABASE_URL,
53
+ // Uses AGENTUITY_AUTH_SECRET env var by default
54
+ });
59
55
 
60
- #### 3. Server Setup (Hono)
56
+ export const authMiddleware = createSessionMiddleware(auth);
57
+ export const optionalAuthMiddleware = createSessionMiddleware(auth, { optional: true });
58
+ ```
61
59
 
62
60
  ```typescript
61
+ // src/api/index.ts
63
62
  import { createRouter } from '@agentuity/runtime';
64
- import { createMiddleware } from '@agentuity/auth/clerk';
63
+ import { auth, authMiddleware } from '../auth';
64
+ import { mountAuthRoutes } from '@agentuity/auth';
65
+
66
+ const api = createRouter();
65
67
 
66
- const router = createRouter();
68
+ // Mount auth routes (sign-in, sign-up, sign-out, session, etc.)
69
+ api.on(['GET', 'POST'], '/api/auth/*', mountAuthRoutes(auth));
67
70
 
68
- // Protected route
69
- router.get('/profile', createMiddleware(), async (c) => {
71
+ // Protect API routes
72
+ api.use('/api/*', authMiddleware);
73
+
74
+ api.get('/api/me', async (c) => {
70
75
  const user = await c.var.auth.getUser();
71
- return c.json({
72
- id: user.id,
73
- name: user.name,
74
- email: user.email,
75
- });
76
+ return c.json({ id: user.id, email: user.email });
76
77
  });
77
78
 
78
- export default router;
79
+ export default api;
79
80
  ```
80
81
 
81
- #### 4. Environment Variables
82
-
83
- Create a `.env` file:
82
+ ### 4. Client Setup (React)
84
83
 
85
- ```env
86
- # Client-side (bundled into frontend)
87
- AGENTUITY_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
84
+ ```tsx
85
+ // src/web/auth-client.ts
86
+ import { createAuthClient } from '@agentuity/auth/react';
88
87
 
89
- # Server-side (kept secret)
90
- CLERK_SECRET_KEY=sk_test_...
88
+ export const authClient = createAuthClient();
89
+ export const { signIn, signUp, signOut, useSession } = authClient;
91
90
  ```
92
91
 
93
- Get your keys from [Clerk Dashboard](https://dashboard.clerk.com).
92
+ ```tsx
93
+ // src/web/frontend.tsx
94
+ import { AgentuityProvider } from '@agentuity/react';
95
+ import { createAuthClient, AuthProvider } from '@agentuity/auth/react';
96
+ import { App } from './App';
94
97
 
95
- ## Usage
98
+ const authClient = createAuthClient();
96
99
 
97
- ### Client Side
100
+ <AgentuityProvider>
101
+ <AuthProvider authClient={authClient}>
102
+ <App />
103
+ </AuthProvider>
104
+ </AgentuityProvider>;
105
+ ```
98
106
 
99
- Once you wrap your app with `AgentuityClerk`, all `useAPI` and `useWebsocket` calls automatically include the auth token:
107
+ ### 5. Environment Variables
100
108
 
101
- ```tsx
102
- import { useAPI, useAuth } from '@agentuity/react';
109
+ ```env
110
+ # Database connection
111
+ DATABASE_URL=postgresql://user:pass@host:5432/dbname
103
112
 
104
- function MyComponent() {
105
- const { isAuthenticated, authLoading } = useAuth();
106
- const { data, invoke } = useAPI('POST /api/users');
113
+ # Auth secret (generate with: openssl rand -hex 32)
114
+ AGENTUITY_AUTH_SECRET=your-secret-here
115
+ ```
107
116
 
108
- if (authLoading) {
109
- return <div>Loading...</div>;
110
- }
117
+ ## Usage
111
118
 
112
- if (!isAuthenticated) {
113
- return <div>Please sign in</div>;
114
- }
119
+ ### Agent Access
115
120
 
116
- return <button onClick={() => invoke({ name: 'Alice' })}>Create User</button>;
117
- }
118
- ```
121
+ Auth is native on AgentContext - no wrappers needed:
119
122
 
120
- ### Server Side
123
+ ```typescript
124
+ import { createAgent } from '@agentuity/runtime';
121
125
 
122
- #### Basic Protection
126
+ export default createAgent('my-agent', {
127
+ handler: async (ctx, input) => {
128
+ // ctx.auth is available when using auth middleware
129
+ if (!ctx.auth) {
130
+ return { error: 'Please sign in' };
131
+ }
123
132
 
124
- ```typescript
125
- import { createMiddleware } from '@agentuity/auth/clerk';
133
+ const user = await ctx.auth.getUser();
134
+ const org = await ctx.auth.getOrg();
126
135
 
127
- // Protect a single route
128
- router.post('/admin', createMiddleware(), async (c) => {
129
- const user = await c.var.auth.getUser();
130
- return c.json({ admin: true, userId: user.id });
136
+ // Check organization roles
137
+ if (org && (await ctx.auth.hasOrgRole('admin'))) {
138
+ // Admin-only logic
139
+ }
140
+
141
+ return { userId: user.id, orgId: org?.id };
142
+ },
131
143
  });
132
144
  ```
133
145
 
134
- #### Global Middleware
146
+ ### Hono Routes
135
147
 
136
148
  ```typescript
137
- // Protect all routes under /api
138
- router.use('/api/*', createMiddleware());
149
+ import { createSessionMiddleware, createApiKeyMiddleware } from '@agentuity/auth';
139
150
 
140
- router.get('/api/profile', async (c) => {
151
+ // Session-based auth
152
+ api.get('/api/profile', authMiddleware, async (c) => {
141
153
  const user = await c.var.auth.getUser();
142
154
  return c.json({ email: user.email });
143
155
  });
156
+
157
+ // API key auth
158
+ api.use('/api/v1/*', createApiKeyMiddleware(auth));
159
+
160
+ api.get('/api/v1/data', async (c) => {
161
+ // Check API key permissions
162
+ if (!c.var.auth.hasPermission('data', 'read')) {
163
+ return c.json({ error: 'Forbidden' }, 403);
164
+ }
165
+ return c.json({ data: '...' });
166
+ });
144
167
  ```
145
168
 
146
- #### Access Provider-Specific Data
169
+ ### React Components
147
170
 
148
- ```typescript
149
- router.get('/profile', createMiddleware(), async (c) => {
150
- const user = await c.var.auth.getUser();
171
+ ```tsx
172
+ import { useAuth } from '@agentuity/react';
173
+ import { useAuth } from '@agentuity/auth/react';
151
174
 
152
- // Access generic fields
153
- console.log(user.id, user.email, user.name);
175
+ function Profile() {
176
+ // Basic auth state from @agentuity/react
177
+ const { isAuthenticated, authLoading } = useAuth();
154
178
 
155
- // Access Clerk-specific fields (fully typed)
156
- const clerkUser = user.raw; // Type: User from @clerk/backend
157
- console.log(clerkUser.imageUrl);
158
- console.log(clerkUser.publicMetadata);
179
+ // Full auth context from @agentuity/auth
180
+ const { user, isPending } = useAuth();
159
181
 
160
- // Access JWT payload
161
- const payload = c.var.auth.raw; // Type: ClerkJWTPayload
162
- console.log(payload.sub);
182
+ if (authLoading || isPending) return <div>Loading...</div>;
183
+ if (!isAuthenticated) return <div>Please sign in</div>;
163
184
 
164
- return c.json({ user });
165
- });
185
+ return <div>Welcome, {user?.name}!</div>;
186
+ }
166
187
  ```
167
188
 
168
- #### Custom Middleware Options
189
+ ## Database Configuration
190
+
191
+ ### Option A: Connection String (Simplest)
169
192
 
170
193
  ```typescript
171
- import { createMiddleware } from '@agentuity/auth/clerk';
172
-
173
- router.use(
174
- '/api/*',
175
- createMiddleware({
176
- secretKey: 'custom-secret',
177
- publishableKey: 'custom-publishable',
178
- getToken: (authHeader) => authHeader.replace('Custom ', ''),
179
- })
180
- );
194
+ import { createAuth } from '@agentuity/auth';
195
+
196
+ export const auth = createAuth({
197
+ connectionString: process.env.DATABASE_URL,
198
+ });
181
199
  ```
182
200
 
183
- ## API Reference
201
+ ### Option B: Bring Your Own Drizzle
184
202
 
185
- ### Client Components
203
+ Merge auth schema with your app schema:
186
204
 
187
- #### `AgentuityClerk`
205
+ ```typescript
206
+ import { drizzle } from 'drizzle-orm/bun-sql';
207
+ import { drizzleAdapter } from 'better-auth/adapters/drizzle';
208
+ import * as authSchema from '@agentuity/auth/schema';
209
+ import * as myAppSchema from './schema';
188
210
 
189
- React component that integrates Clerk with Agentuity context.
211
+ const schema = { ...authSchema, ...myAppSchema };
212
+ const db = drizzle(process.env.DATABASE_URL!, { schema });
190
213
 
191
- **Props:**
214
+ export const auth = createAuth({
215
+ database: drizzleAdapter(db, { provider: 'pg', schema: authSchema }),
216
+ });
217
+ ```
192
218
 
193
- - `useAuth: UseAuth` - Clerk's `useAuth` hook from `@clerk/clerk-react`
194
- - `children: React.ReactNode` - Your app components
195
- - `refreshInterval?: number` - Token refresh interval in ms (default: 60000)
219
+ ### Option C: Other Adapters
196
220
 
197
- **Example:**
221
+ Use any BetterAuth-compatible adapter:
198
222
 
199
- ```tsx
200
- <AgentuityClerk useAuth={useAuth} refreshInterval={30000}>
201
- <App />
202
- </AgentuityClerk>
223
+ ```typescript
224
+ import { prismaAdapter } from 'better-auth/adapters/prisma';
225
+
226
+ export const auth = createAuth({
227
+ database: prismaAdapter(new PrismaClient()),
228
+ });
203
229
  ```
204
230
 
205
- ### Server Middleware
231
+ ## API Reference
232
+
233
+ ### Server
206
234
 
207
- #### `createMiddleware(options?)`
235
+ #### `createAuth(options)`
208
236
 
209
- Creates Hono middleware for Clerk authentication.
237
+ Creates an auth instance with Agentuity defaults.
210
238
 
211
239
  **Options:**
212
240
 
213
- - `secretKey?: string` - Clerk secret key (defaults to `process.env.CLERK_SECRET_KEY`)
214
- - `publishableKey?: string` - Clerk publishable key (defaults to `process.env.AGENTUITY_PUBLIC_CLERK_PUBLISHABLE_KEY` or `process.env.CLERK_PUBLISHABLE_KEY`)
215
- - `getToken?: (authHeader: string) => string` - Custom token extractor
241
+ - `connectionString?: string` - PostgreSQL connection URL (simplest path)
242
+ - `database?: Adapter` - BetterAuth database adapter (for advanced use)
243
+ - `secret?: string` - Auth secret (defaults to `AGENTUITY_AUTH_SECRET` env var)
244
+ - `basePath?: string` - API path prefix (default: `/api/auth`)
245
+ - `emailAndPassword?: { enabled: boolean }` - Email auth (default: `{ enabled: true }`)
246
+ - `skipDefaultPlugins?: boolean` - Skip organization, JWT, bearer, API key plugins
247
+ - `apiKey?: ApiKeyPluginOptions | false` - API key configuration
248
+ - `plugins?: Plugin[]` - Additional BetterAuth plugins
216
249
 
217
- **Returns:** Hono `MiddlewareHandler`
250
+ #### `createSessionMiddleware(auth, options?)`
218
251
 
219
- **Behavior:**
252
+ Hono middleware for session-based auth.
220
253
 
221
- - Returns 401 if Authorization header is missing
222
- - Returns 401 if token is invalid
223
- - Sets `c.var.auth` with authenticated user context
254
+ **Options:**
224
255
 
225
- ### Context Hooks
256
+ - `optional?: boolean` - If true, don't 401 on missing auth
257
+ - `otelSpans?: { email?: boolean, orgName?: boolean }` - Control PII in spans
226
258
 
227
- #### `useAuth()`
259
+ #### `createApiKeyMiddleware(auth, options?)`
228
260
 
229
- Hook to access authentication state (from `@agentuity/react`).
261
+ Hono middleware for API key auth.
230
262
 
231
- **Returns:**
263
+ **Options:**
232
264
 
233
- ```typescript
234
- {
235
- authHeader?: string | null;
236
- authLoading?: boolean;
237
- isAuthenticated: boolean; // Convenience: !authLoading && authHeader !== null
238
- setAuthHeader?: (token: string | null) => void;
239
- setAuthLoading?: (loading: boolean) => void;
240
- }
241
- ```
265
+ - `optional?: boolean` - If true, don't 401 on missing API key
266
+ - `otelSpans?: { email?: boolean }` - Control PII in spans
242
267
 
243
- #### `useAgentuity()`
268
+ #### `mountAuthRoutes(auth, options?)`
244
269
 
245
- Hook to access Agentuity context (non-auth properties only, from `@agentuity/react`).
270
+ Handler for BetterAuth routes with cookie merging.
246
271
 
247
- **Returns:**
272
+ **Options:**
248
273
 
249
- ```typescript
250
- {
251
- baseUrl: string;
252
- }
253
- ```
274
+ - `allowList?: string[]` - Headers to forward from auth responses
254
275
 
255
- ### Types
276
+ ### Client
256
277
 
257
- #### `AgentuityAuthUser<T>`
278
+ #### `createAuthClient(options?)`
258
279
 
259
- Generic authenticated user interface.
280
+ Import from `@agentuity/auth/react`.
260
281
 
261
- ```typescript
262
- interface AgentuityAuthUser<T = unknown> {
263
- id: string;
264
- name?: string;
265
- email?: string;
266
- raw: T; // Provider-specific user object
267
- }
268
- ```
282
+ **Options:**
269
283
 
270
- #### `AgentuityAuth<TUser, TRaw>`
284
+ - `baseURL?: string` - API base URL (default: `window.location.origin`)
285
+ - `basePath?: string` - Auth path prefix (default: `/api/auth`)
286
+ - `skipDefaultPlugins?: boolean` - Skip organization and API key plugins
287
+ - `plugins?: Plugin[]` - Additional client plugins
271
288
 
272
- Generic authentication interface exposed on Hono context.
289
+ **Returns:** BetterAuth client with `signIn`, `signUp`, `signOut`, `useSession`, etc.
273
290
 
274
- ```typescript
275
- interface AgentuityAuth<TUser = unknown, TRaw = unknown> {
276
- getUser(): Promise<AgentuityAuthUser<TUser>>;
277
- getToken(): Promise<string | null>;
278
- raw: TRaw; // Provider-specific auth object (e.g., JWT payload)
279
- }
280
- ```
291
+ #### `AuthProvider`
281
292
 
282
- ## Templates
293
+ React provider that bridges auth state to Agentuity context.
283
294
 
284
- Get started quickly with the Clerk template:
295
+ ```tsx
296
+ import { AuthProvider } from '@agentuity/auth/react';
285
297
 
286
- ```bash
287
- bunx agentuity create my-app --template clerk
288
- cd my-app
289
- cp .env.example .env
290
- # Add your Clerk keys to .env
291
- bun dev
298
+ <AuthProvider authClient={authClient} refreshInterval={60000}>
299
+ {children}
300
+ </AuthProvider>;
292
301
  ```
293
302
 
294
- ## Security Best Practices
295
-
296
- 1. **Never log tokens** - Avoid logging `authHeader` or JWT tokens
297
- 2. **Use HTTPS in production** - Always use TLS for production deployments
298
- 3. **Validate on every request** - Middleware validates tokens on each request
299
- 4. **Keep secrets secret** - Never commit `.env` files or expose `CLERK_SECRET_KEY`
300
- 5. **Use environment variables** - Store all keys in environment variables, not code
303
+ #### `useAuth()`
301
304
 
302
- ## Troubleshooting
305
+ Hook for full auth context. Import from `@agentuity/auth/react`.
303
306
 
304
- ### "Unauthorized" errors when signed in
307
+ **Returns:**
305
308
 
306
- **Check:**
309
+ - `user: AuthUser | null`
310
+ - `isPending: boolean`
311
+ - `error: Error | null`
312
+ - `isAuthenticated: boolean`
313
+ - `authClient: AuthClient`
307
314
 
308
- 1. Authorization header is present in request (browser DevTools → Network tab)
309
- 2. `CLERK_SECRET_KEY` is set in server environment
310
- 3. Token is being fetched (check console for "Failed to get Clerk token")
315
+ ### Schema
311
316
 
312
- **Debug:**
317
+ Import from `@agentuity/auth/schema`:
313
318
 
314
- ```tsx
315
- const { authHeader, authLoading, isAuthenticated } = useAuth();
316
- console.log({ authHeader, authLoading, isAuthenticated });
319
+ ```typescript
320
+ import { user, session, organization, apikey, authSchema } from '@agentuity/auth/schema';
317
321
  ```
318
322
 
319
- ### "Clerk secret key is required" error
323
+ **Tables:**
320
324
 
321
- Set `CLERK_SECRET_KEY` in your `.env` file:
325
+ - `user` - User accounts
326
+ - `session` - Active sessions
327
+ - `account` - OAuth/credential accounts
328
+ - `verification` - Email verification tokens
329
+ - `organization` - Organizations
330
+ - `member` - Organization memberships
331
+ - `invitation` - Pending invitations
332
+ - `jwks` - JWT signing keys
333
+ - `apikey` - API keys
322
334
 
323
- ```env
324
- CLERK_SECRET_KEY=sk_test_...
335
+ **Combined:**
336
+
337
+ - `authSchema` - All tables and relations for easy spreading
338
+
339
+ ### Types
340
+
341
+ ```typescript
342
+ import type {
343
+ AuthUser,
344
+ AuthSession,
345
+ AuthContext,
346
+ AuthOrgContext,
347
+ AuthApiKeyContext,
348
+ AuthMethod,
349
+ AuthInterface,
350
+ } from '@agentuity/auth';
325
351
  ```
326
352
 
327
- ### Token not being sent in requests
353
+ ## CLI Commands
328
354
 
329
- Ensure `AgentuityClerk` is a **child** of `AgentuityProvider`:
355
+ ```bash
356
+ # Initialize auth in a project
357
+ agentuity project auth init
330
358
 
331
- ```tsx
332
- // CORRECT
333
- <AgentuityProvider>
334
- <AgentuityClerk useAuth={useAuth}>
335
- <App />
336
- </AgentuityClerk>
337
- </AgentuityProvider>
338
-
339
- // ❌ WRONG
340
- <AgentuityClerk useAuth={useAuth}>
341
- <AgentuityProvider>
342
- <App />
343
- </AgentuityProvider>
344
- </AgentuityClerk>
359
+ # Run database migrations
360
+ agentuity project auth setup
361
+
362
+ # Generate Drizzle schema
363
+ agentuity project auth generate
364
+
365
+ # Generate a secure secret
366
+ agentuity project auth secret
345
367
  ```
346
368
 
347
- ## Examples
369
+ ## Security Best Practices
370
+
371
+ 1. **Use HTTPS in production** - Always use TLS for deployments
372
+ 2. **Keep secrets secret** - Never commit `.env` files or expose `AGENTUITY_AUTH_SECRET`
373
+ 3. **Rotate secrets periodically** - Rotate `AGENTUITY_AUTH_SECRET` on a regular schedule
374
+ 4. **Control OTEL PII** - Use `otelSpans: { email: false }` to exclude sensitive data from telemetry
375
+ 5. **Validate permissions** - Always check `hasPermission()` for API key routes
348
376
 
349
- See the [Clerk template](../../templates/clerk/) for a complete working example with:
377
+ ## Templates
350
378
 
351
- - Sign-in/out UI
352
- - Protected routes
353
- - Public routes
354
- - Conditional rendering based on auth state
379
+ Get started quickly:
355
380
 
356
- ## Contributing
381
+ ```bash
382
+ bunx agentuity create my-app --template agentuity-auth
383
+ ```
357
384
 
358
- This package follows the [Agentuity SDK contributing guidelines](../../AGENTS.md).
385
+ ## Third-Party Providers
359
386
 
360
- To add a new provider:
387
+ Agentuity Auth is the recommended solution. For Clerk, Auth0, or other providers, see:
361
388
 
362
- 1. Create `src/<provider>/` directory
363
- 2. Implement `client.tsx` and `server.ts`
364
- 3. Export from `src/<provider>/index.ts`
365
- 4. Add export path to `package.json`
366
- 5. Add peer dependencies
367
- 6. Write tests in `test/<provider>-*.test.ts`
389
+ - [Clerk Integration Guide](../../docs/recipes/clerk.md)
390
+ - [Auth0 Integration Guide](../../docs/recipes/auth0.md)
368
391
 
369
392
  ## License
370
393