mcp-authz 0.2.0 → 0.3.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/README.md +5 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/{ladder-BhG1S7nd.js → ladder-CUzOKudC.js} +1 -1
- package/dist/openapi.d.ts +1 -1
- package/dist/openapi.js +1 -1
- package/dist/proxy.d.ts +1 -1
- package/dist/proxy.js +2 -2
- package/dist/{verifier-BruW4XGR.js → verifier-D6VIAYuT.js} +5 -4
- package/dist/{verifier-rQlS6rYR.d.ts → verifier-DF6gUMQ6.d.ts} +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -254,6 +254,11 @@ provider-specific assurance claim, or explicitly set `requireEmailVerified:
|
|
|
254
254
|
false` only when the issuer contract guarantees the email another way. For
|
|
255
255
|
opaque tokens, pass any SDK-compatible `tokenVerifier` plus `identityFromAuth`.
|
|
256
256
|
|
|
257
|
+
An agent that signs in as itself, with an OAuth client-credentials token,
|
|
258
|
+
carries a `sub` and no email. Set `verifier.requireEmail: false` to accept it,
|
|
259
|
+
and name its `sub` in a rule to grant it roles. Email and domain rules never
|
|
260
|
+
match it and `allowedDomain` refuses it, but a rule with no `match` admits it.
|
|
261
|
+
|
|
257
262
|
### `definePolicy(spec)`
|
|
258
263
|
|
|
259
264
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as Identity, a as PermissionCatalog, c as PolicySpec, d as createPrincipal, f as definePermissions, g as DenialReason, h as AccessDeniedError, i as MatchedRule, l as Principal, m as reconcile, n as Explanation, o as PermissionOf, p as definePolicy, r as Match, s as Policy, u as Rule } from "./policy-DuZbwrKf.js";
|
|
2
2
|
import { a as AuditDeliveryFailure, c as AuditSink, d as PromptConfig, f as ResourceConfig, h as authz, i as ApprovalSink, l as Capability, m as ToolConfig, n as ApprovalRefusedError, o as AuditErrorSink, p as ServerOptions, r as ApprovalRequest, s as AuditEvent, t as ApprovalDecision, u as Definition } from "./tools-BQE1O-7P.js";
|
|
3
|
-
import { a as AuthorizationDecisionSink, i as AuthorizationDecisionEvent, n as identityFromAuth, r as jwksVerifier, t as VerifierOptions } from "./verifier-
|
|
3
|
+
import { a as AuthorizationDecisionSink, i as AuthorizationDecisionEvent, n as identityFromAuth, r as jwksVerifier, t as VerifierOptions } from "./verifier-DF6gUMQ6.js";
|
|
4
4
|
import { a as scopesForCapability, i as decodeMcpNameHeader, n as ScopeRequirement, o as scopesFromMcpHeaders, r as ToolScopeMap, s as TrustedMcpRoute, t as CapabilityScopeMap } from "./ladder-D18eJ7tD.js";
|
|
5
5
|
import { AuthInfo, McpServer, OAuthMetadata, OAuthTokenVerifier } from "@modelcontextprotocol/server";
|
|
6
6
|
//#region src/discovery.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as policyDenied, i as emitDecision, n as jwksVerifier, o as principalLabel, r as verifierFor, s as AccessDeniedError, t as identityFromAuth } from "./verifier-
|
|
2
|
-
import { d as scopesForCapability, f as scopesFromMcpHeaders, i as runScopedGate, r as permissionForRoute, u as decodeMcpNameHeader } from "./ladder-
|
|
1
|
+
import { a as policyDenied, i as emitDecision, n as jwksVerifier, o as principalLabel, r as verifierFor, s as AccessDeniedError, t as identityFromAuth } from "./verifier-D6VIAYuT.js";
|
|
2
|
+
import { d as scopesForCapability, f as scopesFromMcpHeaders, i as runScopedGate, r as permissionForRoute, u as decodeMcpNameHeader } from "./ladder-CUzOKudC.js";
|
|
3
3
|
import { i as reconcile, n as definePermissions, r as definePolicy, t as createPrincipal } from "./policy-BBp3Jq6G.js";
|
|
4
4
|
import { McpServer, UriTemplate, createMcpHandler, getOAuthProtectedResourceMetadataUrl, oauthMetadataResponse, requireBearerAuth } from "@modelcontextprotocol/server";
|
|
5
5
|
//#region src/discovery.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as policyDenied, i as emitDecision, o as principalLabel, s as AccessDeniedError } from "./verifier-
|
|
1
|
+
import { a as policyDenied, i as emitDecision, o as principalLabel, s as AccessDeniedError } from "./verifier-D6VIAYuT.js";
|
|
2
2
|
import { OAuthError, OAuthErrorCode, bearerAuthChallengeResponse, classifyInboundRequest, isJsonContentType } from "@modelcontextprotocol/server";
|
|
3
3
|
//#region src/scopes.ts
|
|
4
4
|
const BASE64_SENTINEL = /^=\?base64\?([A-Za-z0-9+/]*(?:={0,2}))\?=$/;
|
package/dist/openapi.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as Identity, l as Principal, s as Policy } from "./policy-DuZbwrKf.js";
|
|
2
2
|
import { c as AuditSink, o as AuditErrorSink } from "./tools-BQE1O-7P.js";
|
|
3
|
-
import { a as AuthorizationDecisionSink, t as VerifierOptions } from "./verifier-
|
|
3
|
+
import { a as AuthorizationDecisionSink, t as VerifierOptions } from "./verifier-DF6gUMQ6.js";
|
|
4
4
|
import { t as PermissionMapRecord } from "./permissions-module-DxCHuE-N.js";
|
|
5
5
|
import { AuthInfo, OAuthMetadata, OAuthTokenVerifier } from "@modelcontextprotocol/server";
|
|
6
6
|
//#region src/openapi.d.ts
|
package/dist/openapi.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as policyDenied, i as emitDecision, o as principalLabel, r as verifierFor, s as AccessDeniedError } from "./verifier-
|
|
1
|
+
import { a as policyDenied, i as emitDecision, o as principalLabel, r as verifierFor, s as AccessDeniedError } from "./verifier-D6VIAYuT.js";
|
|
2
2
|
import { i as reconcile } from "./policy-BBp3Jq6G.js";
|
|
3
3
|
import { getOAuthProtectedResourceMetadataUrl, oauthMetadataResponse, requireBearerAuth } from "@modelcontextprotocol/server";
|
|
4
4
|
//#region src/openapi.ts
|
package/dist/proxy.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as Identity, s as Policy } from "./policy-DuZbwrKf.js";
|
|
2
|
-
import { a as AuthorizationDecisionSink, t as VerifierOptions } from "./verifier-
|
|
2
|
+
import { a as AuthorizationDecisionSink, t as VerifierOptions } from "./verifier-DF6gUMQ6.js";
|
|
3
3
|
import { t as CapabilityScopeMap } from "./ladder-D18eJ7tD.js";
|
|
4
4
|
import { AuthInfo, OAuthMetadata, OAuthTokenVerifier } from "@modelcontextprotocol/server";
|
|
5
5
|
//#region src/upstream.d.ts
|
package/dist/proxy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as policyDenied, i as emitDecision, n as jwksVerifier, o as principalLabel, s as AccessDeniedError, t as identityFromAuth } from "./verifier-
|
|
2
|
-
import { a as forwardToUpstream, c as isJsonResponse, d as scopesForCapability, i as runScopedGate, l as readCappedBody, n as permissionForFlatMap, o as headersForRewrittenBody, s as isEventStream, t as capabilityLabel } from "./ladder-
|
|
1
|
+
import { a as policyDenied, i as emitDecision, n as jwksVerifier, o as principalLabel, s as AccessDeniedError, t as identityFromAuth } from "./verifier-D6VIAYuT.js";
|
|
2
|
+
import { a as forwardToUpstream, c as isJsonResponse, d as scopesForCapability, i as runScopedGate, l as readCappedBody, n as permissionForFlatMap, o as headersForRewrittenBody, s as isEventStream, t as capabilityLabel } from "./ladder-CUzOKudC.js";
|
|
3
3
|
import { i as reconcile } from "./policy-BBp3Jq6G.js";
|
|
4
4
|
import { UriTemplate, getOAuthProtectedResourceMetadataUrl, oauthMetadataResponse, requireBearerAuth } from "@modelcontextprotocol/server";
|
|
5
5
|
import { err, isUnexpectedError, ok, run } from "awaitly";
|
|
@@ -69,9 +69,10 @@ function jwksVerifier(options) {
|
|
|
69
69
|
throw invalidToken(`Token rejected: ${error instanceof Error ? error.message : String(error)}`);
|
|
70
70
|
}
|
|
71
71
|
if (typeof payload.exp !== "number") throw invalidToken("Token has no `exp` claim.");
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
if ((options.
|
|
72
|
+
const claimed = payload[emailClaim];
|
|
73
|
+
const email = typeof claimed === "string" && claimed ? claimed : void 0;
|
|
74
|
+
if (!email && (options.requireEmail ?? true)) throw invalidToken(`Token carries no '${emailClaim}' claim, so there is no identity to map.`);
|
|
75
|
+
if (email && (options.requireEmailVerified ?? true) && payload[emailVerifiedClaim] !== true) throw invalidToken(`Token does not prove '${emailClaim}' with '${emailVerifiedClaim}: true'.`);
|
|
75
76
|
const sub = payload.sub;
|
|
76
77
|
if (typeof sub !== "string" || !sub) throw invalidToken("Token has no `sub` claim, so there is no stable subject to bind to.");
|
|
77
78
|
const domain = typeof payload.hd === "string" ? payload.hd : void 0;
|
|
@@ -86,7 +87,7 @@ function jwksVerifier(options) {
|
|
|
86
87
|
issuer: options.issuer,
|
|
87
88
|
sub,
|
|
88
89
|
email,
|
|
89
|
-
emailVerified: options.requireEmailVerified === false || payload[emailVerifiedClaim] === true,
|
|
90
|
+
emailVerified: email !== void 0 && (options.requireEmailVerified === false || payload[emailVerifiedClaim] === true),
|
|
90
91
|
domain,
|
|
91
92
|
claims: payload
|
|
92
93
|
}
|
|
@@ -62,6 +62,14 @@ type VerifierOptions = {
|
|
|
62
62
|
emailVerifiedClaim?: string;
|
|
63
63
|
/** Require an explicit `true` verified-email claim. Defaults to true. */
|
|
64
64
|
requireEmailVerified?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Require an email in every token. Defaults to true. Set false to accept an
|
|
67
|
+
* agent that signs in as itself, such as an OAuth client-credentials token:
|
|
68
|
+
* its identity is its `sub`, which a policy rule names. Email and domain
|
|
69
|
+
* rules never match it, and neither does `allowedDomain`; a rule with no
|
|
70
|
+
* `match` does. A token that does carry an email is checked as before.
|
|
71
|
+
*/
|
|
72
|
+
requireEmail?: boolean;
|
|
65
73
|
};
|
|
66
74
|
/**
|
|
67
75
|
* A JWKS-backed verifier. Keys are fetched once and cached by `jose`, which
|
package/package.json
CHANGED