@glinr/theauth 0.4.2
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/LICENSE +21 -0
- package/README.md +202 -0
- package/dist/a2a/index.d.ts +2341 -0
- package/dist/a2a/index.js +826 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/agent/index.d.ts +32 -0
- package/dist/agent/index.js +795 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/audit/index.d.ts +24 -0
- package/dist/audit/index.js +641 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/auth/index.d.ts +3466 -0
- package/dist/auth/index.js +16139 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/crypto/index.d.ts +55 -0
- package/dist/crypto/index.js +186 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/index.d.ts +1711 -0
- package/dist/index.js +23160 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +274 -0
- package/dist/mcp/index.js +1262 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/permission/index.d.ts +89 -0
- package/dist/permission/index.js +801 -0
- package/dist/permission/index.js.map +1 -0
- package/dist/redirect/index.d.ts +118 -0
- package/dist/redirect/index.js +292 -0
- package/dist/redirect/index.js.map +1 -0
- package/dist/standards/index.d.ts +139 -0
- package/dist/standards/index.js +72 -0
- package/dist/standards/index.js.map +1 -0
- package/dist/types-BiUe9e8u.d.ts +426 -0
- package/dist/types-D1sBnWrs.d.ts +9636 -0
- package/dist/types-RJPOU4un.d.ts +9636 -0
- package/dist/vc/index.d.ts +989 -0
- package/dist/vc/index.js +692 -0
- package/dist/vc/index.js.map +1 -0
- package/package.json +139 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { M as McpAuthContext, R as Result, a as McpAuthorizeResult, A as ApproveConsentParams, b as McpServerMetadata, c as McpProtectedResourceMetadata, d as McpClientRegistrationResponse, e as McpSession, f as McpConfig, g as McpAuthModule, h as McpTokenResponse } from '../types-BiUe9e8u.js';
|
|
2
|
+
export { K as KavachError, i as McpAccessToken, j as McpAuthorizationCode, k as McpAuthorizeRequest, l as McpAuthorizeRequestSchema, m as McpClient, n as McpClientRegistrationRequest, o as McpClientRegistrationSchema, p as McpTokenPayload, q as McpTokenRequest, r as McpTokenRequestParsed, s as McpTokenRequestSchema } from '../types-BiUe9e8u.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Handle the OAuth 2.1 authorization endpoint.
|
|
7
|
+
*
|
|
8
|
+
* GET /mcp/authorize
|
|
9
|
+
*
|
|
10
|
+
* Validates the request parameters, checks the client, enforces PKCE S256,
|
|
11
|
+
* validates Resource Indicators (RFC 8707), and issues an authorization code.
|
|
12
|
+
*
|
|
13
|
+
* The caller is responsible for authenticating the user before calling this
|
|
14
|
+
* function. The `ctx.resolveUserId(request)` hook must return a non-null
|
|
15
|
+
* user ID for the currently authenticated user.
|
|
16
|
+
*/
|
|
17
|
+
declare function handleAuthorize(ctx: McpAuthContext, request: Request): Promise<Result<McpAuthorizeResult>>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Issue an authorization code after a user has explicitly approved consent.
|
|
21
|
+
*
|
|
22
|
+
* Call this from your consent page handler after the user clicks "Allow".
|
|
23
|
+
* The params should match what was passed to the consent page as query params
|
|
24
|
+
* by `handleAuthorize`.
|
|
25
|
+
*/
|
|
26
|
+
declare function approveConsent(ctx: McpAuthContext, params: ApproveConsentParams): Promise<Result<{
|
|
27
|
+
redirectUri: string;
|
|
28
|
+
}>>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build OAuth 2.0 Authorization Server Metadata (RFC 8414).
|
|
32
|
+
*
|
|
33
|
+
* Returned at: GET /.well-known/oauth-authorization-server
|
|
34
|
+
*/
|
|
35
|
+
declare function getAuthorizationServerMetadata(ctx: McpAuthContext): McpServerMetadata;
|
|
36
|
+
/**
|
|
37
|
+
* Build Protected Resource Metadata (RFC 9728).
|
|
38
|
+
*
|
|
39
|
+
* Returned at: GET /.well-known/oauth-protected-resource
|
|
40
|
+
*
|
|
41
|
+
* An MCP resource server (tool server) publishes this so clients can
|
|
42
|
+
* discover which authorization server to use.
|
|
43
|
+
*/
|
|
44
|
+
declare function getProtectedResourceMetadata(ctx: McpAuthContext): McpProtectedResourceMetadata;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Dynamic Client Registration (RFC 7591).
|
|
48
|
+
*
|
|
49
|
+
* Endpoint logic for: POST /mcp/register
|
|
50
|
+
*
|
|
51
|
+
* Validates the registration request, generates client credentials,
|
|
52
|
+
* persists the client via the context store, and returns the
|
|
53
|
+
* RFC 7591-compliant registration response.
|
|
54
|
+
*/
|
|
55
|
+
declare function registerClient(ctx: McpAuthContext, body: unknown): Promise<Result<McpClientRegistrationResponse>>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validate the Bearer token on a request and assert that it carries all of
|
|
59
|
+
* the `requiredScopes`.
|
|
60
|
+
*
|
|
61
|
+
* Encapsulates the three-branch decision MCP resource servers need to make:
|
|
62
|
+
*
|
|
63
|
+
* 1. No token (or malformed token) → 401 Unauthorized
|
|
64
|
+
* 2. Valid token, missing scopes → 403 with step-up challenge
|
|
65
|
+
* 3. Valid token, all scopes present → session returned to the caller
|
|
66
|
+
*
|
|
67
|
+
* Usage:
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const check = await requireScopes(ctx, request, ['mcp:write']);
|
|
70
|
+
* if (!check.authorized) return check.response;
|
|
71
|
+
* // check.session is available here
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
declare function requireScopes(ctx: McpAuthContext, request: Request, requiredScopes: string[]): Promise<{
|
|
75
|
+
authorized: true;
|
|
76
|
+
session: McpSession;
|
|
77
|
+
} | {
|
|
78
|
+
authorized: false;
|
|
79
|
+
response: Response;
|
|
80
|
+
}>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Create the MCP authorization server module.
|
|
84
|
+
*
|
|
85
|
+
* This is the main factory that wires up all MCP OAuth 2.1 endpoints
|
|
86
|
+
* into a single module. The caller provides storage callbacks (how to
|
|
87
|
+
* persist clients, codes, and tokens) and user resolution (how to identify
|
|
88
|
+
* the currently authenticated user).
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const mcp = createMcpModule({
|
|
93
|
+
* config: {
|
|
94
|
+
* enabled: true,
|
|
95
|
+
* issuer: 'https://auth.example.com',
|
|
96
|
+
* baseUrl: 'https://auth.example.com/api/auth',
|
|
97
|
+
* signingSecret: process.env.MCP_SIGNING_SECRET,
|
|
98
|
+
* },
|
|
99
|
+
* storeClient: async (client) => { await db.insert(mcpClients).values(client); },
|
|
100
|
+
* findClient: async (id) => { return db.query.mcpClients.findFirst({ where: eq(mcpClients.clientId, id) }); },
|
|
101
|
+
* storeAuthorizationCode: async (code) => { await db.insert(mcpCodes).values(code); },
|
|
102
|
+
* consumeAuthorizationCode: async (code) => {
|
|
103
|
+
* const found = await db.query.mcpCodes.findFirst({ where: eq(mcpCodes.code, code) });
|
|
104
|
+
* if (found) await db.delete(mcpCodes).where(eq(mcpCodes.code, code));
|
|
105
|
+
* return found ?? null;
|
|
106
|
+
* },
|
|
107
|
+
* storeToken: async (token) => { await db.insert(mcpTokens).values(token); },
|
|
108
|
+
* findTokenByRefreshToken: async (rt) => { ... },
|
|
109
|
+
* revokeToken: async (at) => { ... },
|
|
110
|
+
* resolveUserId: async (request) => {
|
|
111
|
+
* const session = await getSession(request);
|
|
112
|
+
* return session?.userId ?? null;
|
|
113
|
+
* },
|
|
114
|
+
* });
|
|
115
|
+
*
|
|
116
|
+
* // Use in a framework adapter:
|
|
117
|
+
* app.get('/.well-known/oauth-authorization-server', () => mcp.getMetadata());
|
|
118
|
+
* app.get('/.well-known/oauth-protected-resource', () => mcp.getProtectedResourceMetadata());
|
|
119
|
+
* app.post('/mcp/register', (req) => mcp.registerClient(req.body));
|
|
120
|
+
* app.get('/mcp/authorize', (req) => mcp.authorize(req));
|
|
121
|
+
* app.post('/mcp/token', (req) => mcp.token(req));
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare function createMcpModule(params: {
|
|
125
|
+
config: McpConfig;
|
|
126
|
+
storeClient: McpAuthContext["storeClient"];
|
|
127
|
+
findClient: McpAuthContext["findClient"];
|
|
128
|
+
storeAuthorizationCode: McpAuthContext["storeAuthorizationCode"];
|
|
129
|
+
consumeAuthorizationCode: McpAuthContext["consumeAuthorizationCode"];
|
|
130
|
+
storeToken: McpAuthContext["storeToken"];
|
|
131
|
+
findTokenByRefreshToken: McpAuthContext["findTokenByRefreshToken"];
|
|
132
|
+
revokeToken: McpAuthContext["revokeToken"];
|
|
133
|
+
resolveUserId: McpAuthContext["resolveUserId"];
|
|
134
|
+
}): McpAuthModule;
|
|
135
|
+
/**
|
|
136
|
+
* Create HTTP Response helpers for framework adapters.
|
|
137
|
+
*
|
|
138
|
+
* These take Result types and produce standard Response objects
|
|
139
|
+
* with proper status codes, cache-control headers, and CORS.
|
|
140
|
+
*/
|
|
141
|
+
declare function createMcpResponseHelpers(ctx: McpAuthContext): {
|
|
142
|
+
/** Metadata endpoints: 200 with JSON */
|
|
143
|
+
metadataResponse: (data: unknown) => Response;
|
|
144
|
+
/** Registration: 201 with Cache-Control: no-store */
|
|
145
|
+
registrationResponse: (result: Result<unknown>) => Response;
|
|
146
|
+
/** Authorization: 302 redirect or error */
|
|
147
|
+
authorizeResponse: (result: Result<{
|
|
148
|
+
redirectUri: string;
|
|
149
|
+
}>) => Response;
|
|
150
|
+
/** Token: 200 with Cache-Control: no-store or error */
|
|
151
|
+
tokenResponse: (result: Result<unknown>) => Response;
|
|
152
|
+
/** Auth failure in JSON-RPC format for MCP resource servers */
|
|
153
|
+
unauthorizedResponse: (error: {
|
|
154
|
+
code: string;
|
|
155
|
+
message: string;
|
|
156
|
+
}) => Response;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build a step-up challenge response (403) indicating required scopes.
|
|
161
|
+
*
|
|
162
|
+
* When a token has valid scopes but lacks a specific scope needed for an
|
|
163
|
+
* operation, return this response so the client knows it must re-authorize
|
|
164
|
+
* with the additional scopes.
|
|
165
|
+
*
|
|
166
|
+
* Per RFC 6750 §3.1 the WWW-Authenticate header uses the
|
|
167
|
+
* `error="insufficient_scope"` challenge to signal the exact upgrade path.
|
|
168
|
+
*/
|
|
169
|
+
declare function buildStepUpResponse(ctx: McpAuthContext, options: {
|
|
170
|
+
currentScopes: string[];
|
|
171
|
+
requiredScopes: string[];
|
|
172
|
+
resource?: string;
|
|
173
|
+
}): Response;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Handle the OAuth 2.1 token endpoint.
|
|
177
|
+
*
|
|
178
|
+
* POST /mcp/token
|
|
179
|
+
*
|
|
180
|
+
* Supports two grant types:
|
|
181
|
+
* 1. authorization_code - Exchange auth code + PKCE verifier for tokens
|
|
182
|
+
* 2. refresh_token - Refresh an expired access token
|
|
183
|
+
*/
|
|
184
|
+
declare function handleTokenExchange(ctx: McpAuthContext, request: Request): Promise<Result<McpTokenResponse>>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generate a cryptographically secure random token string.
|
|
188
|
+
*
|
|
189
|
+
* Uses `crypto.getRandomValues()` (Web Crypto API compatible) to produce
|
|
190
|
+
* a URL-safe base64 string of the requested byte length.
|
|
191
|
+
*/
|
|
192
|
+
declare function generateSecureToken(byteLength: number): string;
|
|
193
|
+
/**
|
|
194
|
+
* Compute the S256 code challenge from a code verifier.
|
|
195
|
+
*
|
|
196
|
+
* S256: BASE64URL(SHA256(ASCII(code_verifier)))
|
|
197
|
+
*
|
|
198
|
+
* Uses Web Crypto (SubtleCrypto) for cross-runtime compatibility.
|
|
199
|
+
*/
|
|
200
|
+
declare function computeS256Challenge(codeVerifier: string): Promise<string>;
|
|
201
|
+
/**
|
|
202
|
+
* Verify a PKCE S256 code_verifier against a stored code_challenge.
|
|
203
|
+
*/
|
|
204
|
+
declare function verifyS256(codeVerifier: string, codeChallenge: string): Promise<boolean>;
|
|
205
|
+
/**
|
|
206
|
+
* Parse a URL search params or form body into a plain object.
|
|
207
|
+
*
|
|
208
|
+
* Handles both `application/x-www-form-urlencoded` and `application/json`
|
|
209
|
+
* content types, as required by OAuth 2.1 token endpoint.
|
|
210
|
+
*/
|
|
211
|
+
declare function parseRequestBody(request: Request): Promise<Record<string, string>>;
|
|
212
|
+
/**
|
|
213
|
+
* Extract client credentials from the Authorization header (Basic auth).
|
|
214
|
+
*
|
|
215
|
+
* Returns [client_id, client_secret] or null if not present.
|
|
216
|
+
*/
|
|
217
|
+
declare function extractBasicAuth(request: Request): [string, string] | null;
|
|
218
|
+
/**
|
|
219
|
+
* Extract a Bearer token from the Authorization header.
|
|
220
|
+
*/
|
|
221
|
+
declare function extractBearerToken(request: Request): string | null;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Validate an MCP access token (JWT).
|
|
225
|
+
*
|
|
226
|
+
* Performs:
|
|
227
|
+
* 1. JWT signature verification (HS256)
|
|
228
|
+
* 2. Expiry check
|
|
229
|
+
* 3. Issuer validation
|
|
230
|
+
* 4. Audience validation (token must be bound to the expected resource)
|
|
231
|
+
* 5. Scope validation (optional - checks all required scopes are present)
|
|
232
|
+
*
|
|
233
|
+
* Target: < 5ms with cached keys (per CLAUDE.md performance rule).
|
|
234
|
+
*/
|
|
235
|
+
declare function validateAccessToken(ctx: McpAuthContext, token: string, options?: {
|
|
236
|
+
requiredScopes?: string[];
|
|
237
|
+
expectedAudience?: string;
|
|
238
|
+
}): Promise<Result<McpSession>>;
|
|
239
|
+
/**
|
|
240
|
+
* MCP auth middleware.
|
|
241
|
+
*
|
|
242
|
+
* Extracts the Bearer token from the Authorization header, validates it,
|
|
243
|
+
* and returns the session. This is the primary entry point for protecting
|
|
244
|
+
* MCP resource server endpoints.
|
|
245
|
+
*
|
|
246
|
+
* Pattern inspired by better-auth's `withMcpAuth()`, adapted to TheAuth's
|
|
247
|
+
* functional Result-based API.
|
|
248
|
+
*
|
|
249
|
+
* Usage:
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const result = await withMcpAuth(ctx, request, { requiredScopes: ['read'] });
|
|
252
|
+
* if (!result.success) {
|
|
253
|
+
* return new Response(JSON.stringify(result.error), { status: 401 });
|
|
254
|
+
* }
|
|
255
|
+
* const session = result.data;
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
declare function withMcpAuth(ctx: McpAuthContext, request: Request, options?: {
|
|
259
|
+
requiredScopes?: string[];
|
|
260
|
+
expectedAudience?: string;
|
|
261
|
+
}): Promise<Result<McpSession>>;
|
|
262
|
+
/**
|
|
263
|
+
* Build a 401 Unauthorized response in the JSON-RPC format expected
|
|
264
|
+
* by MCP clients.
|
|
265
|
+
*
|
|
266
|
+
* Includes the WWW-Authenticate header pointing to the protected
|
|
267
|
+
* resource metadata document, as required by the MCP spec.
|
|
268
|
+
*/
|
|
269
|
+
declare function buildUnauthorizedResponse(ctx: McpAuthContext, error: {
|
|
270
|
+
code: string;
|
|
271
|
+
message: string;
|
|
272
|
+
}): Response;
|
|
273
|
+
|
|
274
|
+
export { ApproveConsentParams, McpAuthContext, McpAuthModule, McpAuthorizeResult, McpClientRegistrationResponse, McpConfig, McpProtectedResourceMetadata, McpServerMetadata, McpSession, McpTokenResponse, Result, approveConsent, buildStepUpResponse, buildUnauthorizedResponse, computeS256Challenge, createMcpModule, createMcpResponseHelpers, extractBasicAuth, extractBearerToken, generateSecureToken, getAuthorizationServerMetadata, getProtectedResourceMetadata, handleAuthorize, handleTokenExchange, parseRequestBody, registerClient, requireScopes, validateAccessToken, verifyS256, withMcpAuth };
|