@mastra/auth-okta 0.0.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @mastra/auth-okta
2
+
3
+ ## 0.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Initial release with Okta RBAC and Auth integration
package/README.md ADDED
@@ -0,0 +1,204 @@
1
+ # @mastra/auth-okta
2
+
3
+ Okta integration for Mastra, providing RBAC based on Okta groups and optional JWT authentication.
4
+
5
+ ## Features
6
+
7
+ - 🔐 **RBAC Provider** - Map Okta groups to Mastra permissions
8
+ - 🔑 **Auth Provider** - JWT token verification using Okta's JWKS
9
+ - 🔄 **Cross-provider support** - Use with Auth0, Clerk, or any other auth provider
10
+ - ⚡ **Caching** - LRU cache for group lookups to minimize API calls
11
+ - 🛡️ **Type-safe** - Full TypeScript support with strict types
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @mastra/auth-okta
17
+ # or
18
+ yarn add @mastra/auth-okta
19
+ # or
20
+ pnpm add @mastra/auth-okta
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Auth0 + Okta RBAC (Recommended)
26
+
27
+ Use Auth0 for authentication and Okta for role-based access control:
28
+
29
+ ```typescript
30
+ import { Mastra } from '@mastra/core/mastra';
31
+ import { MastraAuthAuth0 } from '@mastra/auth-auth0';
32
+ import { MastraRBACOkta } from '@mastra/auth-okta';
33
+
34
+ const mastra = new Mastra({
35
+ server: {
36
+ auth: new MastraAuthAuth0(),
37
+ rbac: new MastraRBACOkta({
38
+ // Extract Okta user ID from Auth0 user metadata
39
+ getUserId: user => user.metadata?.oktaUserId || user.email,
40
+ roleMapping: {
41
+ Engineering: ['agents:*', 'workflows:*'],
42
+ Product: ['agents:read', 'workflows:read'],
43
+ Admin: ['*'],
44
+ _default: [], // Users with unmapped groups get no permissions
45
+ },
46
+ }),
47
+ },
48
+ });
49
+ ```
50
+
51
+ ### Full Okta Setup
52
+
53
+ For complete Okta authentication + RBAC:
54
+
55
+ ```typescript
56
+ import { Mastra } from '@mastra/core/mastra';
57
+ import { MastraAuthOkta, MastraRBACOkta } from '@mastra/auth-okta';
58
+
59
+ const mastra = new Mastra({
60
+ server: {
61
+ auth: new MastraAuthOkta(),
62
+ rbac: new MastraRBACOkta({
63
+ roleMapping: {
64
+ Admin: ['*'],
65
+ Member: ['agents:read', 'workflows:*'],
66
+ _default: [],
67
+ },
68
+ }),
69
+ },
70
+ });
71
+ ```
72
+
73
+ ## Configuration
74
+
75
+ ### Environment Variables
76
+
77
+ | Variable | Description | Required |
78
+ | ---------------------- | ----------------------------------------- | -------------------------------------------------- |
79
+ | `OKTA_DOMAIN` | Okta domain (e.g., `dev-123456.okta.com`) | Yes |
80
+ | `OKTA_CLIENT_ID` | OAuth client ID | For auth only |
81
+ | `OKTA_CLIENT_SECRET` | OAuth client secret | For auth only |
82
+ | `OKTA_REDIRECT_URI` | OAuth redirect URI for SSO callback | For auth only |
83
+ | `OKTA_ISSUER` | Token issuer URL | No (defaults to `https://{domain}/oauth2/default`) |
84
+ | `OKTA_COOKIE_PASSWORD` | Session encryption key (min 32 chars) | No (auto-generated if omitted; set for production) |
85
+ | `OKTA_API_TOKEN` | API token for management SDK | For RBAC only |
86
+
87
+ ### MastraAuthOkta Options
88
+
89
+ ```typescript
90
+ interface MastraAuthOktaOptions {
91
+ domain?: string; // Okta domain (or OKTA_DOMAIN env var)
92
+ clientId?: string; // OAuth client ID (or OKTA_CLIENT_ID)
93
+ clientSecret?: string; // OAuth client secret (or OKTA_CLIENT_SECRET)
94
+ redirectUri?: string; // SSO callback URI (or OKTA_REDIRECT_URI)
95
+ issuer?: string; // Token issuer URL (or OKTA_ISSUER)
96
+ scopes?: string[]; // OAuth scopes (default: ['openid', 'profile', 'email', 'groups'])
97
+ name?: string; // Provider name (default: 'okta')
98
+ session?: {
99
+ cookieName?: string; // Cookie name (default: 'okta_session')
100
+ cookieMaxAge?: number; // Cookie max age in seconds (default: 86400)
101
+ cookiePassword?: string; // Encryption key, min 32 chars (or OKTA_COOKIE_PASSWORD)
102
+ secureCookies?: boolean; // Set Secure flag (default: auto-detect from NODE_ENV)
103
+ };
104
+ }
105
+ ```
106
+
107
+ ### MastraRBACOkta Options
108
+
109
+ ```typescript
110
+ interface MastraRBACOktaOptions {
111
+ domain?: string; // Okta domain
112
+ apiToken?: string; // API token for group fetching
113
+
114
+ // Map Okta groups to Mastra permissions
115
+ roleMapping: {
116
+ [groupName: string]: string[]; // e.g., 'Admin': ['*']
117
+ };
118
+
119
+ // Extract Okta user ID from any user object (for cross-provider use)
120
+ getUserId?: (user: unknown) => string | undefined;
121
+
122
+ // Cache configuration
123
+ cache?: {
124
+ maxSize?: number; // Max users to cache (default: 1000)
125
+ ttlMs?: number; // Cache TTL in ms (default: 60000)
126
+ };
127
+ }
128
+ ```
129
+
130
+ ## Role Mapping
131
+
132
+ The `roleMapping` configuration maps Okta group names to Mastra permission patterns:
133
+
134
+ ```typescript
135
+ roleMapping: {
136
+ // Users in 'Engineering' group get full access to agents and workflows
137
+ 'Engineering': ['agents:*', 'workflows:*'],
138
+
139
+ // Users in 'Product' group get read-only access
140
+ 'Product': ['agents:read', 'workflows:read'],
141
+
142
+ // Users in 'Admin' group get full access to everything
143
+ 'Admin': ['*'],
144
+
145
+ // Special '_default' key: permissions for users with unmapped groups
146
+ '_default': [],
147
+ }
148
+ ```
149
+
150
+ ### Permission Patterns
151
+
152
+ - `*` - Full access to all resources
153
+ - `agents:*` - Full access to agents
154
+ - `agents:read` - Read-only access to agents
155
+ - `workflows:create` - Create workflows only
156
+
157
+ ## Cross-Provider Support
158
+
159
+ When using a different auth provider (Auth0, Clerk, etc.) with Okta RBAC, you need to link users between systems. The `getUserId` option allows you to extract the Okta user ID from any user object:
160
+
161
+ ```typescript
162
+ new MastraRBACOkta({
163
+ // Extract Okta user ID from Auth0 user's app_metadata
164
+ getUserId: (user) => {
165
+ return user.metadata?.oktaUserId || user.email;
166
+ },
167
+ roleMapping: { ... },
168
+ })
169
+ ```
170
+
171
+ ### Linking Users
172
+
173
+ To link Auth0 users to Okta:
174
+
175
+ 1. Store the Okta user ID in Auth0's `app_metadata`
176
+ 2. Configure `getUserId` to extract it
177
+ 3. Mastra will use this ID to fetch groups from Okta
178
+
179
+ ## API
180
+
181
+ ### MastraRBACOkta
182
+
183
+ | Method | Description |
184
+ | -------------------------------------- | ------------------------------------ |
185
+ | `getRoles(user)` | Get user's Okta groups |
186
+ | `hasRole(user, role)` | Check if user has a specific group |
187
+ | `getPermissions(user)` | Get resolved permissions from groups |
188
+ | `hasPermission(user, permission)` | Check if user has a permission |
189
+ | `hasAllPermissions(user, permissions)` | Check if user has all permissions |
190
+ | `hasAnyPermission(user, permissions)` | Check if user has any permission |
191
+
192
+ ### MastraAuthOkta
193
+
194
+ | Method | Description |
195
+ | ----------------------------------- | --------------------------- |
196
+ | `authenticateToken(token, request)` | Verify JWT and return user |
197
+ | `authorizeUser(user, request)` | Check if user is authorized |
198
+
199
+ ## Requirements
200
+
201
+ - Node.js 22.13.0 or later
202
+ - Okta account with:
203
+ - OAuth application (for authentication)
204
+ - API token (for RBAC group fetching)
@@ -0,0 +1,120 @@
1
+ /**
2
+ * MastraAuthOkta - Okta authentication provider for Mastra with SSO support.
3
+ *
4
+ * Supports OAuth 2.0 / OIDC login flow with client_secret and session management.
5
+ */
6
+ import type { ISSOProvider, ISessionProvider, IUserProvider, Session, SSOCallbackResult, SSOLoginConfig } from '@mastra/core/auth';
7
+ import { MastraAuthProvider } from '@mastra/core/server';
8
+ import type { HonoRequest } from 'hono';
9
+ import type { OktaUser, MastraAuthOktaOptions } from './types.js';
10
+ /**
11
+ * Mastra authentication provider for Okta with SSO support.
12
+ *
13
+ * Implements OAuth 2.0 / OIDC login flow with encrypted session cookies.
14
+ *
15
+ * @example Basic usage with SSO
16
+ * ```typescript
17
+ * import { MastraAuthOkta } from '@mastra/auth-okta';
18
+ *
19
+ * const auth = new MastraAuthOkta({
20
+ * domain: 'dev-123456.okta.com',
21
+ * clientId: 'your-client-id',
22
+ * clientSecret: 'your-client-secret',
23
+ * redirectUri: 'http://localhost:4111/api/auth/callback',
24
+ * });
25
+ * ```
26
+ */
27
+ export declare class MastraAuthOkta extends MastraAuthProvider<OktaUser> implements ISSOProvider<OktaUser>, ISessionProvider<Session>, IUserProvider<OktaUser> {
28
+ protected domain: string;
29
+ protected clientId: string;
30
+ protected clientSecret: string;
31
+ protected issuer: string;
32
+ protected redirectUri: string;
33
+ protected scopes: string[];
34
+ protected cookieName: string;
35
+ protected cookieMaxAge: number;
36
+ protected cookiePassword: string;
37
+ protected secureCookies: boolean;
38
+ protected apiToken?: string;
39
+ private jwks;
40
+ constructor(options?: MastraAuthOktaOptions);
41
+ /**
42
+ * Authenticate a token from the request.
43
+ * First tries to read from session cookie, then falls back to Authorization header.
44
+ */
45
+ authenticateToken(token: string, request: HonoRequest | Request): Promise<OktaUser | null>;
46
+ /**
47
+ * Authorize a user.
48
+ */
49
+ authorizeUser(user: OktaUser, _request: HonoRequest): boolean;
50
+ /**
51
+ * Get the current user from the request session.
52
+ */
53
+ getCurrentUser(request: Request): Promise<OktaUser | null>;
54
+ /**
55
+ * Get a user by ID via the Okta Users API.
56
+ * Requires an API token (set OKTA_API_TOKEN or pass apiToken in options).
57
+ * Returns null if no API token is configured or user is not found.
58
+ */
59
+ getUser(userId: string): Promise<OktaUser | null>;
60
+ /**
61
+ * Get user from session cookie.
62
+ */
63
+ private getUserFromSession;
64
+ /**
65
+ * Extract the raw ID token from the encrypted session cookie.
66
+ * Used to provide id_token_hint for Okta logout.
67
+ */
68
+ private getIdTokenFromSession;
69
+ /**
70
+ * Get the URL to redirect users to for Okta login.
71
+ * Uses client_secret authentication (no PKCE) since this is a confidential client.
72
+ */
73
+ getLoginUrl(redirectUri: string, state: string): string;
74
+ /**
75
+ * Handle the OAuth callback from Okta.
76
+ * Note: The server passes only the stateId (UUID part), not the full state.
77
+ */
78
+ handleCallback(code: string, stateId: string): Promise<SSOCallbackResult<OktaUser>>;
79
+ /**
80
+ * Get the URL to redirect users to for logout.
81
+ * Includes id_token_hint from session when available (required by Okta).
82
+ */
83
+ getLogoutUrl(redirectUri: string, request?: Request): Promise<string | null>;
84
+ /**
85
+ * Get cookies to set during login.
86
+ */
87
+ getLoginCookies(_state: string): string[];
88
+ /**
89
+ * Get the configuration for rendering the login button.
90
+ */
91
+ getLoginButtonConfig(): SSOLoginConfig;
92
+ createSession(userId: string, metadata?: Record<string, unknown>): Promise<Session>;
93
+ validateSession(_sessionId: string): Promise<Session | null>;
94
+ destroySession(_sessionId: string): Promise<void>;
95
+ refreshSession(_sessionId: string): Promise<Session | null>;
96
+ getSessionIdFromRequest(_request: Request): string | null;
97
+ getSessionHeaders(_session: Session): Record<string, string>;
98
+ getClearSessionHeaders(): Record<string, string>;
99
+ /**
100
+ * Build consistent cookie attribute string for set/clear operations.
101
+ */
102
+ private cookieFlags;
103
+ /**
104
+ * Get the Okta domain.
105
+ */
106
+ getDomain(): string;
107
+ /**
108
+ * Get the configured client ID.
109
+ */
110
+ getClientId(): string;
111
+ /**
112
+ * Get the configured redirect URI.
113
+ */
114
+ getRedirectUri(): string;
115
+ /**
116
+ * Get the issuer URL.
117
+ */
118
+ getIssuer(): string;
119
+ }
120
+ //# sourceMappingURL=auth-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-provider.d.ts","sourceRoot":"","sources":["../src/auth-provider.ts"],"names":[],"mappings":"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"}