@agentuity/auth 0.0.109 → 0.0.111
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.
- package/AGENTS.md +82 -28
- package/README.md +259 -236
- package/dist/agentuity/config.d.ts +2386 -0
- package/dist/agentuity/config.d.ts.map +1 -0
- package/dist/agentuity/config.js +220 -0
- package/dist/agentuity/config.js.map +1 -0
- package/dist/agentuity/plugins/api-key.d.ts +152 -0
- package/dist/agentuity/plugins/api-key.d.ts.map +1 -0
- package/dist/agentuity/plugins/api-key.js +21 -0
- package/dist/agentuity/plugins/api-key.js.map +1 -0
- package/dist/agentuity/plugins/index.d.ts +23 -0
- package/dist/agentuity/plugins/index.d.ts.map +1 -0
- package/dist/agentuity/plugins/index.js +10 -0
- package/dist/agentuity/plugins/index.js.map +1 -0
- package/dist/agentuity/plugins/jwt.d.ts +34 -0
- package/dist/agentuity/plugins/jwt.d.ts.map +1 -0
- package/dist/agentuity/plugins/jwt.js +11 -0
- package/dist/agentuity/plugins/jwt.js.map +1 -0
- package/dist/agentuity/plugins/organization.d.ts +355 -0
- package/dist/agentuity/plugins/organization.d.ts.map +1 -0
- package/dist/agentuity/plugins/organization.js +12 -0
- package/dist/agentuity/plugins/organization.js.map +1 -0
- package/dist/agentuity/react.d.ts +1375 -0
- package/dist/agentuity/react.d.ts.map +1 -0
- package/dist/agentuity/react.js +206 -0
- package/dist/agentuity/react.js.map +1 -0
- package/dist/agentuity/server.d.ts +220 -0
- package/dist/agentuity/server.d.ts.map +1 -0
- package/dist/agentuity/server.js +505 -0
- package/dist/agentuity/server.js.map +1 -0
- package/dist/agentuity/types.d.ts +172 -0
- package/dist/agentuity/types.d.ts.map +1 -0
- package/dist/agentuity/types.js +7 -0
- package/dist/agentuity/types.js.map +1 -0
- package/dist/index.d.ts +31 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -8
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +2922 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +223 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +14 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +15 -39
- package/src/agentuity/config.ts +401 -0
- package/src/agentuity/plugins/api-key.ts +158 -0
- package/src/agentuity/plugins/index.ts +35 -0
- package/src/agentuity/plugins/jwt.ts +30 -0
- package/src/agentuity/plugins/organization.ts +345 -0
- package/src/agentuity/react.tsx +328 -0
- package/src/agentuity/server.ts +734 -0
- package/src/agentuity/types.ts +201 -0
- package/src/index.ts +76 -8
- package/src/schema.ts +270 -0
- package/src/types.ts +14 -22
- package/test/agentuity/config.test.ts +621 -0
- package/test/agentuity/server.test.ts +537 -0
- package/test/schema.test.ts +147 -0
- package/tsconfig.json +3 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/auth0/client.d.ts +0 -44
- package/dist/auth0/client.d.ts.map +0 -1
- package/dist/auth0/client.js +0 -79
- package/dist/auth0/client.js.map +0 -1
- package/dist/auth0/index.d.ts +0 -35
- package/dist/auth0/index.d.ts.map +0 -1
- package/dist/auth0/index.js +0 -38
- package/dist/auth0/index.js.map +0 -1
- package/dist/auth0/server.d.ts +0 -91
- package/dist/auth0/server.d.ts.map +0 -1
- package/dist/auth0/server.js +0 -237
- package/dist/auth0/server.js.map +0 -1
- package/dist/clerk/client.d.ts +0 -42
- package/dist/clerk/client.d.ts.map +0 -1
- package/dist/clerk/client.js +0 -65
- package/dist/clerk/client.js.map +0 -1
- package/dist/clerk/index.d.ts +0 -37
- package/dist/clerk/index.d.ts.map +0 -1
- package/dist/clerk/index.js +0 -35
- package/dist/clerk/index.js.map +0 -1
- package/dist/clerk/server.d.ts +0 -55
- package/dist/clerk/server.d.ts.map +0 -1
- package/dist/clerk/server.js +0 -111
- package/dist/clerk/server.js.map +0 -1
- package/docs/adding-providers.md +0 -261
- package/src/auth0/client.tsx +0 -109
- package/src/auth0/index.ts +0 -40
- package/src/auth0/server.ts +0 -378
- package/src/clerk/client.tsx +0 -86
- package/src/clerk/index.ts +0 -37
- package/src/clerk/server.ts +0 -168
- package/test/clerk-client.test.tsx +0 -21
- package/test/clerk-server.test.ts +0 -51
package/README.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# @agentuity/auth
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
First-class authentication for Agentuity projects, powered by [BetterAuth](https://better-auth.com).
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- ✅ **Zero Configuration**:
|
|
8
|
-
- ✅ **
|
|
9
|
-
- ✅ **
|
|
10
|
-
- ✅ **
|
|
11
|
-
- ✅ **
|
|
12
|
-
- ✅ **
|
|
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
|
-
##
|
|
21
|
+
## Quick Start
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
- WorkOS - Coming soon
|
|
24
|
-
- Auth0 - Coming soon
|
|
25
|
-
- Better Auth - Coming soon
|
|
23
|
+
### 1. Setup with CLI
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
```bash
|
|
26
|
+
agentuity project auth init
|
|
27
|
+
```
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
This will:
|
|
30
30
|
|
|
31
|
-
|
|
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
|
-
|
|
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
|
-
|
|
45
|
+
### 3. Server Setup (Hono)
|
|
38
46
|
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
import
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
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 {
|
|
63
|
+
import { auth, authMiddleware } from '../auth';
|
|
64
|
+
import { mountAuthRoutes } from '@agentuity/auth';
|
|
65
|
+
|
|
66
|
+
const api = createRouter();
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
// Mount auth routes (sign-in, sign-up, sign-out, session, etc.)
|
|
69
|
+
api.on(['GET', 'POST'], '/api/auth/*', mountAuthRoutes(auth));
|
|
67
70
|
|
|
68
|
-
//
|
|
69
|
-
|
|
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
|
|
79
|
+
export default api;
|
|
79
80
|
```
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Create a `.env` file:
|
|
82
|
+
### 4. Client Setup (React)
|
|
84
83
|
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
```tsx
|
|
85
|
+
// src/web/auth-client.ts
|
|
86
|
+
import { createAuthClient } from '@agentuity/auth/react';
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
export const authClient = createAuthClient();
|
|
89
|
+
export const { signIn, signUp, signOut, useSession } = authClient;
|
|
91
90
|
```
|
|
92
91
|
|
|
93
|
-
|
|
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
|
-
|
|
98
|
+
const authClient = createAuthClient();
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
<AgentuityProvider>
|
|
101
|
+
<AuthProvider authClient={authClient}>
|
|
102
|
+
<App />
|
|
103
|
+
</AuthProvider>
|
|
104
|
+
</AgentuityProvider>;
|
|
105
|
+
```
|
|
98
106
|
|
|
99
|
-
|
|
107
|
+
### 5. Environment Variables
|
|
100
108
|
|
|
101
|
-
```
|
|
102
|
-
|
|
109
|
+
```env
|
|
110
|
+
# Database connection
|
|
111
|
+
DATABASE_URL=postgresql://user:pass@host:5432/dbname
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
113
|
+
# Auth secret (generate with: openssl rand -hex 32)
|
|
114
|
+
AGENTUITY_AUTH_SECRET=your-secret-here
|
|
115
|
+
```
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
return <div>Loading...</div>;
|
|
110
|
-
}
|
|
117
|
+
## Usage
|
|
111
118
|
|
|
112
|
-
|
|
113
|
-
return <div>Please sign in</div>;
|
|
114
|
-
}
|
|
119
|
+
### Agent Access
|
|
115
120
|
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
```
|
|
121
|
+
Auth is native on AgentContext - no wrappers needed:
|
|
119
122
|
|
|
120
|
-
|
|
123
|
+
```typescript
|
|
124
|
+
import { createAgent } from '@agentuity/runtime';
|
|
121
125
|
|
|
122
|
-
|
|
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
|
-
|
|
125
|
-
|
|
133
|
+
const user = await ctx.auth.getUser();
|
|
134
|
+
const org = await ctx.auth.getOrg();
|
|
126
135
|
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
146
|
+
### Hono Routes
|
|
135
147
|
|
|
136
148
|
```typescript
|
|
137
|
-
|
|
138
|
-
router.use('/api/*', createMiddleware());
|
|
149
|
+
import { createSessionMiddleware, createApiKeyMiddleware } from '@agentuity/auth';
|
|
139
150
|
|
|
140
|
-
|
|
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
|
-
|
|
169
|
+
### React Components
|
|
147
170
|
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
```tsx
|
|
172
|
+
import { useAuth } from '@agentuity/react';
|
|
173
|
+
import { useAuth } from '@agentuity/auth/react';
|
|
151
174
|
|
|
152
|
-
|
|
153
|
-
|
|
175
|
+
function Profile() {
|
|
176
|
+
// Basic auth state from @agentuity/react
|
|
177
|
+
const { isAuthenticated, authLoading } = useAuth();
|
|
154
178
|
|
|
155
|
-
//
|
|
156
|
-
const
|
|
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
|
-
|
|
161
|
-
|
|
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
|
|
165
|
-
}
|
|
185
|
+
return <div>Welcome, {user?.name}!</div>;
|
|
186
|
+
}
|
|
166
187
|
```
|
|
167
188
|
|
|
168
|
-
|
|
189
|
+
## Database Configuration
|
|
190
|
+
|
|
191
|
+
### Option A: Connection String (Simplest)
|
|
169
192
|
|
|
170
193
|
```typescript
|
|
171
|
-
import {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
201
|
+
### Option B: Bring Your Own Drizzle
|
|
184
202
|
|
|
185
|
-
|
|
203
|
+
Merge auth schema with your app schema:
|
|
186
204
|
|
|
187
|
-
|
|
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
|
-
|
|
211
|
+
const schema = { ...authSchema, ...myAppSchema };
|
|
212
|
+
const db = drizzle(process.env.DATABASE_URL!, { schema });
|
|
190
213
|
|
|
191
|
-
|
|
214
|
+
export const auth = createAuth({
|
|
215
|
+
database: drizzleAdapter(db, { provider: 'pg', schema: authSchema }),
|
|
216
|
+
});
|
|
217
|
+
```
|
|
192
218
|
|
|
193
|
-
|
|
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
|
-
|
|
221
|
+
Use any BetterAuth-compatible adapter:
|
|
198
222
|
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
231
|
+
## API Reference
|
|
232
|
+
|
|
233
|
+
### Server
|
|
206
234
|
|
|
207
|
-
#### `
|
|
235
|
+
#### `createAuth(options)`
|
|
208
236
|
|
|
209
|
-
Creates
|
|
237
|
+
Creates an auth instance with Agentuity defaults.
|
|
210
238
|
|
|
211
239
|
**Options:**
|
|
212
240
|
|
|
213
|
-
- `
|
|
214
|
-
- `
|
|
215
|
-
- `
|
|
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
|
-
|
|
250
|
+
#### `createSessionMiddleware(auth, options?)`
|
|
218
251
|
|
|
219
|
-
|
|
252
|
+
Hono middleware for session-based auth.
|
|
220
253
|
|
|
221
|
-
|
|
222
|
-
- Returns 401 if token is invalid
|
|
223
|
-
- Sets `c.var.auth` with authenticated user context
|
|
254
|
+
**Options:**
|
|
224
255
|
|
|
225
|
-
|
|
256
|
+
- `optional?: boolean` - If true, don't 401 on missing auth
|
|
257
|
+
- `otelSpans?: { email?: boolean, orgName?: boolean }` - Control PII in spans
|
|
226
258
|
|
|
227
|
-
#### `
|
|
259
|
+
#### `createApiKeyMiddleware(auth, options?)`
|
|
228
260
|
|
|
229
|
-
|
|
261
|
+
Hono middleware for API key auth.
|
|
230
262
|
|
|
231
|
-
**
|
|
263
|
+
**Options:**
|
|
232
264
|
|
|
233
|
-
|
|
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
|
-
#### `
|
|
268
|
+
#### `mountAuthRoutes(auth, options?)`
|
|
244
269
|
|
|
245
|
-
|
|
270
|
+
Handler for BetterAuth routes with cookie merging.
|
|
246
271
|
|
|
247
|
-
**
|
|
272
|
+
**Options:**
|
|
248
273
|
|
|
249
|
-
|
|
250
|
-
{
|
|
251
|
-
baseUrl: string;
|
|
252
|
-
}
|
|
253
|
-
```
|
|
274
|
+
- `allowList?: string[]` - Headers to forward from auth responses
|
|
254
275
|
|
|
255
|
-
###
|
|
276
|
+
### Client
|
|
256
277
|
|
|
257
|
-
#### `
|
|
278
|
+
#### `createAuthClient(options?)`
|
|
258
279
|
|
|
259
|
-
|
|
280
|
+
Import from `@agentuity/auth/react`.
|
|
260
281
|
|
|
261
|
-
|
|
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
|
-
|
|
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
|
-
|
|
289
|
+
**Returns:** BetterAuth client with `signIn`, `signUp`, `signOut`, `useSession`, etc.
|
|
273
290
|
|
|
274
|
-
|
|
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
|
-
|
|
293
|
+
React provider that bridges auth state to Agentuity context.
|
|
283
294
|
|
|
284
|
-
|
|
295
|
+
```tsx
|
|
296
|
+
import { AuthProvider } from '@agentuity/auth/react';
|
|
285
297
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
|
|
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
|
-
|
|
305
|
+
Hook for full auth context. Import from `@agentuity/auth/react`.
|
|
303
306
|
|
|
304
|
-
|
|
307
|
+
**Returns:**
|
|
305
308
|
|
|
306
|
-
|
|
309
|
+
- `user: AuthUser | null`
|
|
310
|
+
- `isPending: boolean`
|
|
311
|
+
- `error: Error | null`
|
|
312
|
+
- `isAuthenticated: boolean`
|
|
313
|
+
- `authClient: AuthClient`
|
|
307
314
|
|
|
308
|
-
|
|
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
|
-
|
|
317
|
+
Import from `@agentuity/auth/schema`:
|
|
313
318
|
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
console.log({ authHeader, authLoading, isAuthenticated });
|
|
319
|
+
```typescript
|
|
320
|
+
import { user, session, organization, apikey, authSchema } from '@agentuity/auth/schema';
|
|
317
321
|
```
|
|
318
322
|
|
|
319
|
-
|
|
323
|
+
**Tables:**
|
|
320
324
|
|
|
321
|
-
|
|
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
|
-
|
|
324
|
-
|
|
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
|
-
|
|
353
|
+
## CLI Commands
|
|
328
354
|
|
|
329
|
-
|
|
355
|
+
```bash
|
|
356
|
+
# Initialize auth in a project
|
|
357
|
+
agentuity project auth init
|
|
330
358
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
377
|
+
## Templates
|
|
350
378
|
|
|
351
|
-
|
|
352
|
-
- Protected routes
|
|
353
|
-
- Public routes
|
|
354
|
-
- Conditional rendering based on auth state
|
|
379
|
+
Get started quickly:
|
|
355
380
|
|
|
356
|
-
|
|
381
|
+
```bash
|
|
382
|
+
bunx agentuity create my-app --template agentuity-auth
|
|
383
|
+
```
|
|
357
384
|
|
|
358
|
-
|
|
385
|
+
## Third-Party Providers
|
|
359
386
|
|
|
360
|
-
|
|
387
|
+
Agentuity Auth is the recommended solution. For Clerk, Auth0, or other providers, see:
|
|
361
388
|
|
|
362
|
-
|
|
363
|
-
|
|
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
|
|