mcp-authz 0.1.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/LICENSE +21 -0
- package/README.md +411 -0
- package/dist/index.d.ts +386 -0
- package/dist/index.js +731 -0
- package/dist/node.d.ts +16 -0
- package/dist/node.js +46 -0
- package/dist/policy-CnQj53Hq.d.ts +144 -0
- package/dist/policy.d.ts +2 -0
- package/dist/policy.js +203 -0
- package/package.json +80 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import { a as Policy, c as Rule, d as definePolicy, f as reconcile, h as Identity, i as PermissionOf, l as createPrincipal, m as DenialReason, n as Match, o as PolicySpec, p as AccessDeniedError, r as PermissionCatalog, s as Principal, u as definePermissions } from "./policy-CnQj53Hq.js";
|
|
2
|
+
import { AuthInfo, CallToolResult, GetPromptResult, Icon, Implementation, InboundClassificationOutcome, McpServer, OAuthMetadata, OAuthTokenVerifier, ReadResourceResult, ResourceMetadata, ResourceTemplate, ServerOptions as ServerOptions$1, StandardSchemaV1, StandardSchemaWithJSON, ToolAnnotations } from "@modelcontextprotocol/server";
|
|
3
|
+
//#region src/discovery.d.ts
|
|
4
|
+
type DiscoverOptions = {
|
|
5
|
+
/** Swap in for tests, or to add a timeout or proxy. Defaults to global fetch. */
|
|
6
|
+
fetch?: typeof globalThis.fetch;
|
|
7
|
+
};
|
|
8
|
+
declare function discoverOAuth(issuer: string, options?: DiscoverOptions): Promise<OAuthMetadata>;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/tools.d.ts
|
|
11
|
+
/**
|
|
12
|
+
* Tools, prompts and resources that carry the permission they require.
|
|
13
|
+
*
|
|
14
|
+
* Declaring it here rather than in a separate rules file is the whole point: it
|
|
15
|
+
* is checked against the policy by the compiler, reconciled against the policy
|
|
16
|
+
* at boot, and it cannot drift when somebody renames the tool.
|
|
17
|
+
*
|
|
18
|
+
* MCP exposes three things a caller can reach, so gating only tools leaves two
|
|
19
|
+
* doors open. All three register the same way: check the permission, skip the
|
|
20
|
+
* registration when the caller lacks it, audit what they do reach.
|
|
21
|
+
*/
|
|
22
|
+
/** Which of the three a caller reached. */
|
|
23
|
+
type Capability = 'tool' | 'prompt' | 'resource';
|
|
24
|
+
/** What actually happened, for the audit log the downstream API cannot write. */
|
|
25
|
+
type AuditEvent = {
|
|
26
|
+
issuer: string;
|
|
27
|
+
sub: string;
|
|
28
|
+
email?: string;
|
|
29
|
+
kind: Capability;
|
|
30
|
+
/** The registered name, e.g. `update_case`. */
|
|
31
|
+
name: string;
|
|
32
|
+
permission: string;
|
|
33
|
+
/** Whatever the definition's own `audit` said the call touched, e.g. `case:C1234`. */
|
|
34
|
+
resource?: string;
|
|
35
|
+
decision: 'allow';
|
|
36
|
+
phase: 'attempt' | 'success' | 'failure';
|
|
37
|
+
at: string;
|
|
38
|
+
durationMs?: number;
|
|
39
|
+
error?: string;
|
|
40
|
+
};
|
|
41
|
+
type AuditSink = (event: AuditEvent) => unknown | Promise<unknown>;
|
|
42
|
+
type InferArgs<S> = S extends StandardSchemaV1<unknown, infer Output> ? Output : undefined;
|
|
43
|
+
/** Shared by all three: what it costs, and what the call touched. */
|
|
44
|
+
type Gated<P extends string, A> = {
|
|
45
|
+
/** Required to reach it. Typed to the policy's permissions, so a typo is a build error. */
|
|
46
|
+
permission: P;
|
|
47
|
+
/**
|
|
48
|
+
* Name the thing the call touched, for the audit event. The library cannot
|
|
49
|
+
* know that `{ caseId: 'C1234' }` means a case; the application always does.
|
|
50
|
+
*/
|
|
51
|
+
audit?: (args: A) => string | undefined;
|
|
52
|
+
};
|
|
53
|
+
type ToolConfig<P extends string, S> = Gated<P, InferArgs<S>> & {
|
|
54
|
+
title?: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
inputSchema?: S;
|
|
57
|
+
outputSchema?: StandardSchemaWithJSON;
|
|
58
|
+
annotations?: ToolAnnotations;
|
|
59
|
+
icons?: Icon[];
|
|
60
|
+
};
|
|
61
|
+
type PromptConfig<P extends string, S> = Gated<P, InferArgs<S>> & {
|
|
62
|
+
title?: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
argsSchema?: S;
|
|
65
|
+
icons?: Icon[];
|
|
66
|
+
};
|
|
67
|
+
type ResourceConfig<P extends string> = Gated<P, URL> & ResourceMetadata & {
|
|
68
|
+
/** The URI clients read, or a template for a family of them. */
|
|
69
|
+
uri: string | ResourceTemplate;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Erased once built, so a server registers every capability the same way
|
|
73
|
+
* whatever it accepts.
|
|
74
|
+
*/
|
|
75
|
+
type Definition<P extends string, C = Principal<P>> = {
|
|
76
|
+
/**
|
|
77
|
+
* Unique key for the boot-time check. Bare for a tool, prefixed otherwise, so
|
|
78
|
+
* a prompt sharing a tool's name stays a separate entry rather than shadowing
|
|
79
|
+
* it.
|
|
80
|
+
*/
|
|
81
|
+
label: string;
|
|
82
|
+
kind: Capability;
|
|
83
|
+
/** Exact protocol name used to refuse an unpermitted direct invocation before scope step-up. */
|
|
84
|
+
routeName?: string;
|
|
85
|
+
routeMatches?: (name: string) => boolean;
|
|
86
|
+
permission: P;
|
|
87
|
+
register: (server: McpServer, principal: Principal<P>, context: C, onAudit?: AuditSink) => void;
|
|
88
|
+
};
|
|
89
|
+
type ServerOptions = Implementation & {
|
|
90
|
+
/** Called on every permitted invocation. The one record tying a person to an action. */
|
|
91
|
+
onAudit?: AuditSink;
|
|
92
|
+
/** Pass-through SDK options; declared gated capabilities are merged in. */
|
|
93
|
+
mcp?: ServerOptions$1;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* A per-request server factory over a fixed set of capabilities, plus the
|
|
97
|
+
* label-to-permission map that `createMcpFetch` reconciles against the policy
|
|
98
|
+
* at boot.
|
|
99
|
+
*/
|
|
100
|
+
type ServerFactory<C> = ((context: C) => McpServer) & {
|
|
101
|
+
permissions: ReadonlyMap<string, string>;
|
|
102
|
+
routePermissions: ReadonlyMap<string, string>;
|
|
103
|
+
permissionForRoute: (kind: Capability, name: string) => string | undefined;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Everything bound to one policy: `permission` accepts only what that policy can
|
|
107
|
+
* grant, in all four places, from one call.
|
|
108
|
+
*
|
|
109
|
+
* The policy is a type carrier here and is never invoked. Authorization happens
|
|
110
|
+
* once per request when the principal is resolved, not once per definition.
|
|
111
|
+
*
|
|
112
|
+
* ```ts
|
|
113
|
+
* const { tool, prompt, resource, server } = authz(policy);
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
declare function bindAuthz<P extends string, C, H>(_permissions: Policy<P> | PermissionCatalog<P>, principalOf: (context: C) => Principal<P>, handlerContext: (context: C, principal: Principal<P>) => H): {
|
|
117
|
+
tool: <S extends StandardSchemaWithJSON | undefined = undefined>(name: string, config: ToolConfig<P, S>, handler: (args: InferArgs<S>, context: H) => CallToolResult | Promise<CallToolResult>) => Definition<P, C>;
|
|
118
|
+
prompt: <S extends StandardSchemaWithJSON | undefined = undefined>(name: string, config: PromptConfig<P, S>, handler: (args: InferArgs<S>, context: H) => GetPromptResult | Promise<GetPromptResult>) => Definition<P, C>;
|
|
119
|
+
resource: (name: string, config: ResourceConfig<P>, handler: (uri: URL, context: H) => ReadResourceResult | Promise<ReadResourceResult>) => Definition<P, C>;
|
|
120
|
+
server: (definitions: readonly Definition<P, C>[], options: ServerOptions) => ServerFactory<C>;
|
|
121
|
+
};
|
|
122
|
+
declare function authz<P extends string>(policy: Policy<P> | PermissionCatalog<P>): ReturnType<typeof bindAuthz<P, Principal<P>, {
|
|
123
|
+
principal: Principal<P>;
|
|
124
|
+
}>>;
|
|
125
|
+
declare function authz<P extends string, C>(policy: Policy<P> | PermissionCatalog<P>, options: {
|
|
126
|
+
principal: (context: C) => Principal<P>;
|
|
127
|
+
}): ReturnType<typeof bindAuthz<P, C, C>>;
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/gate.d.ts
|
|
130
|
+
/**
|
|
131
|
+
* Gate a server somebody else builds.
|
|
132
|
+
*
|
|
133
|
+
* `authz(policy)` is for tools you write. This is for the ones you already
|
|
134
|
+
* have: an MCP server from another package, or one you are not ready to change,
|
|
135
|
+
* whose tools were never declared with a permission.
|
|
136
|
+
*
|
|
137
|
+
* It cannot read a built server's tool list — the SDK keeps that private, and
|
|
138
|
+
* no library can filter what it never saw. So this wraps the server *before*
|
|
139
|
+
* registration and gates each call as it happens, which needs one hook from
|
|
140
|
+
* whoever builds it:
|
|
141
|
+
*
|
|
142
|
+
* ```ts
|
|
143
|
+
* // in their builder
|
|
144
|
+
* const server = options.wrap ? options.wrap(new McpServer(info, opts)) : new McpServer(info, opts);
|
|
145
|
+
*
|
|
146
|
+
* // in your connector
|
|
147
|
+
* buildServer(config, { wrap: (server) => gate(server, principal, PERMISSIONS) })
|
|
148
|
+
* ```
|
|
149
|
+
*
|
|
150
|
+
* Unpermitted registrations are registered and immediately disabled rather than
|
|
151
|
+
* skipped, so the caller still gets the handle its own code expects, and the
|
|
152
|
+
* SDK does the list-filtering and the refusal.
|
|
153
|
+
*/
|
|
154
|
+
type GateOptions = {
|
|
155
|
+
/** Same event as `authz`, for tools this package did not define. */
|
|
156
|
+
onAudit?: AuditSink;
|
|
157
|
+
/**
|
|
158
|
+
* Name the thing a call touched, keyed by the same label as `permissions`.
|
|
159
|
+
* Their tool, your domain knowledge.
|
|
160
|
+
*/
|
|
161
|
+
audit?: Readonly<Record<string, (args: never) => string | undefined>>;
|
|
162
|
+
};
|
|
163
|
+
/** Bare name for a tool, `prompt:`/`resource:` prefixed for the rest. */
|
|
164
|
+
type PermissionMap<P extends string> = Readonly<Record<string, P>> | ReadonlyMap<string, P>;
|
|
165
|
+
declare function gate<P extends string>(server: McpServer, principal: Principal<P>, permissions: PermissionMap<P>, options?: GateOptions): McpServer;
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/routing.d.ts
|
|
168
|
+
type TrustedMcpRoute = {
|
|
169
|
+
kind: 'modern';
|
|
170
|
+
body: unknown;
|
|
171
|
+
outcome: Extract<InboundClassificationOutcome, {
|
|
172
|
+
kind: 'modern';
|
|
173
|
+
}>;
|
|
174
|
+
method: string;
|
|
175
|
+
name?: string;
|
|
176
|
+
};
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/scopes.d.ts
|
|
179
|
+
/**
|
|
180
|
+
* Helpers for deriving required OAuth scopes from Streamable HTTP headers
|
|
181
|
+
* (SEP-2243). Use with `createMcpFetch({ scopesForRequest })`.
|
|
182
|
+
*/
|
|
183
|
+
type ScopeRequirement = string | readonly string[];
|
|
184
|
+
type ToolScopeMap = Readonly<Record<string, ScopeRequirement>>;
|
|
185
|
+
type CapabilityScopeMap = ToolScopeMap;
|
|
186
|
+
/**
|
|
187
|
+
* Tools use their bare name (or `tool:name`); prompts use `prompt:name`; and
|
|
188
|
+
* resources use `resource:<uri>`. Everything else needs only the baseline.
|
|
189
|
+
*/
|
|
190
|
+
declare function scopesFromMcpHeaders(request: Request, toolScopes: ToolScopeMap, baseline?: string): string[];
|
|
191
|
+
/** Select scopes from an already validated MCP method/name pair. */
|
|
192
|
+
declare function scopesForCapability(method: string | undefined, name: string | undefined, capabilityScopes: CapabilityScopeMap, baseline?: string): string[];
|
|
193
|
+
/** Decode SEP-2243's optional Base64 sentinel without accepting non-canonical input. */
|
|
194
|
+
declare function decodeMcpNameHeader(value: string): string | undefined;
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/verifier.d.ts
|
|
197
|
+
/**
|
|
198
|
+
* Token verification, the one thing the SDK deliberately leaves to you.
|
|
199
|
+
*
|
|
200
|
+
* `authInfo` is strictly pass-through in the SDK: it is never derived from
|
|
201
|
+
* request headers, and no token is checked unless we check it. So this file is
|
|
202
|
+
* the security boundary of the whole server.
|
|
203
|
+
*
|
|
204
|
+
* The authorization server is something that already exists (WorkOS, Stytch,
|
|
205
|
+
* Auth0) doing dynamic client registration / CIMD and Google Workspace login.
|
|
206
|
+
* Google cannot play that role itself: it has no DCR/CIMD, and it will not
|
|
207
|
+
* mint a token whose audience is this server.
|
|
208
|
+
*/
|
|
209
|
+
type VerifierOptions = {
|
|
210
|
+
/** The AS issuer, e.g. `https://auth.acme.com`. Must match the token's `iss`. */
|
|
211
|
+
issuer: string;
|
|
212
|
+
/** Where the AS publishes its signing keys. */
|
|
213
|
+
jwksUri: string;
|
|
214
|
+
/**
|
|
215
|
+
* This server's public URL. A token minted for a different resource is
|
|
216
|
+
* refused even when its signature is valid (RFC 8707).
|
|
217
|
+
*/
|
|
218
|
+
resource: URL;
|
|
219
|
+
/**
|
|
220
|
+
* Restrict to one Google Workspace domain, checked against the `hd` claim
|
|
221
|
+
* the AS passes through. Omit to accept any domain the AS admits.
|
|
222
|
+
*/
|
|
223
|
+
allowedDomain?: string;
|
|
224
|
+
/** Claim carrying the verified email. Auth0 and WorkOS both use `email`. */
|
|
225
|
+
emailClaim?: string;
|
|
226
|
+
/** Claim proving the email was verified. Defaults to `email_verified`. */
|
|
227
|
+
emailVerifiedClaim?: string;
|
|
228
|
+
/** Require an explicit `true` verified-email claim. Defaults to true. */
|
|
229
|
+
requireEmailVerified?: boolean;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* A JWKS-backed verifier. Keys are fetched once and cached by `jose`, which
|
|
233
|
+
* also handles rotation, so a key roll at the AS does not need a redeploy.
|
|
234
|
+
*/
|
|
235
|
+
declare function jwksVerifier(options: VerifierOptions): OAuthTokenVerifier & {
|
|
236
|
+
identityOf: (auth: AuthInfo) => Identity;
|
|
237
|
+
};
|
|
238
|
+
/** Default identity mapper for custom verifiers using `AuthInfo.extra`. */
|
|
239
|
+
declare function identityFromAuth(auth: AuthInfo): Identity;
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/handler.d.ts
|
|
242
|
+
type AuthorizationDecisionEvent = {
|
|
243
|
+
issuer: string;
|
|
244
|
+
sub: string;
|
|
245
|
+
email?: string;
|
|
246
|
+
decision: 'allow' | 'deny';
|
|
247
|
+
roles: readonly string[];
|
|
248
|
+
permissions: readonly string[];
|
|
249
|
+
reason?: string;
|
|
250
|
+
at: string;
|
|
251
|
+
};
|
|
252
|
+
type AuthorizationDecisionSink = (event: AuthorizationDecisionEvent) => unknown | Promise<unknown>;
|
|
253
|
+
/**
|
|
254
|
+
* An MCP Streamable HTTP resource server (2026-07-28) with
|
|
255
|
+
* each person's own Google login in front of a per-request server factory.
|
|
256
|
+
*
|
|
257
|
+
* Three parties, and it matters which does what:
|
|
258
|
+
*
|
|
259
|
+
* Claude runs the OAuth flow and presents a bearer token
|
|
260
|
+
* your AS registers Claude (CIMD preferred; DCR deprecated), logs
|
|
261
|
+
* the human in with Google, and mints a token bound to
|
|
262
|
+
* THIS server's URL
|
|
263
|
+
* this file verifies that token, maps the identity to context, and
|
|
264
|
+
* builds a server for that request
|
|
265
|
+
*
|
|
266
|
+
* We are a resource server and nothing more.
|
|
267
|
+
*/
|
|
268
|
+
type McpFetchOptions<TContext, P extends string = string> = {
|
|
269
|
+
/** This server's public URL, e.g. `https://mcp.acme.com/mcp`. */
|
|
270
|
+
resourceServerUrl: URL;
|
|
271
|
+
/** RFC 8414 metadata for the authorization server in front of us. */
|
|
272
|
+
oauthMetadata: OAuthMetadata;
|
|
273
|
+
/**
|
|
274
|
+
* Token verification. The SDK verifies no tokens of its own, so this is the
|
|
275
|
+
* security boundary, but every field has a sound default.
|
|
276
|
+
*
|
|
277
|
+
* `issuer` and `resource` come from `oauthMetadata.issuer` and
|
|
278
|
+
* `resourceServerUrl`, which is what they have to be: a verifier trusting a
|
|
279
|
+
* different issuer, or checking the audience against a URL this server does
|
|
280
|
+
* not answer on, refuses every valid token and says only "invalid token".
|
|
281
|
+
* `jwksUri` comes from `oauthMetadata.jwks_uri` when discovery supplied it,
|
|
282
|
+
* so this whole block is optional.
|
|
283
|
+
*/
|
|
284
|
+
verifier?: Partial<VerifierOptions>;
|
|
285
|
+
/**
|
|
286
|
+
* Bring any SDK-compatible verifier, including RFC 7662 introspection for
|
|
287
|
+
* opaque tokens. Mutually exclusive with the built-in `verifier` options.
|
|
288
|
+
*/
|
|
289
|
+
tokenVerifier?: OAuthTokenVerifier;
|
|
290
|
+
/** Map a custom verifier's AuthInfo into the identity consumed by policy. */
|
|
291
|
+
identityFromAuth?: (auth: AuthInfo) => Identity;
|
|
292
|
+
/**
|
|
293
|
+
* Baseline scopes every request must carry. Keep it to one small scope
|
|
294
|
+
* (`mcp` by default); use `scopesForRequest` for per-tool step-up.
|
|
295
|
+
*/
|
|
296
|
+
requiredScopes?: string[];
|
|
297
|
+
/** All scopes advertised in protected-resource metadata. */
|
|
298
|
+
supportedScopes?: string[];
|
|
299
|
+
/** Declarative per-tool step-up. Mutually exclusive with `scopesForRequest`. */
|
|
300
|
+
toolScopes?: ToolScopeMap;
|
|
301
|
+
/** Tools, prompts and resource URIs mapped to scope requirements. */
|
|
302
|
+
capabilityScopes?: CapabilityScopeMap;
|
|
303
|
+
/**
|
|
304
|
+
* Map a request to the scopes it needs. The second argument is the trusted,
|
|
305
|
+
* body-validated and Base64-decoded MCP route; use it instead of reading raw
|
|
306
|
+
* `Mcp-Method` / `Mcp-Name` values yourself. Returning more than the token
|
|
307
|
+
* holds produces HTTP 403 with actionable `insufficient_scope` step-up.
|
|
308
|
+
*
|
|
309
|
+
* Omit to demand only `requiredScopes` on every call.
|
|
310
|
+
*/
|
|
311
|
+
scopesForRequest?: (request: Request, route: TrustedMcpRoute) => string[];
|
|
312
|
+
/**
|
|
313
|
+
* Who may connect and what they may do. Supply this and the per-request
|
|
314
|
+
* context is the `Principal`; a caller matching no rule is refused.
|
|
315
|
+
*
|
|
316
|
+
* Paired with a `toolServer`, the tools' permissions are reconciled against
|
|
317
|
+
* the policy at startup, so a tool no role can reach fails the boot rather
|
|
318
|
+
* than sitting there looking live.
|
|
319
|
+
*/
|
|
320
|
+
policy?: Policy<P>;
|
|
321
|
+
/**
|
|
322
|
+
* Async alternative to `policy`, for roles and permissions stored in an IdP,
|
|
323
|
+
* database or policy service. Return a principal with `createPrincipal`.
|
|
324
|
+
*/
|
|
325
|
+
authorize?: (identity: Identity) => Promise<Principal<P>> | Principal<P>;
|
|
326
|
+
/** Awaited access-decision sink. A rejection fails closed. */
|
|
327
|
+
onDecision?: AuthorizationDecisionSink;
|
|
328
|
+
/**
|
|
329
|
+
* After auth: map the verified identity to backend context, or throw
|
|
330
|
+
* `AccessDeniedError` for an actionable 403. Omit to use `policy` alone.
|
|
331
|
+
*
|
|
332
|
+
* Supply both when the context needs more than the principal — a tenant, a
|
|
333
|
+
* connection, a downstream credential. The policy still runs first and still
|
|
334
|
+
* refuses anyone it grants nothing, so this enriches the context rather than
|
|
335
|
+
* taking over the decision, and the boot-time reconciliation stays honest.
|
|
336
|
+
*/
|
|
337
|
+
resolve?: (identity: Identity, principal: Principal<P> | undefined) => Promise<TContext> | TContext;
|
|
338
|
+
/** Per-request MCP server factory. `toolServer` builds one from a tool set. */
|
|
339
|
+
createServer: ((context: TContext) => McpServer) & {
|
|
340
|
+
/** Tool name to required permission, when the factory knows its own tools. */
|
|
341
|
+
permissions?: ReadonlyMap<string, string>;
|
|
342
|
+
/** Protocol route to permission, used to distinguish policy denial from scope step-up. */
|
|
343
|
+
routePermissions?: ReadonlyMap<string, string>;
|
|
344
|
+
/** Resolve exact and templated protocol routes to their declared permission. */
|
|
345
|
+
permissionForRoute?: (kind: 'tool' | 'prompt' | 'resource', name: string) => string | undefined;
|
|
346
|
+
};
|
|
347
|
+
/**
|
|
348
|
+
* The same map, when your own factory wraps a `toolServer` and hides it —
|
|
349
|
+
* which a richer `TContext` than the principal forces you to do. Pass
|
|
350
|
+
* `toolServer(...).permissions` here and the boot-time check still runs.
|
|
351
|
+
*/
|
|
352
|
+
permissions?: ReadonlyMap<string, string>;
|
|
353
|
+
/** Key under `authInfo.extra` for the resolved context. */
|
|
354
|
+
contextExtraKey?: string;
|
|
355
|
+
/** Health check path. Defaults to `/health`. */
|
|
356
|
+
healthPath?: string;
|
|
357
|
+
/** Reject 2025-era requests by default; opt in only when legacy clients are required. */
|
|
358
|
+
legacy?: 'reject' | 'stateless';
|
|
359
|
+
/**
|
|
360
|
+
* Cap on a body read before authentication, which only the declarative scope
|
|
361
|
+
* path does. Defaults to 1 MiB; over it is a 413.
|
|
362
|
+
*/
|
|
363
|
+
maxRequestBytes?: number;
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* With a `policy`, the principal reaching `resolve` is never undefined: the
|
|
367
|
+
* policy ran first and already refused anyone it grants nothing. Saying so here
|
|
368
|
+
* saves every caller the same non-null assertion.
|
|
369
|
+
*/
|
|
370
|
+
declare function createMcpFetch<TContext = Principal<string>, P extends string = string>(options: Omit<McpFetchOptions<TContext, P>, 'policy' | 'authorize' | 'resolve'> & {
|
|
371
|
+
policy: Policy<P>;
|
|
372
|
+
authorize?: never;
|
|
373
|
+
resolve?: (identity: Identity, principal: Principal<P>) => Promise<TContext> | TContext;
|
|
374
|
+
}): (request: Request) => Promise<Response>;
|
|
375
|
+
declare function createMcpFetch<TContext = Principal<string>, P extends string = string>(options: Omit<McpFetchOptions<TContext, P>, 'policy' | 'authorize' | 'resolve'> & {
|
|
376
|
+
policy?: never;
|
|
377
|
+
authorize: (identity: Identity) => Promise<Principal<P>> | Principal<P>;
|
|
378
|
+
resolve?: (identity: Identity, principal: Principal<P>) => Promise<TContext> | TContext;
|
|
379
|
+
}): (request: Request) => Promise<Response>;
|
|
380
|
+
declare function createMcpFetch<TContext = Principal<string>, P extends string = string>(options: Omit<McpFetchOptions<TContext, P>, 'policy' | 'authorize' | 'resolve'> & {
|
|
381
|
+
policy?: never;
|
|
382
|
+
authorize?: never;
|
|
383
|
+
resolve: (identity: Identity, principal: undefined) => Promise<TContext> | TContext;
|
|
384
|
+
}): (request: Request) => Promise<Response>;
|
|
385
|
+
//#endregion
|
|
386
|
+
export { AccessDeniedError, type AuditEvent, type AuditSink, type AuthorizationDecisionEvent, type AuthorizationDecisionSink, type Capability, type CapabilityScopeMap, type Definition, type DenialReason, type DiscoverOptions, type GateOptions, type Identity, type Match, type McpFetchOptions, type PermissionCatalog, type PermissionMap, type PermissionOf, type Policy, type PolicySpec, type Principal, type PromptConfig, type ResourceConfig, type Rule, type ScopeRequirement, type ServerOptions, type ToolConfig, type ToolScopeMap, type TrustedMcpRoute, type VerifierOptions, authz, createMcpFetch, createPrincipal, decodeMcpNameHeader, definePermissions, definePolicy, discoverOAuth, gate, identityFromAuth, jwksVerifier, reconcile, scopesForCapability, scopesFromMcpHeaders };
|