@frontmcp/auth 1.0.4 → 1.1.0-beta.1
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/authorities/authorities.context.d.ts +63 -0
- package/authorities/authorities.context.d.ts.map +1 -0
- package/authorities/authorities.engine.d.ts +65 -0
- package/authorities/authorities.engine.d.ts.map +1 -0
- package/authorities/authorities.errors.d.ts +59 -0
- package/authorities/authorities.errors.d.ts.map +1 -0
- package/authorities/authorities.evaluator.d.ts +28 -0
- package/authorities/authorities.evaluator.d.ts.map +1 -0
- package/authorities/authorities.metadata-augment.d.ts +31 -0
- package/authorities/authorities.metadata-augment.d.ts.map +1 -0
- package/authorities/authorities.profiles.d.ts +75 -0
- package/authorities/authorities.profiles.d.ts.map +1 -0
- package/authorities/authorities.registry.d.ts +86 -0
- package/authorities/authorities.registry.d.ts.map +1 -0
- package/authorities/authorities.schema.d.ts +24 -0
- package/authorities/authorities.schema.d.ts.map +1 -0
- package/authorities/authorities.scope-mapping.d.ts +16 -0
- package/authorities/authorities.scope-mapping.d.ts.map +1 -0
- package/authorities/authorities.types.d.ts +290 -0
- package/authorities/authorities.types.d.ts.map +1 -0
- package/authorities/index.d.ts +17 -0
- package/authorities/index.d.ts.map +1 -0
- package/authorization/authorization.class.d.ts +2 -3
- package/authorization/authorization.class.d.ts.map +1 -1
- package/authorization/authorization.types.d.ts +53 -54
- package/authorization/authorization.types.d.ts.map +1 -1
- package/authorization/index.d.ts +1 -1
- package/authorization/index.d.ts.map +1 -1
- package/cimd/cimd.types.d.ts +90 -90
- package/cimd/cimd.types.d.ts.map +1 -1
- package/common/jwt.types.d.ts +16 -16
- package/common/jwt.types.d.ts.map +1 -1
- package/common/session.types.d.ts +75 -76
- package/common/session.types.d.ts.map +1 -1
- package/common/zod-utils.d.ts +1 -1
- package/common/zod-utils.d.ts.map +1 -1
- package/consent/consent.types.d.ts +69 -69
- package/consent/consent.types.d.ts.map +1 -1
- package/context/frontmcp-auth-context.d.ts +113 -0
- package/context/frontmcp-auth-context.d.ts.map +1 -0
- package/context/frontmcp-auth-context.factory.d.ts +39 -0
- package/context/frontmcp-auth-context.factory.d.ts.map +1 -0
- package/context/frontmcp-auth-context.impl.d.ts +72 -0
- package/context/frontmcp-auth-context.impl.d.ts.map +1 -0
- package/context/index.d.ts +16 -0
- package/context/index.d.ts.map +1 -0
- package/detection/auth-provider-detection.d.ts +25 -25
- package/detection/auth-provider-detection.d.ts.map +1 -1
- package/esm/index.mjs +1036 -120
- package/esm/package.json +5 -5
- package/fetch/fetch-credential-middleware.d.ts +99 -0
- package/fetch/fetch-credential-middleware.d.ts.map +1 -0
- package/fetch/index.d.ts +10 -0
- package/fetch/index.d.ts.map +1 -0
- package/index.d.ts +6 -2
- package/index.d.ts.map +1 -1
- package/index.js +1619 -680
- package/machine-id/index.d.ts +1 -1
- package/machine-id/index.d.ts.map +1 -1
- package/options/app-auth.schema.d.ts +235 -235
- package/options/app-auth.schema.d.ts.map +1 -1
- package/options/orchestrated.schema.d.ts +371 -371
- package/options/orchestrated.schema.d.ts.map +1 -1
- package/options/public.schema.d.ts +16 -16
- package/options/public.schema.d.ts.map +1 -1
- package/options/schema.d.ts +227 -227
- package/options/schema.d.ts.map +1 -1
- package/options/shared.schemas.d.ts +97 -97
- package/options/shared.schemas.d.ts.map +1 -1
- package/options/transparent.schema.d.ts +30 -30
- package/options/transparent.schema.d.ts.map +1 -1
- package/options/typecheck.d.ts.map +1 -1
- package/package.json +5 -5
- package/session/authorization-vault.d.ts +380 -380
- package/session/authorization-vault.d.ts.map +1 -1
- package/session/authorization.store.d.ts +28 -29
- package/session/authorization.store.d.ts.map +1 -1
- package/session/encrypted-authorization-vault.d.ts +21 -21
- package/session/encrypted-authorization-vault.d.ts.map +1 -1
- package/session/transport-session.types.d.ts +166 -167
- package/session/transport-session.types.d.ts.map +1 -1
- package/session/vault-encryption.d.ts +27 -27
- package/session/vault-encryption.d.ts.map +1 -1
- package/vault/auth-providers.types.d.ts +45 -46
- package/vault/auth-providers.types.d.ts.map +1 -1
package/esm/index.mjs
CHANGED
|
@@ -1149,8 +1149,8 @@ function renderToHtml(html, _options) {
|
|
|
1149
1149
|
}
|
|
1150
1150
|
|
|
1151
1151
|
// libs/auth/src/session/authorization.store.ts
|
|
1152
|
+
import { z } from "@frontmcp/lazy-zod";
|
|
1152
1153
|
import { randomUUID, sha256Base64url } from "@frontmcp/utils";
|
|
1153
|
-
import { z } from "zod";
|
|
1154
1154
|
var pkceChallengeSchema = z.object({
|
|
1155
1155
|
challenge: z.string().min(43).max(128),
|
|
1156
1156
|
method: z.literal("S256")
|
|
@@ -1428,7 +1428,7 @@ var RedisAuthorizationStore = class {
|
|
|
1428
1428
|
};
|
|
1429
1429
|
|
|
1430
1430
|
// libs/auth/src/session/authorization-vault.ts
|
|
1431
|
-
import { z as z2 } from "zod";
|
|
1431
|
+
import { z as z2 } from "@frontmcp/lazy-zod";
|
|
1432
1432
|
var credentialTypeSchema = z2.enum([
|
|
1433
1433
|
"oauth",
|
|
1434
1434
|
// OAuth 2.0 tokens
|
|
@@ -1689,14 +1689,14 @@ var authorizationVaultEntrySchema = z2.object({
|
|
|
1689
1689
|
});
|
|
1690
1690
|
|
|
1691
1691
|
// libs/auth/src/session/vault-encryption.ts
|
|
1692
|
-
import { z as z3 } from "zod";
|
|
1692
|
+
import { z as z3 } from "@frontmcp/lazy-zod";
|
|
1693
1693
|
import {
|
|
1694
|
-
|
|
1695
|
-
encryptAesGcm,
|
|
1696
|
-
decryptAesGcm,
|
|
1697
|
-
randomBytes as randomBytes2,
|
|
1694
|
+
base64urlDecode,
|
|
1698
1695
|
base64urlEncode,
|
|
1699
|
-
|
|
1696
|
+
decryptAesGcm,
|
|
1697
|
+
encryptAesGcm,
|
|
1698
|
+
hkdfSha256,
|
|
1699
|
+
randomBytes as randomBytes2
|
|
1700
1700
|
} from "@frontmcp/utils";
|
|
1701
1701
|
var encryptedDataSchema = z3.object({
|
|
1702
1702
|
/** Version for future algorithm changes */
|
|
@@ -1940,7 +1940,7 @@ import {
|
|
|
1940
1940
|
} from "@frontmcp/utils";
|
|
1941
1941
|
|
|
1942
1942
|
// libs/auth/src/session/transport-session.types.ts
|
|
1943
|
-
import { z as z4 } from "zod";
|
|
1943
|
+
import { z as z4 } from "@frontmcp/lazy-zod";
|
|
1944
1944
|
var transportProtocolSchema = z4.enum([
|
|
1945
1945
|
"legacy-sse",
|
|
1946
1946
|
"sse",
|
|
@@ -2426,84 +2426,13 @@ function extractBearerToken(header) {
|
|
|
2426
2426
|
}
|
|
2427
2427
|
|
|
2428
2428
|
// libs/auth/src/session/utils/session-crypto.utils.ts
|
|
2429
|
-
import {
|
|
2430
|
-
|
|
2431
|
-
// libs/auth/src/machine-id/machine-id.ts
|
|
2432
|
-
import { randomUUID as randomUUID3, mkdir, writeFile, readFileSync, getEnv as getEnv2, getCwd, isProduction as isProduction3, isBrowser } from "@frontmcp/utils";
|
|
2433
|
-
var DEFAULT_MACHINE_ID_PATH = ".frontmcp/machine-id";
|
|
2434
|
-
function isDevPersistenceEnabled() {
|
|
2435
|
-
if (isBrowser()) return false;
|
|
2436
|
-
return !isProduction3();
|
|
2437
|
-
}
|
|
2438
|
-
function resolveMachineIdPath() {
|
|
2439
|
-
if (isBrowser()) return DEFAULT_MACHINE_ID_PATH;
|
|
2440
|
-
const path = __require("path");
|
|
2441
|
-
const machineIdPath = getEnv2("MACHINE_ID_PATH") ?? DEFAULT_MACHINE_ID_PATH;
|
|
2442
|
-
return path.isAbsolute(machineIdPath) ? machineIdPath : path.resolve(getCwd(), machineIdPath);
|
|
2443
|
-
}
|
|
2444
|
-
function loadMachineIdSync() {
|
|
2445
|
-
if (!isDevPersistenceEnabled()) {
|
|
2446
|
-
return null;
|
|
2447
|
-
}
|
|
2448
|
-
const machineIdPath = resolveMachineIdPath();
|
|
2449
|
-
try {
|
|
2450
|
-
const content = readFileSync(machineIdPath, "utf8").trim();
|
|
2451
|
-
if (/^[0-9a-f-]{32,36}$/i.test(content)) {
|
|
2452
|
-
return content;
|
|
2453
|
-
}
|
|
2454
|
-
console.warn(`[MachineId] Invalid format at ${machineIdPath}, will regenerate`);
|
|
2455
|
-
return null;
|
|
2456
|
-
} catch (error) {
|
|
2457
|
-
if (error.code !== "ENOENT") {
|
|
2458
|
-
console.warn(`[MachineId] Failed to load from ${machineIdPath}: ${error.message}`);
|
|
2459
|
-
}
|
|
2460
|
-
return null;
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
function saveMachineIdAsync(machineId2) {
|
|
2464
|
-
if (!isDevPersistenceEnabled()) {
|
|
2465
|
-
return;
|
|
2466
|
-
}
|
|
2467
|
-
const machineIdPath = resolveMachineIdPath();
|
|
2468
|
-
const path = __require("path");
|
|
2469
|
-
const dir = path.dirname(machineIdPath);
|
|
2470
|
-
(async () => {
|
|
2471
|
-
try {
|
|
2472
|
-
await mkdir(dir, { recursive: true, mode: 448 });
|
|
2473
|
-
await writeFile(machineIdPath, machineId2, { mode: 384 });
|
|
2474
|
-
} catch (error) {
|
|
2475
|
-
console.warn(`[MachineId] Failed to save to ${machineIdPath}: ${error.message}`);
|
|
2476
|
-
}
|
|
2477
|
-
})();
|
|
2478
|
-
}
|
|
2479
|
-
var machineId = (() => {
|
|
2480
|
-
const envMachineId = getEnv2("MACHINE_ID");
|
|
2481
|
-
if (envMachineId) {
|
|
2482
|
-
return envMachineId;
|
|
2483
|
-
}
|
|
2484
|
-
const loadedId = loadMachineIdSync();
|
|
2485
|
-
if (loadedId) {
|
|
2486
|
-
return loadedId;
|
|
2487
|
-
}
|
|
2488
|
-
const newId = randomUUID3();
|
|
2489
|
-
saveMachineIdAsync(newId);
|
|
2490
|
-
return newId;
|
|
2491
|
-
})();
|
|
2492
|
-
var machineIdOverride;
|
|
2493
|
-
function getMachineId() {
|
|
2494
|
-
return machineIdOverride ?? machineId;
|
|
2495
|
-
}
|
|
2496
|
-
function setMachineIdOverride(id) {
|
|
2497
|
-
machineIdOverride = id;
|
|
2498
|
-
}
|
|
2499
|
-
|
|
2500
|
-
// libs/auth/src/session/utils/session-crypto.utils.ts
|
|
2429
|
+
import { decryptValue, encryptValue, getEnv as getEnv2, getMachineId, isProduction as isProduction3, sha256 } from "@frontmcp/utils";
|
|
2501
2430
|
var cachedKey = null;
|
|
2502
2431
|
function getKey() {
|
|
2503
2432
|
if (cachedKey) return cachedKey;
|
|
2504
|
-
const secret =
|
|
2433
|
+
const secret = getEnv2("MCP_SESSION_SECRET");
|
|
2505
2434
|
if (!secret) {
|
|
2506
|
-
if (
|
|
2435
|
+
if (isProduction3()) {
|
|
2507
2436
|
throw new SessionSecretRequiredError("session ID encryption");
|
|
2508
2437
|
}
|
|
2509
2438
|
console.warn(
|
|
@@ -2543,7 +2472,7 @@ import { TypedStorage as TypedStorage3 } from "@frontmcp/utils";
|
|
|
2543
2472
|
import { EncryptedTypedStorage, EncryptedStorageError } from "@frontmcp/utils";
|
|
2544
2473
|
|
|
2545
2474
|
// libs/auth/src/session/storage/storage-token-store.ts
|
|
2546
|
-
import { randomUUID as
|
|
2475
|
+
import { randomUUID as randomUUID3, TypedStorage } from "@frontmcp/utils";
|
|
2547
2476
|
var StorageTokenStore = class {
|
|
2548
2477
|
storage;
|
|
2549
2478
|
namespace;
|
|
@@ -2561,7 +2490,7 @@ var StorageTokenStore = class {
|
|
|
2561
2490
|
* Allocate a new unique ID for a token record.
|
|
2562
2491
|
*/
|
|
2563
2492
|
allocId() {
|
|
2564
|
-
return
|
|
2493
|
+
return randomUUID3();
|
|
2565
2494
|
}
|
|
2566
2495
|
/**
|
|
2567
2496
|
* Store an encrypted token blob.
|
|
@@ -2624,7 +2553,7 @@ var StorageTokenStore = class {
|
|
|
2624
2553
|
};
|
|
2625
2554
|
|
|
2626
2555
|
// libs/auth/src/session/storage/storage-authorization-vault.ts
|
|
2627
|
-
import { randomUUID as
|
|
2556
|
+
import { randomUUID as randomUUID4, TypedStorage as TypedStorage2 } from "@frontmcp/utils";
|
|
2628
2557
|
var StorageAuthorizationVault = class {
|
|
2629
2558
|
storage;
|
|
2630
2559
|
namespace;
|
|
@@ -2644,7 +2573,7 @@ var StorageAuthorizationVault = class {
|
|
|
2644
2573
|
async create(params) {
|
|
2645
2574
|
const now = Date.now();
|
|
2646
2575
|
const entry = {
|
|
2647
|
-
id:
|
|
2576
|
+
id: randomUUID4(),
|
|
2648
2577
|
userSub: params.userSub,
|
|
2649
2578
|
userEmail: params.userEmail,
|
|
2650
2579
|
userName: params.userName,
|
|
@@ -2718,7 +2647,7 @@ var StorageAuthorizationVault = class {
|
|
|
2718
2647
|
}
|
|
2719
2648
|
const now = Date.now();
|
|
2720
2649
|
const pendingAuth = {
|
|
2721
|
-
id:
|
|
2650
|
+
id: randomUUID4(),
|
|
2722
2651
|
appId: params.appId,
|
|
2723
2652
|
toolId: params.toolId,
|
|
2724
2653
|
authUrl: params.authUrl,
|
|
@@ -2947,7 +2876,7 @@ var InMemoryAuthorizationVault = class extends StorageAuthorizationVault {
|
|
|
2947
2876
|
};
|
|
2948
2877
|
|
|
2949
2878
|
// libs/auth/src/session/redis-session.store.ts
|
|
2950
|
-
import { randomUUID as
|
|
2879
|
+
import { randomUUID as randomUUID5, RedisStorageAdapter } from "@frontmcp/utils";
|
|
2951
2880
|
var RedisSessionStore = class {
|
|
2952
2881
|
storage;
|
|
2953
2882
|
keyPrefix;
|
|
@@ -3158,7 +3087,7 @@ var RedisSessionStore = class {
|
|
|
3158
3087
|
* Allocate a new session ID
|
|
3159
3088
|
*/
|
|
3160
3089
|
allocId() {
|
|
3161
|
-
return
|
|
3090
|
+
return randomUUID5();
|
|
3162
3091
|
}
|
|
3163
3092
|
/**
|
|
3164
3093
|
* Disconnect from Redis (only if we created the connection)
|
|
@@ -3194,7 +3123,7 @@ var RedisSessionStore = class {
|
|
|
3194
3123
|
};
|
|
3195
3124
|
|
|
3196
3125
|
// libs/auth/src/session/vercel-kv-session.store.ts
|
|
3197
|
-
import { randomUUID as
|
|
3126
|
+
import { randomUUID as randomUUID6, VercelKvStorageAdapter } from "@frontmcp/utils";
|
|
3198
3127
|
var VercelKvSessionStore = class {
|
|
3199
3128
|
storage;
|
|
3200
3129
|
keyPrefix;
|
|
@@ -3388,7 +3317,7 @@ var VercelKvSessionStore = class {
|
|
|
3388
3317
|
* Allocate a new session ID
|
|
3389
3318
|
*/
|
|
3390
3319
|
allocId() {
|
|
3391
|
-
return
|
|
3320
|
+
return randomUUID6();
|
|
3392
3321
|
}
|
|
3393
3322
|
/**
|
|
3394
3323
|
* Disconnect from Vercel KV
|
|
@@ -3688,7 +3617,7 @@ var InMemoryOrchestratedTokenStore = class {
|
|
|
3688
3617
|
};
|
|
3689
3618
|
|
|
3690
3619
|
// libs/auth/src/session/federated-auth.session.ts
|
|
3691
|
-
import { randomUUID as
|
|
3620
|
+
import { randomUUID as randomUUID7 } from "@frontmcp/utils";
|
|
3692
3621
|
function toSessionRecord(session) {
|
|
3693
3622
|
return {
|
|
3694
3623
|
...session,
|
|
@@ -3763,7 +3692,7 @@ var InMemoryFederatedAuthSessionStore = class {
|
|
|
3763
3692
|
createSession(params) {
|
|
3764
3693
|
const now = Date.now();
|
|
3765
3694
|
return {
|
|
3766
|
-
id:
|
|
3695
|
+
id: randomUUID7(),
|
|
3767
3696
|
pendingAuthId: params.pendingAuthId,
|
|
3768
3697
|
clientId: params.clientId,
|
|
3769
3698
|
redirectUri: params.redirectUri,
|
|
@@ -3795,7 +3724,7 @@ var InMemoryFederatedAuthSessionStore = class {
|
|
|
3795
3724
|
function createFederatedAuthSession(params, ttlMs = 15 * 60 * 1e3) {
|
|
3796
3725
|
const now = Date.now();
|
|
3797
3726
|
return {
|
|
3798
|
-
id:
|
|
3727
|
+
id: randomUUID7(),
|
|
3799
3728
|
pendingAuthId: params.pendingAuthId,
|
|
3800
3729
|
clientId: params.clientId,
|
|
3801
3730
|
redirectUri: params.redirectUri,
|
|
@@ -3852,9 +3781,8 @@ function startNextProvider(session, pkce, state) {
|
|
|
3852
3781
|
}
|
|
3853
3782
|
|
|
3854
3783
|
// libs/auth/src/session/encrypted-authorization-vault.ts
|
|
3855
|
-
import { z as z5 } from "zod";
|
|
3856
|
-
import { randomUUID as
|
|
3857
|
-
import { AsyncLocalStorage } from "@frontmcp/utils";
|
|
3784
|
+
import { z as z5 } from "@frontmcp/lazy-zod";
|
|
3785
|
+
import { AsyncLocalStorage, randomUUID as randomUUID8 } from "@frontmcp/utils";
|
|
3858
3786
|
var redisVaultEntrySchema = z5.object({
|
|
3859
3787
|
/** Vault ID */
|
|
3860
3788
|
id: z5.string(),
|
|
@@ -4012,7 +3940,7 @@ var EncryptedRedisVault = class {
|
|
|
4012
3940
|
async create(params) {
|
|
4013
3941
|
const now = Date.now();
|
|
4014
3942
|
const entry = {
|
|
4015
|
-
id:
|
|
3943
|
+
id: randomUUID8(),
|
|
4016
3944
|
userSub: params.userSub,
|
|
4017
3945
|
userEmail: params.userEmail,
|
|
4018
3946
|
userName: params.userName,
|
|
@@ -4071,7 +3999,7 @@ var EncryptedRedisVault = class {
|
|
|
4071
3999
|
}
|
|
4072
4000
|
const now = Date.now();
|
|
4073
4001
|
const pendingAuth = {
|
|
4074
|
-
id:
|
|
4002
|
+
id: randomUUID8(),
|
|
4075
4003
|
appId: params.appId,
|
|
4076
4004
|
toolId: params.toolId,
|
|
4077
4005
|
authUrl: params.authUrl,
|
|
@@ -4280,7 +4208,7 @@ function tryJwtExp(token) {
|
|
|
4280
4208
|
}
|
|
4281
4209
|
|
|
4282
4210
|
// libs/auth/src/authorization/authorization.types.ts
|
|
4283
|
-
import { z as z6 } from "zod";
|
|
4211
|
+
import { z as z6 } from "@frontmcp/lazy-zod";
|
|
4284
4212
|
var authModeSchema = z6.enum(["public", "transparent", "orchestrated"]);
|
|
4285
4213
|
var authUserSchema = z6.object({
|
|
4286
4214
|
sub: z6.string(),
|
|
@@ -4334,7 +4262,7 @@ var progressiveAuthStateSchema = z6.object({
|
|
|
4334
4262
|
});
|
|
4335
4263
|
|
|
4336
4264
|
// libs/auth/src/authorization/authorization.class.ts
|
|
4337
|
-
import {
|
|
4265
|
+
import { base64urlDecode as base64urlDecode4, getMachineId as getMachineId2, randomUUID as randomUUID9 } from "@frontmcp/utils";
|
|
4338
4266
|
var AuthorizationBase = class _AuthorizationBase {
|
|
4339
4267
|
id;
|
|
4340
4268
|
isAnonymous;
|
|
@@ -4382,14 +4310,14 @@ var AuthorizationBase = class _AuthorizationBase {
|
|
|
4382
4310
|
* @param fingerprint - Optional client fingerprint for tracking
|
|
4383
4311
|
*/
|
|
4384
4312
|
createTransportSession(protocol, fingerprint) {
|
|
4385
|
-
const sessionId =
|
|
4313
|
+
const sessionId = randomUUID9();
|
|
4386
4314
|
const session = {
|
|
4387
4315
|
id: sessionId,
|
|
4388
4316
|
authorizationId: this.id,
|
|
4389
4317
|
protocol,
|
|
4390
4318
|
createdAt: Date.now(),
|
|
4391
4319
|
expiresAt: this.expiresAt,
|
|
4392
|
-
nodeId:
|
|
4320
|
+
nodeId: getMachineId2(),
|
|
4393
4321
|
clientFingerprint: fingerprint
|
|
4394
4322
|
};
|
|
4395
4323
|
this.#sessions.set(session.id, session);
|
|
@@ -4571,7 +4499,7 @@ var AuthorizationBase = class _AuthorizationBase {
|
|
|
4571
4499
|
};
|
|
4572
4500
|
|
|
4573
4501
|
// libs/auth/src/authorization/public.authorization.ts
|
|
4574
|
-
import { randomUUID as
|
|
4502
|
+
import { randomUUID as randomUUID10 } from "@frontmcp/utils";
|
|
4575
4503
|
var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
|
|
4576
4504
|
mode = "public";
|
|
4577
4505
|
/**
|
|
@@ -4607,7 +4535,7 @@ var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
|
|
|
4607
4535
|
allowedTools = "all",
|
|
4608
4536
|
allowedPrompts = "all"
|
|
4609
4537
|
} = ctx;
|
|
4610
|
-
const uuid =
|
|
4538
|
+
const uuid = randomUUID10();
|
|
4611
4539
|
const sub = `${prefix}:${uuid}`;
|
|
4612
4540
|
const user = {
|
|
4613
4541
|
sub,
|
|
@@ -5189,7 +5117,7 @@ var OrchestratedAuthAccessorAdapter = class {
|
|
|
5189
5117
|
};
|
|
5190
5118
|
|
|
5191
5119
|
// libs/auth/src/common/jwt.types.ts
|
|
5192
|
-
import { z as z7 } from "zod";
|
|
5120
|
+
import { z as z7 } from "@frontmcp/lazy-zod";
|
|
5193
5121
|
var jwkParametersSchema = z7.object({
|
|
5194
5122
|
kty: z7.string().optional(),
|
|
5195
5123
|
alg: z7.string().optional(),
|
|
@@ -5223,7 +5151,7 @@ var jsonWebKeySetSchema = z7.object({
|
|
|
5223
5151
|
});
|
|
5224
5152
|
|
|
5225
5153
|
// libs/auth/src/common/session.types.ts
|
|
5226
|
-
import { z as z8 } from "zod";
|
|
5154
|
+
import { z as z8 } from "@frontmcp/lazy-zod";
|
|
5227
5155
|
var aiPlatformTypeSchema = z8.enum([
|
|
5228
5156
|
"openai",
|
|
5229
5157
|
"claude",
|
|
@@ -5273,7 +5201,7 @@ var authorizationSchema = z8.object({
|
|
|
5273
5201
|
});
|
|
5274
5202
|
|
|
5275
5203
|
// libs/auth/src/options/shared.schemas.ts
|
|
5276
|
-
import { z as z10 } from "zod";
|
|
5204
|
+
import { z as z10 } from "@frontmcp/lazy-zod";
|
|
5277
5205
|
|
|
5278
5206
|
// libs/auth/src/cimd/cimd.logger.ts
|
|
5279
5207
|
var noopLogger = {
|
|
@@ -5289,7 +5217,7 @@ var noopLogger = {
|
|
|
5289
5217
|
};
|
|
5290
5218
|
|
|
5291
5219
|
// libs/auth/src/cimd/cimd.types.ts
|
|
5292
|
-
import { z as z9 } from "zod";
|
|
5220
|
+
import { z as z9 } from "@frontmcp/lazy-zod";
|
|
5293
5221
|
var clientMetadataDocumentSchema = z9.object({
|
|
5294
5222
|
// REQUIRED per CIMD spec
|
|
5295
5223
|
/**
|
|
@@ -6381,7 +6309,7 @@ var incrementalAuthConfigSchema = z10.object({
|
|
|
6381
6309
|
});
|
|
6382
6310
|
|
|
6383
6311
|
// libs/auth/src/options/public.schema.ts
|
|
6384
|
-
import { z as z11 } from "zod";
|
|
6312
|
+
import { z as z11 } from "@frontmcp/lazy-zod";
|
|
6385
6313
|
var publicAuthOptionsSchema = z11.object({
|
|
6386
6314
|
mode: z11.literal("public"),
|
|
6387
6315
|
/**
|
|
@@ -6416,7 +6344,7 @@ var publicAuthOptionsSchema = z11.object({
|
|
|
6416
6344
|
});
|
|
6417
6345
|
|
|
6418
6346
|
// libs/auth/src/options/transparent.schema.ts
|
|
6419
|
-
import { z as z12 } from "zod";
|
|
6347
|
+
import { z as z12 } from "@frontmcp/lazy-zod";
|
|
6420
6348
|
var transparentAuthOptionsSchema = z12.object({
|
|
6421
6349
|
mode: z12.literal("transparent"),
|
|
6422
6350
|
/**
|
|
@@ -6451,7 +6379,7 @@ var transparentAuthOptionsSchema = z12.object({
|
|
|
6451
6379
|
});
|
|
6452
6380
|
|
|
6453
6381
|
// libs/auth/src/options/orchestrated.schema.ts
|
|
6454
|
-
import { z as z13 } from "zod";
|
|
6382
|
+
import { z as z13 } from "@frontmcp/lazy-zod";
|
|
6455
6383
|
var sharedAuthFields = {
|
|
6456
6384
|
local: localSigningConfigSchema.optional(),
|
|
6457
6385
|
tokenStorage: tokenStorageConfigSchema.default("memory"),
|
|
@@ -6478,7 +6406,7 @@ var orchestratedLocalSchema = localAuthSchema;
|
|
|
6478
6406
|
var orchestratedRemoteSchema = remoteAuthSchema;
|
|
6479
6407
|
|
|
6480
6408
|
// libs/auth/src/options/schema.ts
|
|
6481
|
-
import { z as z14 } from "zod";
|
|
6409
|
+
import { z as z14 } from "@frontmcp/lazy-zod";
|
|
6482
6410
|
var authOptionsSchema = z14.union([
|
|
6483
6411
|
publicAuthOptionsSchema,
|
|
6484
6412
|
transparentAuthOptionsSchema,
|
|
@@ -6487,7 +6415,7 @@ var authOptionsSchema = z14.union([
|
|
|
6487
6415
|
]);
|
|
6488
6416
|
|
|
6489
6417
|
// libs/auth/src/options/app-auth.schema.ts
|
|
6490
|
-
import { z as z15 } from "zod";
|
|
6418
|
+
import { z as z15 } from "@frontmcp/lazy-zod";
|
|
6491
6419
|
var standaloneOptionSchema = {
|
|
6492
6420
|
standalone: z15.boolean().optional(),
|
|
6493
6421
|
excludeFromParent: z15.boolean().optional()
|
|
@@ -6532,7 +6460,7 @@ function allowsPublicAccess(options) {
|
|
|
6532
6460
|
}
|
|
6533
6461
|
|
|
6534
6462
|
// libs/auth/src/consent/consent.types.ts
|
|
6535
|
-
import { z as z16 } from "zod";
|
|
6463
|
+
import { z as z16 } from "@frontmcp/lazy-zod";
|
|
6536
6464
|
var consentToolItemSchema = z16.object({
|
|
6537
6465
|
/** Tool ID (e.g., 'slack:send_message') */
|
|
6538
6466
|
id: z16.string().min(1),
|
|
@@ -6617,7 +6545,7 @@ var federatedSelectionSchema = z16.object({
|
|
|
6617
6545
|
});
|
|
6618
6546
|
|
|
6619
6547
|
// libs/auth/src/detection/auth-provider-detection.ts
|
|
6620
|
-
import { z as z17 } from "zod";
|
|
6548
|
+
import { z as z17 } from "@frontmcp/lazy-zod";
|
|
6621
6549
|
var detectedAuthProviderSchema = z17.object({
|
|
6622
6550
|
id: z17.string(),
|
|
6623
6551
|
providerUrl: z17.string().optional(),
|
|
@@ -7023,7 +6951,7 @@ var AudienceValidator = class _AudienceValidator {
|
|
|
7023
6951
|
};
|
|
7024
6952
|
|
|
7025
6953
|
// libs/auth/src/vault/auth-providers.types.ts
|
|
7026
|
-
import { z as z18 } from "zod";
|
|
6954
|
+
import { z as z18 } from "@frontmcp/lazy-zod";
|
|
7027
6955
|
var credentialScopeSchema = z18.enum(["global", "user", "session"]);
|
|
7028
6956
|
var loadingStrategySchema = z18.enum(["eager", "lazy"]);
|
|
7029
6957
|
var getCredentialOptionsSchema = z18.object({
|
|
@@ -8024,6 +7952,971 @@ var LazyCredentialLoader = class {
|
|
|
8024
7952
|
this.loading.clear();
|
|
8025
7953
|
}
|
|
8026
7954
|
};
|
|
7955
|
+
|
|
7956
|
+
// libs/auth/src/authorities/authorities.context.ts
|
|
7957
|
+
function resolveDotPath(obj, path) {
|
|
7958
|
+
if (path in obj) {
|
|
7959
|
+
return obj[path];
|
|
7960
|
+
}
|
|
7961
|
+
const segments = path.split(".");
|
|
7962
|
+
let current = obj;
|
|
7963
|
+
for (const segment of segments) {
|
|
7964
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
7965
|
+
return void 0;
|
|
7966
|
+
}
|
|
7967
|
+
current = current[segment];
|
|
7968
|
+
}
|
|
7969
|
+
return current;
|
|
7970
|
+
}
|
|
7971
|
+
function toStringArray(value) {
|
|
7972
|
+
if (Array.isArray(value)) {
|
|
7973
|
+
return value.filter((v) => typeof v === "string");
|
|
7974
|
+
}
|
|
7975
|
+
if (typeof value === "string") {
|
|
7976
|
+
return value.split(/\s+/).filter(Boolean);
|
|
7977
|
+
}
|
|
7978
|
+
return [];
|
|
7979
|
+
}
|
|
7980
|
+
var noopRelationshipResolver = {
|
|
7981
|
+
async check() {
|
|
7982
|
+
return false;
|
|
7983
|
+
}
|
|
7984
|
+
};
|
|
7985
|
+
var AuthoritiesContextBuilder = class {
|
|
7986
|
+
claimsMapping;
|
|
7987
|
+
claimsResolver;
|
|
7988
|
+
relationshipResolver;
|
|
7989
|
+
constructor(options = {}) {
|
|
7990
|
+
this.claimsMapping = options.claimsMapping;
|
|
7991
|
+
this.claimsResolver = options.claimsResolver;
|
|
7992
|
+
this.relationshipResolver = options.relationshipResolver ?? noopRelationshipResolver;
|
|
7993
|
+
}
|
|
7994
|
+
/**
|
|
7995
|
+
* Build an evaluation context from AuthInfo and tool input.
|
|
7996
|
+
*/
|
|
7997
|
+
build(authInfo, input = {}, env = {}) {
|
|
7998
|
+
if (this.claimsResolver) {
|
|
7999
|
+
const resolved = this.claimsResolver(authInfo);
|
|
8000
|
+
return {
|
|
8001
|
+
user: {
|
|
8002
|
+
sub: authInfo?.user?.sub ?? "",
|
|
8003
|
+
roles: resolved.roles,
|
|
8004
|
+
permissions: resolved.permissions,
|
|
8005
|
+
claims: resolved.claims
|
|
8006
|
+
},
|
|
8007
|
+
input,
|
|
8008
|
+
env,
|
|
8009
|
+
relationships: this.relationshipResolver
|
|
8010
|
+
};
|
|
8011
|
+
}
|
|
8012
|
+
const user = authInfo?.user ?? {};
|
|
8013
|
+
const authorization = authInfo?.extra?.["authorization"];
|
|
8014
|
+
const authorizationClaims = authorization?.["claims"] ?? {};
|
|
8015
|
+
const rawClaims = {
|
|
8016
|
+
...authorizationClaims,
|
|
8017
|
+
...user
|
|
8018
|
+
};
|
|
8019
|
+
let roles;
|
|
8020
|
+
if (this.claimsMapping?.roles) {
|
|
8021
|
+
roles = toStringArray(resolveDotPath(rawClaims, this.claimsMapping.roles));
|
|
8022
|
+
} else {
|
|
8023
|
+
roles = toStringArray(
|
|
8024
|
+
user["roles"] ?? authorization?.["scopes"] ?? []
|
|
8025
|
+
);
|
|
8026
|
+
}
|
|
8027
|
+
let permissions;
|
|
8028
|
+
if (this.claimsMapping?.permissions) {
|
|
8029
|
+
permissions = toStringArray(resolveDotPath(rawClaims, this.claimsMapping.permissions));
|
|
8030
|
+
} else {
|
|
8031
|
+
permissions = toStringArray(user["permissions"] ?? []);
|
|
8032
|
+
}
|
|
8033
|
+
const sub = this.claimsMapping?.userId ? String(resolveDotPath(rawClaims, this.claimsMapping.userId) ?? "") : user.sub ?? "";
|
|
8034
|
+
return {
|
|
8035
|
+
user: {
|
|
8036
|
+
sub,
|
|
8037
|
+
roles,
|
|
8038
|
+
permissions,
|
|
8039
|
+
claims: rawClaims
|
|
8040
|
+
},
|
|
8041
|
+
input,
|
|
8042
|
+
env,
|
|
8043
|
+
relationships: this.relationshipResolver
|
|
8044
|
+
};
|
|
8045
|
+
}
|
|
8046
|
+
};
|
|
8047
|
+
|
|
8048
|
+
// libs/auth/src/context/frontmcp-auth-context.impl.ts
|
|
8049
|
+
function toStringArray2(value) {
|
|
8050
|
+
if (Array.isArray(value)) {
|
|
8051
|
+
return value.filter((v) => typeof v === "string");
|
|
8052
|
+
}
|
|
8053
|
+
if (typeof value === "string") {
|
|
8054
|
+
return value.split(/\s+/).filter(Boolean);
|
|
8055
|
+
}
|
|
8056
|
+
return [];
|
|
8057
|
+
}
|
|
8058
|
+
var FrontMcpAuthContextImpl = class {
|
|
8059
|
+
user;
|
|
8060
|
+
isAnonymous;
|
|
8061
|
+
mode;
|
|
8062
|
+
sessionId;
|
|
8063
|
+
scopes;
|
|
8064
|
+
claims;
|
|
8065
|
+
roles;
|
|
8066
|
+
permissions;
|
|
8067
|
+
constructor(source, claimsMapping) {
|
|
8068
|
+
const rawUser = source.user ?? {};
|
|
8069
|
+
const sub = claimsMapping?.userId ? String(resolveDotPath(this.buildRawClaims(source), claimsMapping.userId) ?? rawUser.sub ?? "") : String(rawUser.sub ?? "");
|
|
8070
|
+
this.user = Object.freeze({
|
|
8071
|
+
sub,
|
|
8072
|
+
name: rawUser.name,
|
|
8073
|
+
email: rawUser.email,
|
|
8074
|
+
picture: rawUser.picture
|
|
8075
|
+
});
|
|
8076
|
+
this.isAnonymous = sub === "" || sub.startsWith("anon:");
|
|
8077
|
+
const extraAuth = source.extra?.["authorization"];
|
|
8078
|
+
this.mode = String(
|
|
8079
|
+
source.extra?.["authMode"] ?? extraAuth?.["mode"] ?? (source.extra?.["isPublic"] === true || rawUser["anonymous"] === true ? "public" : "authenticated")
|
|
8080
|
+
);
|
|
8081
|
+
this.sessionId = typeof source.sessionId === "string" ? source.sessionId : "";
|
|
8082
|
+
this.scopes = Object.freeze(
|
|
8083
|
+
Array.isArray(source.scopes) ? source.scopes.filter((s) => typeof s === "string") : []
|
|
8084
|
+
);
|
|
8085
|
+
const rawClaims = this.buildRawClaims(source);
|
|
8086
|
+
this.claims = Object.freeze({ ...rawClaims });
|
|
8087
|
+
if (claimsMapping?.roles) {
|
|
8088
|
+
this.roles = Object.freeze([...toStringArray2(resolveDotPath(rawClaims, claimsMapping.roles))]);
|
|
8089
|
+
} else {
|
|
8090
|
+
this.roles = Object.freeze([
|
|
8091
|
+
...toStringArray2(rawUser["roles"] ?? extraAuth?.["scopes"] ?? [])
|
|
8092
|
+
]);
|
|
8093
|
+
}
|
|
8094
|
+
if (claimsMapping?.permissions) {
|
|
8095
|
+
this.permissions = Object.freeze([...toStringArray2(resolveDotPath(rawClaims, claimsMapping.permissions))]);
|
|
8096
|
+
} else {
|
|
8097
|
+
this.permissions = Object.freeze([...toStringArray2(rawUser["permissions"] ?? [])]);
|
|
8098
|
+
}
|
|
8099
|
+
}
|
|
8100
|
+
// -- Query methods -------------------------------------------------
|
|
8101
|
+
hasRole(role) {
|
|
8102
|
+
return this.roles.includes(role);
|
|
8103
|
+
}
|
|
8104
|
+
hasAllRoles(roles) {
|
|
8105
|
+
return roles.every((r) => this.roles.includes(r));
|
|
8106
|
+
}
|
|
8107
|
+
hasAnyRole(roles) {
|
|
8108
|
+
return roles.some((r) => this.roles.includes(r));
|
|
8109
|
+
}
|
|
8110
|
+
hasPermission(permission) {
|
|
8111
|
+
return this.permissions.includes(permission);
|
|
8112
|
+
}
|
|
8113
|
+
hasAllPermissions(permissions) {
|
|
8114
|
+
return permissions.every((p) => this.permissions.includes(p));
|
|
8115
|
+
}
|
|
8116
|
+
hasAnyPermission(permissions) {
|
|
8117
|
+
return permissions.some((p) => this.permissions.includes(p));
|
|
8118
|
+
}
|
|
8119
|
+
hasScope(scope) {
|
|
8120
|
+
return this.scopes.includes(scope);
|
|
8121
|
+
}
|
|
8122
|
+
hasAllScopes(scopes) {
|
|
8123
|
+
return scopes.every((s) => this.scopes.includes(s));
|
|
8124
|
+
}
|
|
8125
|
+
hasAnyScope(scopes) {
|
|
8126
|
+
return scopes.some((s) => this.scopes.includes(s));
|
|
8127
|
+
}
|
|
8128
|
+
// -- Internal helpers ----------------------------------------------
|
|
8129
|
+
/**
|
|
8130
|
+
* Build the merged raw claims map from user fields + extra.authorization.claims.
|
|
8131
|
+
* Mirrors the logic in AuthoritiesContextBuilder.build().
|
|
8132
|
+
*/
|
|
8133
|
+
buildRawClaims(source) {
|
|
8134
|
+
const rawUser = source.user ?? {};
|
|
8135
|
+
const extraAuth = source.extra?.["authorization"];
|
|
8136
|
+
const authorizationClaims = extraAuth?.["claims"] ?? {};
|
|
8137
|
+
return {
|
|
8138
|
+
...authorizationClaims,
|
|
8139
|
+
...rawUser
|
|
8140
|
+
};
|
|
8141
|
+
}
|
|
8142
|
+
};
|
|
8143
|
+
|
|
8144
|
+
// libs/auth/src/context/frontmcp-auth-context.factory.ts
|
|
8145
|
+
function buildAuthContext(authInfo, claimsMapping, pipes) {
|
|
8146
|
+
const base = new FrontMcpAuthContextImpl(authInfo, claimsMapping);
|
|
8147
|
+
if (!pipes || pipes.length === 0) {
|
|
8148
|
+
return base;
|
|
8149
|
+
}
|
|
8150
|
+
return runPipes(base, pipes);
|
|
8151
|
+
}
|
|
8152
|
+
async function runPipes(base, pipes) {
|
|
8153
|
+
const extensions = {};
|
|
8154
|
+
for (const pipe of pipes) {
|
|
8155
|
+
try {
|
|
8156
|
+
const result = await pipe(base.claims);
|
|
8157
|
+
if (result && typeof result === "object") {
|
|
8158
|
+
Object.assign(extensions, result);
|
|
8159
|
+
}
|
|
8160
|
+
} catch (error) {
|
|
8161
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8162
|
+
console.warn(`[FrontMcpAuth] pipe failed: ${message}`);
|
|
8163
|
+
}
|
|
8164
|
+
}
|
|
8165
|
+
const merged = Object.create(Object.getPrototypeOf(base));
|
|
8166
|
+
Object.assign(merged, base, extensions);
|
|
8167
|
+
return Object.freeze(merged);
|
|
8168
|
+
}
|
|
8169
|
+
|
|
8170
|
+
// libs/auth/src/authorities/authorities.scope-mapping.ts
|
|
8171
|
+
function resolveRequiredScopes(denial, mapping, authorities) {
|
|
8172
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
8173
|
+
if (typeof authorities === "string" && mapping.profiles?.[authorities]) {
|
|
8174
|
+
mapping.profiles[authorities].forEach((s) => scopes.add(s));
|
|
8175
|
+
}
|
|
8176
|
+
if (Array.isArray(authorities)) {
|
|
8177
|
+
for (const profileName of authorities) {
|
|
8178
|
+
if (typeof profileName === "string" && mapping.profiles?.[profileName]) {
|
|
8179
|
+
mapping.profiles[profileName].forEach((s) => scopes.add(s));
|
|
8180
|
+
}
|
|
8181
|
+
}
|
|
8182
|
+
}
|
|
8183
|
+
if (denial.kind === "roles" && denial.missing && mapping.roles) {
|
|
8184
|
+
for (const role of denial.missing) {
|
|
8185
|
+
const mapped = mapping.roles[role];
|
|
8186
|
+
if (mapped) mapped.forEach((s) => scopes.add(s));
|
|
8187
|
+
}
|
|
8188
|
+
}
|
|
8189
|
+
if (denial.kind === "permissions" && denial.missing && mapping.permissions) {
|
|
8190
|
+
for (const perm of denial.missing) {
|
|
8191
|
+
const mapped = mapping.permissions[perm];
|
|
8192
|
+
if (mapped) mapped.forEach((s) => scopes.add(s));
|
|
8193
|
+
}
|
|
8194
|
+
}
|
|
8195
|
+
return scopes.size > 0 ? [...scopes].sort() : void 0;
|
|
8196
|
+
}
|
|
8197
|
+
|
|
8198
|
+
// libs/auth/src/authorities/authorities.schema.ts
|
|
8199
|
+
import { z as z19 } from "@frontmcp/lazy-zod";
|
|
8200
|
+
var rbacRolesPolicySchema = z19.object({
|
|
8201
|
+
all: z19.array(z19.string().min(1)).optional(),
|
|
8202
|
+
any: z19.array(z19.string().min(1)).optional()
|
|
8203
|
+
}).refine((data) => data.all !== void 0 || data.any !== void 0, {
|
|
8204
|
+
message: 'Roles policy must have at least "all" or "any"'
|
|
8205
|
+
});
|
|
8206
|
+
var rbacPermissionsPolicySchema = z19.object({
|
|
8207
|
+
all: z19.array(z19.string().min(1)).optional(),
|
|
8208
|
+
any: z19.array(z19.string().min(1)).optional()
|
|
8209
|
+
}).refine((data) => data.all !== void 0 || data.any !== void 0, {
|
|
8210
|
+
message: 'Permissions policy must have at least "all" or "any"'
|
|
8211
|
+
});
|
|
8212
|
+
var abacOperatorSchema = z19.enum([
|
|
8213
|
+
"eq",
|
|
8214
|
+
"neq",
|
|
8215
|
+
"in",
|
|
8216
|
+
"notIn",
|
|
8217
|
+
"gt",
|
|
8218
|
+
"gte",
|
|
8219
|
+
"lt",
|
|
8220
|
+
"lte",
|
|
8221
|
+
"contains",
|
|
8222
|
+
"startsWith",
|
|
8223
|
+
"endsWith",
|
|
8224
|
+
"exists",
|
|
8225
|
+
"matches"
|
|
8226
|
+
]);
|
|
8227
|
+
var abacConditionSchema = z19.object({
|
|
8228
|
+
path: z19.string().min(1),
|
|
8229
|
+
op: abacOperatorSchema,
|
|
8230
|
+
value: z19.unknown()
|
|
8231
|
+
});
|
|
8232
|
+
var abacPolicySchema = z19.object({
|
|
8233
|
+
match: z19.record(z19.string(), z19.unknown()).optional(),
|
|
8234
|
+
conditions: z19.array(abacConditionSchema).optional()
|
|
8235
|
+
}).refine((data) => data.match !== void 0 || data.conditions !== void 0, {
|
|
8236
|
+
message: 'Attributes policy must have at least "match" or "conditions"'
|
|
8237
|
+
});
|
|
8238
|
+
var resourceIdRefSchema = z19.union([
|
|
8239
|
+
z19.string().min(1),
|
|
8240
|
+
z19.object({ fromInput: z19.string().min(1) }).strict(),
|
|
8241
|
+
z19.object({ fromClaims: z19.string().min(1) }).strict()
|
|
8242
|
+
]);
|
|
8243
|
+
var rebacPolicySchema = z19.object({
|
|
8244
|
+
type: z19.string().min(1),
|
|
8245
|
+
resource: z19.string().min(1),
|
|
8246
|
+
resourceId: resourceIdRefSchema
|
|
8247
|
+
});
|
|
8248
|
+
var basePolicyShape = {
|
|
8249
|
+
roles: rbacRolesPolicySchema.optional(),
|
|
8250
|
+
permissions: rbacPermissionsPolicySchema.optional(),
|
|
8251
|
+
attributes: abacPolicySchema.optional(),
|
|
8252
|
+
relationships: z19.union([rebacPolicySchema, z19.array(rebacPolicySchema)]).optional(),
|
|
8253
|
+
custom: z19.record(z19.string(), z19.unknown()).optional(),
|
|
8254
|
+
guards: z19.array(z19.instanceof(Function)).optional(),
|
|
8255
|
+
operator: z19.enum(["AND", "OR"]).optional()
|
|
8256
|
+
};
|
|
8257
|
+
var authoritiesPolicySchema = z19.lazy(
|
|
8258
|
+
() => z19.object({
|
|
8259
|
+
...basePolicyShape,
|
|
8260
|
+
not: authoritiesPolicySchema.optional(),
|
|
8261
|
+
anyOf: z19.array(authoritiesPolicySchema).optional(),
|
|
8262
|
+
allOf: z19.array(authoritiesPolicySchema).optional()
|
|
8263
|
+
})
|
|
8264
|
+
);
|
|
8265
|
+
var authoritiesMetadataSchema = z19.union([
|
|
8266
|
+
z19.string().min(1),
|
|
8267
|
+
z19.array(z19.string().min(1)).min(1),
|
|
8268
|
+
authoritiesPolicySchema
|
|
8269
|
+
]);
|
|
8270
|
+
var authoritiesClaimsMappingSchema = z19.record(z19.string(), z19.string().optional()).refine((data) => Object.values(data).some((v) => v !== void 0), {
|
|
8271
|
+
message: "Claims mapping must have at least one mapping"
|
|
8272
|
+
});
|
|
8273
|
+
var authoritiesConfigSchema = z19.object({
|
|
8274
|
+
claimsMapping: authoritiesClaimsMappingSchema.optional(),
|
|
8275
|
+
profiles: z19.record(z19.string().min(1), authoritiesPolicySchema).optional()
|
|
8276
|
+
});
|
|
8277
|
+
|
|
8278
|
+
// libs/auth/src/authorities/authorities.evaluator.ts
|
|
8279
|
+
function evaluateRbacRoles(policy, ctx) {
|
|
8280
|
+
const userRoles = ctx.user.roles;
|
|
8281
|
+
if (policy.all) {
|
|
8282
|
+
const missing = policy.all.filter((r) => !userRoles.includes(r));
|
|
8283
|
+
if (missing.length > 0) {
|
|
8284
|
+
return {
|
|
8285
|
+
granted: false,
|
|
8286
|
+
deniedBy: `roles.all: missing ${missing.map((r) => `'${r}'`).join(", ")}`,
|
|
8287
|
+
denial: { kind: "roles", path: "roles.all", missing },
|
|
8288
|
+
evaluatedPolicies: ["roles.all"]
|
|
8289
|
+
};
|
|
8290
|
+
}
|
|
8291
|
+
}
|
|
8292
|
+
if (policy.any) {
|
|
8293
|
+
const hasAny = policy.any.some((r) => userRoles.includes(r));
|
|
8294
|
+
if (!hasAny) {
|
|
8295
|
+
return {
|
|
8296
|
+
granted: false,
|
|
8297
|
+
deniedBy: `roles.any: user has none of ${policy.any.map((r) => `'${r}'`).join(", ")}`,
|
|
8298
|
+
denial: { kind: "roles", path: "roles.any", missing: policy.any },
|
|
8299
|
+
evaluatedPolicies: ["roles.any"]
|
|
8300
|
+
};
|
|
8301
|
+
}
|
|
8302
|
+
}
|
|
8303
|
+
return { granted: true, evaluatedPolicies: ["roles"] };
|
|
8304
|
+
}
|
|
8305
|
+
function evaluateRbacPermissions(policy, ctx) {
|
|
8306
|
+
const userPerms = ctx.user.permissions;
|
|
8307
|
+
if (policy.all) {
|
|
8308
|
+
const missing = policy.all.filter((p) => !userPerms.includes(p));
|
|
8309
|
+
if (missing.length > 0) {
|
|
8310
|
+
return {
|
|
8311
|
+
granted: false,
|
|
8312
|
+
deniedBy: `permissions.all: missing ${missing.map((p) => `'${p}'`).join(", ")}`,
|
|
8313
|
+
denial: { kind: "permissions", path: "permissions.all", missing },
|
|
8314
|
+
evaluatedPolicies: ["permissions.all"]
|
|
8315
|
+
};
|
|
8316
|
+
}
|
|
8317
|
+
}
|
|
8318
|
+
if (policy.any) {
|
|
8319
|
+
const hasAny = policy.any.some((p) => userPerms.includes(p));
|
|
8320
|
+
if (!hasAny) {
|
|
8321
|
+
return {
|
|
8322
|
+
granted: false,
|
|
8323
|
+
deniedBy: `permissions.any: user has none of ${policy.any.map((p) => `'${p}'`).join(", ")}`,
|
|
8324
|
+
denial: { kind: "permissions", path: "permissions.any", missing: policy.any },
|
|
8325
|
+
evaluatedPolicies: ["permissions.any"]
|
|
8326
|
+
};
|
|
8327
|
+
}
|
|
8328
|
+
}
|
|
8329
|
+
return { granted: true, evaluatedPolicies: ["permissions"] };
|
|
8330
|
+
}
|
|
8331
|
+
function buildContextEnvelope(ctx) {
|
|
8332
|
+
return {
|
|
8333
|
+
user: ctx.user,
|
|
8334
|
+
claims: ctx.user.claims,
|
|
8335
|
+
input: ctx.input,
|
|
8336
|
+
env: ctx.env
|
|
8337
|
+
};
|
|
8338
|
+
}
|
|
8339
|
+
function resolveValue(value, ctx) {
|
|
8340
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
8341
|
+
const obj = value;
|
|
8342
|
+
if ("fromInput" in obj && typeof obj["fromInput"] === "string") {
|
|
8343
|
+
return ctx.input[obj["fromInput"]];
|
|
8344
|
+
}
|
|
8345
|
+
if ("fromClaims" in obj && typeof obj["fromClaims"] === "string") {
|
|
8346
|
+
return resolveDotPath(ctx.user.claims, obj["fromClaims"]);
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8349
|
+
return value;
|
|
8350
|
+
}
|
|
8351
|
+
function applyOperator(actual, op, expected) {
|
|
8352
|
+
switch (op) {
|
|
8353
|
+
case "eq":
|
|
8354
|
+
return actual === expected;
|
|
8355
|
+
case "neq":
|
|
8356
|
+
return actual !== expected;
|
|
8357
|
+
case "in":
|
|
8358
|
+
return Array.isArray(expected) && expected.includes(actual);
|
|
8359
|
+
case "notIn":
|
|
8360
|
+
return Array.isArray(expected) && !expected.includes(actual);
|
|
8361
|
+
case "gt":
|
|
8362
|
+
return typeof actual === "number" && typeof expected === "number" && actual > expected;
|
|
8363
|
+
case "gte":
|
|
8364
|
+
return typeof actual === "number" && typeof expected === "number" && actual >= expected;
|
|
8365
|
+
case "lt":
|
|
8366
|
+
return typeof actual === "number" && typeof expected === "number" && actual < expected;
|
|
8367
|
+
case "lte":
|
|
8368
|
+
return typeof actual === "number" && typeof expected === "number" && actual <= expected;
|
|
8369
|
+
case "contains":
|
|
8370
|
+
if (typeof actual === "string" && typeof expected === "string") return actual.includes(expected);
|
|
8371
|
+
if (Array.isArray(actual)) return actual.includes(expected);
|
|
8372
|
+
return false;
|
|
8373
|
+
case "startsWith":
|
|
8374
|
+
return typeof actual === "string" && typeof expected === "string" && actual.startsWith(expected);
|
|
8375
|
+
case "endsWith":
|
|
8376
|
+
return typeof actual === "string" && typeof expected === "string" && actual.endsWith(expected);
|
|
8377
|
+
case "exists":
|
|
8378
|
+
return expected ? actual !== void 0 && actual !== null : actual === void 0 || actual === null;
|
|
8379
|
+
case "matches":
|
|
8380
|
+
if (typeof actual !== "string" || typeof expected !== "string") return false;
|
|
8381
|
+
if (expected.length > 256) return false;
|
|
8382
|
+
if (/(\+\+|\*\*|\{\d+,\d*\}\{)/.test(expected)) return false;
|
|
8383
|
+
try {
|
|
8384
|
+
return new RegExp(expected).test(actual);
|
|
8385
|
+
} catch {
|
|
8386
|
+
return false;
|
|
8387
|
+
}
|
|
8388
|
+
default:
|
|
8389
|
+
return false;
|
|
8390
|
+
}
|
|
8391
|
+
}
|
|
8392
|
+
function evaluateCondition(condition, envelope, ctx) {
|
|
8393
|
+
const actual = resolveDotPath(envelope, condition.path);
|
|
8394
|
+
const expected = resolveValue(condition.value, ctx);
|
|
8395
|
+
return applyOperator(actual, condition.op, expected);
|
|
8396
|
+
}
|
|
8397
|
+
function evaluateAbac(policy, ctx) {
|
|
8398
|
+
const envelope = buildContextEnvelope(ctx);
|
|
8399
|
+
if (policy.match) {
|
|
8400
|
+
for (const [path, expectedRaw] of Object.entries(policy.match)) {
|
|
8401
|
+
const actual = resolveDotPath(envelope, path);
|
|
8402
|
+
const expected = resolveValue(expectedRaw, ctx);
|
|
8403
|
+
if (actual !== expected) {
|
|
8404
|
+
return {
|
|
8405
|
+
granted: false,
|
|
8406
|
+
deniedBy: `attributes.match: '${path}' expected '${String(expected)}' but got '${String(actual)}'`,
|
|
8407
|
+
denial: { kind: "attributes", path: "attributes.match", expected, actual },
|
|
8408
|
+
evaluatedPolicies: ["attributes.match"]
|
|
8409
|
+
};
|
|
8410
|
+
}
|
|
8411
|
+
}
|
|
8412
|
+
}
|
|
8413
|
+
if (policy.conditions) {
|
|
8414
|
+
for (let i = 0; i < policy.conditions.length; i++) {
|
|
8415
|
+
const condition = policy.conditions[i];
|
|
8416
|
+
if (!evaluateCondition(condition, envelope, ctx)) {
|
|
8417
|
+
const expected = resolveValue(condition.value, ctx);
|
|
8418
|
+
const actual = resolveDotPath(envelope, condition.path);
|
|
8419
|
+
return {
|
|
8420
|
+
granted: false,
|
|
8421
|
+
deniedBy: `attributes.conditions: '${condition.path}' failed '${condition.op}' check against '${String(expected)}'`,
|
|
8422
|
+
denial: { kind: "attributes", path: `attributes.conditions[${i}]`, expected, actual },
|
|
8423
|
+
evaluatedPolicies: ["attributes.conditions"]
|
|
8424
|
+
};
|
|
8425
|
+
}
|
|
8426
|
+
}
|
|
8427
|
+
}
|
|
8428
|
+
return { granted: true, evaluatedPolicies: ["attributes"] };
|
|
8429
|
+
}
|
|
8430
|
+
function resolveResourceId(ref, ctx) {
|
|
8431
|
+
if (typeof ref === "string") return ref;
|
|
8432
|
+
if ("fromInput" in ref) {
|
|
8433
|
+
const val = ctx.input[ref.fromInput];
|
|
8434
|
+
return typeof val === "string" ? val : void 0;
|
|
8435
|
+
}
|
|
8436
|
+
if ("fromClaims" in ref) {
|
|
8437
|
+
const val = resolveDotPath(ctx.user.claims, ref.fromClaims);
|
|
8438
|
+
return typeof val === "string" ? val : void 0;
|
|
8439
|
+
}
|
|
8440
|
+
return void 0;
|
|
8441
|
+
}
|
|
8442
|
+
async function evaluateSingleRebac(policy, ctx) {
|
|
8443
|
+
const resourceId = resolveResourceId(policy.resourceId, ctx);
|
|
8444
|
+
if (resourceId === void 0) {
|
|
8445
|
+
return {
|
|
8446
|
+
granted: false,
|
|
8447
|
+
deniedBy: `relationships: could not resolve resourceId for ${policy.resource}`,
|
|
8448
|
+
denial: {
|
|
8449
|
+
kind: "relationships",
|
|
8450
|
+
path: "relationships",
|
|
8451
|
+
expected: `${policy.resource}:resourceId`,
|
|
8452
|
+
actual: void 0
|
|
8453
|
+
},
|
|
8454
|
+
evaluatedPolicies: ["relationships"]
|
|
8455
|
+
};
|
|
8456
|
+
}
|
|
8457
|
+
const hasRelationship = await ctx.relationships.check(policy.type, policy.resource, resourceId, ctx.user.sub, ctx);
|
|
8458
|
+
if (!hasRelationship) {
|
|
8459
|
+
return {
|
|
8460
|
+
granted: false,
|
|
8461
|
+
deniedBy: `relationships: user '${ctx.user.sub}' is not '${policy.type}' of ${policy.resource}:${resourceId}`,
|
|
8462
|
+
denial: {
|
|
8463
|
+
kind: "relationships",
|
|
8464
|
+
path: "relationships",
|
|
8465
|
+
expected: `${policy.type}:${policy.resource}:${resourceId}`
|
|
8466
|
+
},
|
|
8467
|
+
evaluatedPolicies: ["relationships"]
|
|
8468
|
+
};
|
|
8469
|
+
}
|
|
8470
|
+
return { granted: true, evaluatedPolicies: ["relationships"] };
|
|
8471
|
+
}
|
|
8472
|
+
async function evaluateRebac(policy, ctx) {
|
|
8473
|
+
const policies = Array.isArray(policy) ? policy : [policy];
|
|
8474
|
+
for (const p of policies) {
|
|
8475
|
+
const result = await evaluateSingleRebac(p, ctx);
|
|
8476
|
+
if (!result.granted) return result;
|
|
8477
|
+
}
|
|
8478
|
+
return { granted: true, evaluatedPolicies: ["relationships"] };
|
|
8479
|
+
}
|
|
8480
|
+
|
|
8481
|
+
// libs/auth/src/authorities/authorities.engine.ts
|
|
8482
|
+
function mergeResult(base, ...others) {
|
|
8483
|
+
const evaluatedPolicies = [...base.evaluatedPolicies];
|
|
8484
|
+
for (const other of others) {
|
|
8485
|
+
evaluatedPolicies.push(...other.evaluatedPolicies);
|
|
8486
|
+
}
|
|
8487
|
+
return { ...base, evaluatedPolicies };
|
|
8488
|
+
}
|
|
8489
|
+
function granted(policies) {
|
|
8490
|
+
return { granted: true, evaluatedPolicies: policies };
|
|
8491
|
+
}
|
|
8492
|
+
var AuthoritiesEngine = class {
|
|
8493
|
+
constructor(profiles, evaluators) {
|
|
8494
|
+
this.profiles = profiles;
|
|
8495
|
+
this.evaluators = evaluators;
|
|
8496
|
+
}
|
|
8497
|
+
/**
|
|
8498
|
+
* Evaluate an AuthoritiesMetadata value (string, string[], or policy object).
|
|
8499
|
+
*/
|
|
8500
|
+
async evaluate(authorities, ctx) {
|
|
8501
|
+
if (typeof authorities === "string") {
|
|
8502
|
+
return this.evaluateProfile(authorities, ctx);
|
|
8503
|
+
}
|
|
8504
|
+
if (Array.isArray(authorities)) {
|
|
8505
|
+
return this.evaluateProfileArray(authorities, ctx);
|
|
8506
|
+
}
|
|
8507
|
+
return this.evaluatePolicy(authorities, ctx);
|
|
8508
|
+
}
|
|
8509
|
+
/**
|
|
8510
|
+
* Resolve and evaluate a single named profile.
|
|
8511
|
+
*/
|
|
8512
|
+
async evaluateProfile(name, ctx) {
|
|
8513
|
+
const policy = this.profiles.resolve(name);
|
|
8514
|
+
if (!policy) {
|
|
8515
|
+
return {
|
|
8516
|
+
granted: false,
|
|
8517
|
+
deniedBy: `profile '${name}' is not registered`,
|
|
8518
|
+
evaluatedPolicies: [`profile:${name}`]
|
|
8519
|
+
};
|
|
8520
|
+
}
|
|
8521
|
+
const result = await this.evaluatePolicy(policy, ctx);
|
|
8522
|
+
if (!result.granted) {
|
|
8523
|
+
return {
|
|
8524
|
+
...result,
|
|
8525
|
+
deniedBy: `profile:${name}: ${result.deniedBy}`,
|
|
8526
|
+
evaluatedPolicies: [`profile:${name}`, ...result.evaluatedPolicies]
|
|
8527
|
+
};
|
|
8528
|
+
}
|
|
8529
|
+
return mergeResult(result, { granted: true, evaluatedPolicies: [`profile:${name}`] });
|
|
8530
|
+
}
|
|
8531
|
+
/**
|
|
8532
|
+
* Evaluate an array of profile names (AND semantics).
|
|
8533
|
+
*/
|
|
8534
|
+
async evaluateProfileArray(names, ctx) {
|
|
8535
|
+
const allPolicies = [];
|
|
8536
|
+
for (const name of names) {
|
|
8537
|
+
const result = await this.evaluateProfile(name, ctx);
|
|
8538
|
+
allPolicies.push(...result.evaluatedPolicies);
|
|
8539
|
+
if (!result.granted) {
|
|
8540
|
+
return { ...result, evaluatedPolicies: allPolicies };
|
|
8541
|
+
}
|
|
8542
|
+
}
|
|
8543
|
+
return { granted: true, evaluatedPolicies: allPolicies };
|
|
8544
|
+
}
|
|
8545
|
+
/**
|
|
8546
|
+
* Evaluate an inline policy object.
|
|
8547
|
+
*/
|
|
8548
|
+
async evaluatePolicy(policy, ctx) {
|
|
8549
|
+
const operator = policy.operator ?? "AND";
|
|
8550
|
+
const results = [];
|
|
8551
|
+
if (policy.roles) {
|
|
8552
|
+
results.push(evaluateRbacRoles(policy.roles, ctx));
|
|
8553
|
+
}
|
|
8554
|
+
if (policy.permissions) {
|
|
8555
|
+
results.push(evaluateRbacPermissions(policy.permissions, ctx));
|
|
8556
|
+
}
|
|
8557
|
+
if (policy.attributes) {
|
|
8558
|
+
results.push(evaluateAbac(policy.attributes, ctx));
|
|
8559
|
+
}
|
|
8560
|
+
if (policy.relationships) {
|
|
8561
|
+
results.push(await evaluateRebac(policy.relationships, ctx));
|
|
8562
|
+
}
|
|
8563
|
+
if (policy.custom) {
|
|
8564
|
+
results.push(await this.evaluateCustom(policy.custom, ctx));
|
|
8565
|
+
}
|
|
8566
|
+
if (policy.guards && policy.guards.length > 0) {
|
|
8567
|
+
results.push(await this.evaluateGuards(policy.guards, ctx));
|
|
8568
|
+
}
|
|
8569
|
+
if (policy.allOf) {
|
|
8570
|
+
results.push(await this.evaluateAllOf(policy.allOf, ctx));
|
|
8571
|
+
}
|
|
8572
|
+
if (policy.anyOf) {
|
|
8573
|
+
results.push(await this.evaluateAnyOf(policy.anyOf, ctx));
|
|
8574
|
+
}
|
|
8575
|
+
if (policy.not) {
|
|
8576
|
+
results.push(await this.evaluateNot(policy.not, ctx));
|
|
8577
|
+
}
|
|
8578
|
+
if (results.length === 0) {
|
|
8579
|
+
return granted([]);
|
|
8580
|
+
}
|
|
8581
|
+
return this.combineResults(results, operator);
|
|
8582
|
+
}
|
|
8583
|
+
/**
|
|
8584
|
+
* Combine results with AND or OR semantics.
|
|
8585
|
+
*/
|
|
8586
|
+
combineResults(results, operator) {
|
|
8587
|
+
const allPolicies = results.flatMap((r) => r.evaluatedPolicies);
|
|
8588
|
+
if (operator === "AND") {
|
|
8589
|
+
const denied = results.find((r) => !r.granted);
|
|
8590
|
+
if (denied) {
|
|
8591
|
+
return { ...denied, evaluatedPolicies: allPolicies };
|
|
8592
|
+
}
|
|
8593
|
+
return { granted: true, evaluatedPolicies: allPolicies };
|
|
8594
|
+
}
|
|
8595
|
+
const anyGranted = results.some((r) => r.granted);
|
|
8596
|
+
if (anyGranted) {
|
|
8597
|
+
return { granted: true, evaluatedPolicies: allPolicies };
|
|
8598
|
+
}
|
|
8599
|
+
const firstDenied = results.find((r) => !r.granted);
|
|
8600
|
+
return {
|
|
8601
|
+
granted: false,
|
|
8602
|
+
deniedBy: firstDenied?.deniedBy ?? "all policies denied (OR)",
|
|
8603
|
+
evaluatedPolicies: allPolicies
|
|
8604
|
+
};
|
|
8605
|
+
}
|
|
8606
|
+
/**
|
|
8607
|
+
* Evaluate custom evaluators.
|
|
8608
|
+
*/
|
|
8609
|
+
async evaluateCustom(custom, ctx) {
|
|
8610
|
+
const allPolicies = [];
|
|
8611
|
+
for (const [name, config] of Object.entries(custom)) {
|
|
8612
|
+
const evaluator = this.evaluators.get(name);
|
|
8613
|
+
if (!evaluator) {
|
|
8614
|
+
return {
|
|
8615
|
+
granted: false,
|
|
8616
|
+
deniedBy: `custom evaluator '${name}' is not registered`,
|
|
8617
|
+
evaluatedPolicies: [...allPolicies, `custom.${name}`]
|
|
8618
|
+
};
|
|
8619
|
+
}
|
|
8620
|
+
const result = await evaluator.evaluate(config, ctx);
|
|
8621
|
+
allPolicies.push(`custom.${name}`, ...result.evaluatedPolicies);
|
|
8622
|
+
if (!result.granted) {
|
|
8623
|
+
return { ...result, evaluatedPolicies: allPolicies };
|
|
8624
|
+
}
|
|
8625
|
+
}
|
|
8626
|
+
return { granted: true, evaluatedPolicies: allPolicies };
|
|
8627
|
+
}
|
|
8628
|
+
/**
|
|
8629
|
+
* Evaluate async guard functions in sequence.
|
|
8630
|
+
* Each guard returns true (granted) or a string (denial message).
|
|
8631
|
+
*/
|
|
8632
|
+
async evaluateGuards(guards, ctx) {
|
|
8633
|
+
for (let i = 0; i < guards.length; i++) {
|
|
8634
|
+
const guard = guards[i];
|
|
8635
|
+
const result = await guard(ctx);
|
|
8636
|
+
if (result === false || typeof result === "string") {
|
|
8637
|
+
const denialMessage = typeof result === "string" ? result : `guard[${i}] denied`;
|
|
8638
|
+
return {
|
|
8639
|
+
granted: false,
|
|
8640
|
+
deniedBy: `guards[${i}]: ${denialMessage}`,
|
|
8641
|
+
denial: { kind: "custom", path: `guards[${i}]` },
|
|
8642
|
+
evaluatedPolicies: ["guards"]
|
|
8643
|
+
};
|
|
8644
|
+
}
|
|
8645
|
+
}
|
|
8646
|
+
return { granted: true, evaluatedPolicies: ["guards"] };
|
|
8647
|
+
}
|
|
8648
|
+
/**
|
|
8649
|
+
* allOf combinator — all nested policies must pass.
|
|
8650
|
+
*/
|
|
8651
|
+
async evaluateAllOf(policies, ctx) {
|
|
8652
|
+
const allPolicies = ["allOf"];
|
|
8653
|
+
for (const policy of policies) {
|
|
8654
|
+
const result = await this.evaluatePolicy(policy, ctx);
|
|
8655
|
+
allPolicies.push(...result.evaluatedPolicies);
|
|
8656
|
+
if (!result.granted) {
|
|
8657
|
+
return { ...result, evaluatedPolicies: allPolicies };
|
|
8658
|
+
}
|
|
8659
|
+
}
|
|
8660
|
+
return { granted: true, evaluatedPolicies: allPolicies };
|
|
8661
|
+
}
|
|
8662
|
+
/**
|
|
8663
|
+
* anyOf combinator — at least one nested policy must pass.
|
|
8664
|
+
*/
|
|
8665
|
+
async evaluateAnyOf(policies, ctx) {
|
|
8666
|
+
const allPolicies = ["anyOf"];
|
|
8667
|
+
let lastDenied;
|
|
8668
|
+
for (const policy of policies) {
|
|
8669
|
+
const result = await this.evaluatePolicy(policy, ctx);
|
|
8670
|
+
allPolicies.push(...result.evaluatedPolicies);
|
|
8671
|
+
if (result.granted) {
|
|
8672
|
+
return { granted: true, evaluatedPolicies: allPolicies };
|
|
8673
|
+
}
|
|
8674
|
+
lastDenied = result;
|
|
8675
|
+
}
|
|
8676
|
+
return {
|
|
8677
|
+
granted: false,
|
|
8678
|
+
deniedBy: lastDenied?.deniedBy ?? "no policies in anyOf",
|
|
8679
|
+
denial: lastDenied?.denial ?? { kind: "anyOf", path: "anyOf" },
|
|
8680
|
+
evaluatedPolicies: allPolicies
|
|
8681
|
+
};
|
|
8682
|
+
}
|
|
8683
|
+
/**
|
|
8684
|
+
* not combinator — inverts the nested policy result.
|
|
8685
|
+
*/
|
|
8686
|
+
async evaluateNot(policy, ctx) {
|
|
8687
|
+
const result = await this.evaluatePolicy(policy, ctx);
|
|
8688
|
+
return {
|
|
8689
|
+
granted: !result.granted,
|
|
8690
|
+
deniedBy: result.granted ? "not: inner policy was granted (negated to denied)" : void 0,
|
|
8691
|
+
denial: result.granted ? { kind: "not", path: "not" } : void 0,
|
|
8692
|
+
evaluatedPolicies: ["not", ...result.evaluatedPolicies]
|
|
8693
|
+
};
|
|
8694
|
+
}
|
|
8695
|
+
};
|
|
8696
|
+
|
|
8697
|
+
// libs/auth/src/authorities/authorities.registry.ts
|
|
8698
|
+
var AuthoritiesProfileRegistry = class {
|
|
8699
|
+
profiles = /* @__PURE__ */ new Map();
|
|
8700
|
+
/**
|
|
8701
|
+
* Register a named profile.
|
|
8702
|
+
* Overwrites any existing profile with the same name.
|
|
8703
|
+
*/
|
|
8704
|
+
register(name, policy) {
|
|
8705
|
+
this.profiles.set(name, policy);
|
|
8706
|
+
}
|
|
8707
|
+
/**
|
|
8708
|
+
* Register multiple profiles at once.
|
|
8709
|
+
*/
|
|
8710
|
+
registerAll(profiles) {
|
|
8711
|
+
for (const [name, policy] of Object.entries(profiles)) {
|
|
8712
|
+
this.profiles.set(name, policy);
|
|
8713
|
+
}
|
|
8714
|
+
}
|
|
8715
|
+
/**
|
|
8716
|
+
* Resolve a profile name to its policy.
|
|
8717
|
+
* Returns `undefined` if the profile is not registered.
|
|
8718
|
+
*/
|
|
8719
|
+
resolve(name) {
|
|
8720
|
+
return this.profiles.get(name);
|
|
8721
|
+
}
|
|
8722
|
+
/**
|
|
8723
|
+
* Check if a profile is registered.
|
|
8724
|
+
*/
|
|
8725
|
+
has(name) {
|
|
8726
|
+
return this.profiles.has(name);
|
|
8727
|
+
}
|
|
8728
|
+
/**
|
|
8729
|
+
* Get all registered profiles.
|
|
8730
|
+
*/
|
|
8731
|
+
getAll() {
|
|
8732
|
+
const result = {};
|
|
8733
|
+
for (const [name, policy] of this.profiles) {
|
|
8734
|
+
result[name] = policy;
|
|
8735
|
+
}
|
|
8736
|
+
return result;
|
|
8737
|
+
}
|
|
8738
|
+
/**
|
|
8739
|
+
* Get the number of registered profiles.
|
|
8740
|
+
*/
|
|
8741
|
+
get size() {
|
|
8742
|
+
return this.profiles.size;
|
|
8743
|
+
}
|
|
8744
|
+
/**
|
|
8745
|
+
* Remove a profile by name.
|
|
8746
|
+
*/
|
|
8747
|
+
remove(name) {
|
|
8748
|
+
return this.profiles.delete(name);
|
|
8749
|
+
}
|
|
8750
|
+
/**
|
|
8751
|
+
* Clear all profiles.
|
|
8752
|
+
*/
|
|
8753
|
+
clear() {
|
|
8754
|
+
this.profiles.clear();
|
|
8755
|
+
}
|
|
8756
|
+
};
|
|
8757
|
+
var AuthoritiesEvaluatorRegistry = class {
|
|
8758
|
+
evaluators = /* @__PURE__ */ new Map();
|
|
8759
|
+
/**
|
|
8760
|
+
* Register a custom evaluator.
|
|
8761
|
+
* The evaluator's name must match the key used in `custom.*`.
|
|
8762
|
+
*/
|
|
8763
|
+
register(name, evaluator) {
|
|
8764
|
+
this.evaluators.set(name, evaluator);
|
|
8765
|
+
}
|
|
8766
|
+
/**
|
|
8767
|
+
* Register multiple evaluators at once.
|
|
8768
|
+
*/
|
|
8769
|
+
registerAll(evaluators) {
|
|
8770
|
+
for (const [name, evaluator] of Object.entries(evaluators)) {
|
|
8771
|
+
this.evaluators.set(name, evaluator);
|
|
8772
|
+
}
|
|
8773
|
+
}
|
|
8774
|
+
/**
|
|
8775
|
+
* Get an evaluator by name.
|
|
8776
|
+
*/
|
|
8777
|
+
get(name) {
|
|
8778
|
+
return this.evaluators.get(name);
|
|
8779
|
+
}
|
|
8780
|
+
/**
|
|
8781
|
+
* Check if an evaluator is registered.
|
|
8782
|
+
*/
|
|
8783
|
+
has(name) {
|
|
8784
|
+
return this.evaluators.has(name);
|
|
8785
|
+
}
|
|
8786
|
+
/**
|
|
8787
|
+
* Get the number of registered evaluators.
|
|
8788
|
+
*/
|
|
8789
|
+
get size() {
|
|
8790
|
+
return this.evaluators.size;
|
|
8791
|
+
}
|
|
8792
|
+
/**
|
|
8793
|
+
* Remove an evaluator by name.
|
|
8794
|
+
*/
|
|
8795
|
+
remove(name) {
|
|
8796
|
+
return this.evaluators.delete(name);
|
|
8797
|
+
}
|
|
8798
|
+
/**
|
|
8799
|
+
* Clear all evaluators.
|
|
8800
|
+
*/
|
|
8801
|
+
clear() {
|
|
8802
|
+
this.evaluators.clear();
|
|
8803
|
+
}
|
|
8804
|
+
};
|
|
8805
|
+
|
|
8806
|
+
// libs/auth/src/authorities/authorities.errors.ts
|
|
8807
|
+
var FORBIDDEN_CODE = -32003;
|
|
8808
|
+
var AuthorityDeniedError = class extends Error {
|
|
8809
|
+
/** MCP error code for JSON-RPC responses */
|
|
8810
|
+
mcpErrorCode = FORBIDDEN_CODE;
|
|
8811
|
+
/** HTTP status code equivalent */
|
|
8812
|
+
statusCode = 403;
|
|
8813
|
+
/** Error classification code */
|
|
8814
|
+
code = "AUTHORITY_DENIED";
|
|
8815
|
+
/** Entry type that was denied */
|
|
8816
|
+
entryType;
|
|
8817
|
+
/** Entry name that was denied */
|
|
8818
|
+
entryName;
|
|
8819
|
+
/** Policy that caused the denial */
|
|
8820
|
+
deniedBy;
|
|
8821
|
+
/** Structured denial data (machine-parsable) */
|
|
8822
|
+
denial;
|
|
8823
|
+
/** Required scopes for scope challenges */
|
|
8824
|
+
requiredScopes;
|
|
8825
|
+
constructor(params) {
|
|
8826
|
+
const msg = params.message ?? `Access denied to ${params.entryType} "${params.entryName}": ${params.deniedBy}`;
|
|
8827
|
+
super(msg);
|
|
8828
|
+
this.name = "AuthorityDeniedError";
|
|
8829
|
+
this.entryType = params.entryType;
|
|
8830
|
+
this.entryName = params.entryName;
|
|
8831
|
+
this.deniedBy = params.deniedBy;
|
|
8832
|
+
this.denial = params.denial;
|
|
8833
|
+
this.requiredScopes = params.requiredScopes;
|
|
8834
|
+
}
|
|
8835
|
+
/**
|
|
8836
|
+
* Convert to JSON-RPC error format.
|
|
8837
|
+
*/
|
|
8838
|
+
toJsonRpcError() {
|
|
8839
|
+
const data = {
|
|
8840
|
+
entryType: this.entryType,
|
|
8841
|
+
entryName: this.entryName,
|
|
8842
|
+
deniedBy: this.deniedBy
|
|
8843
|
+
};
|
|
8844
|
+
if (this.denial !== void 0) data["denial"] = this.denial;
|
|
8845
|
+
if (this.requiredScopes !== void 0) data["requiredScopes"] = this.requiredScopes;
|
|
8846
|
+
return {
|
|
8847
|
+
code: this.mcpErrorCode,
|
|
8848
|
+
message: this.message,
|
|
8849
|
+
data
|
|
8850
|
+
};
|
|
8851
|
+
}
|
|
8852
|
+
};
|
|
8853
|
+
|
|
8854
|
+
// libs/auth/src/fetch/fetch-credential-middleware.ts
|
|
8855
|
+
var bearerApplier = {
|
|
8856
|
+
apply(token, _url, init) {
|
|
8857
|
+
const headers = new Headers(init.headers);
|
|
8858
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
8859
|
+
return { init: { ...init, headers } };
|
|
8860
|
+
}
|
|
8861
|
+
};
|
|
8862
|
+
function headerApplier(headerName, prefix) {
|
|
8863
|
+
return {
|
|
8864
|
+
apply(token, _url, init) {
|
|
8865
|
+
const headers = new Headers(init.headers);
|
|
8866
|
+
headers.set(headerName, prefix ? `${prefix} ${token}` : token);
|
|
8867
|
+
return { init: { ...init, headers } };
|
|
8868
|
+
}
|
|
8869
|
+
};
|
|
8870
|
+
}
|
|
8871
|
+
function queryApplier(paramName) {
|
|
8872
|
+
return {
|
|
8873
|
+
apply(token, url, init) {
|
|
8874
|
+
const urlObj = new URL(url);
|
|
8875
|
+
urlObj.searchParams.set(paramName, token);
|
|
8876
|
+
return { init, url: urlObj.toString() };
|
|
8877
|
+
}
|
|
8878
|
+
};
|
|
8879
|
+
}
|
|
8880
|
+
var basicApplier = {
|
|
8881
|
+
apply(token, _url, init) {
|
|
8882
|
+
const headers = new Headers(init.headers);
|
|
8883
|
+
const encoded = typeof btoa === "function" ? btoa(token) : Buffer.from(token).toString("base64");
|
|
8884
|
+
headers.set("Authorization", `Basic ${encoded}`);
|
|
8885
|
+
return { init: { ...init, headers } };
|
|
8886
|
+
}
|
|
8887
|
+
};
|
|
8888
|
+
function isFrontMcpCredentials(creds) {
|
|
8889
|
+
return typeof creds === "object" && creds !== null && "provider" in creds && typeof creds.provider === "string" && creds.provider.length > 0;
|
|
8890
|
+
}
|
|
8891
|
+
var FetchCredentialMiddleware = class {
|
|
8892
|
+
constructor(tokenAccessor, appliers) {
|
|
8893
|
+
this.tokenAccessor = tokenAccessor;
|
|
8894
|
+
this.appliers = new Map(Object.entries(appliers ?? {}));
|
|
8895
|
+
}
|
|
8896
|
+
appliers;
|
|
8897
|
+
/**
|
|
8898
|
+
* Inspect the `credentials` field. If it references a named provider,
|
|
8899
|
+
* resolve the token and delegate to the provider's applier.
|
|
8900
|
+
*/
|
|
8901
|
+
async applyCredentials(url, init) {
|
|
8902
|
+
const creds = init.credentials;
|
|
8903
|
+
if (!creds || typeof creds === "string") {
|
|
8904
|
+
return { init };
|
|
8905
|
+
}
|
|
8906
|
+
if (!isFrontMcpCredentials(creds)) {
|
|
8907
|
+
const { credentials: _removed2, ...rest } = init;
|
|
8908
|
+
return { init: rest };
|
|
8909
|
+
}
|
|
8910
|
+
const token = await this.tokenAccessor.getToken(creds.provider);
|
|
8911
|
+
if (!token) {
|
|
8912
|
+
const { credentials: _removed2, ...rest } = init;
|
|
8913
|
+
return { init: rest };
|
|
8914
|
+
}
|
|
8915
|
+
const applier = this.appliers.get(creds.provider) ?? bearerApplier;
|
|
8916
|
+
const { credentials: _removed, ...cleanInit } = init;
|
|
8917
|
+
return applier.apply(token, url, cleanInit);
|
|
8918
|
+
}
|
|
8919
|
+
};
|
|
8027
8920
|
export {
|
|
8028
8921
|
AUTH_PROVIDERS_ACCESSOR,
|
|
8029
8922
|
AUTH_PROVIDERS_REGISTRY,
|
|
@@ -8036,6 +8929,11 @@ export {
|
|
|
8036
8929
|
AuthProvidersNotConfiguredError,
|
|
8037
8930
|
AuthProvidersRegistry,
|
|
8038
8931
|
AuthProvidersVault,
|
|
8932
|
+
AuthoritiesContextBuilder,
|
|
8933
|
+
AuthoritiesEngine,
|
|
8934
|
+
AuthoritiesEvaluatorRegistry,
|
|
8935
|
+
AuthoritiesProfileRegistry,
|
|
8936
|
+
AuthorityDeniedError,
|
|
8039
8937
|
AuthorizationBase,
|
|
8040
8938
|
CDN,
|
|
8041
8939
|
CimdClientIdMismatchError,
|
|
@@ -8057,6 +8955,8 @@ export {
|
|
|
8057
8955
|
EncryptedTypedStorage,
|
|
8058
8956
|
EncryptionContextNotSetError,
|
|
8059
8957
|
EncryptionKeyNotConfiguredError,
|
|
8958
|
+
FetchCredentialMiddleware,
|
|
8959
|
+
FrontMcpAuthContextImpl,
|
|
8060
8960
|
InMemoryAuthorizationStore,
|
|
8061
8961
|
InMemoryAuthorizationVault,
|
|
8062
8962
|
InMemoryCimdCache,
|
|
@@ -8095,6 +8995,9 @@ export {
|
|
|
8095
8995
|
VaultLoadError,
|
|
8096
8996
|
VaultNotFoundError,
|
|
8097
8997
|
VercelKvSessionStore,
|
|
8998
|
+
abacConditionSchema,
|
|
8999
|
+
abacOperatorSchema,
|
|
9000
|
+
abacPolicySchema,
|
|
8098
9001
|
aiPlatformTypeSchema,
|
|
8099
9002
|
allowsPublicAccess,
|
|
8100
9003
|
apiKeyCredentialSchema,
|
|
@@ -8110,13 +9013,20 @@ export {
|
|
|
8110
9013
|
authProviderMappingSchema,
|
|
8111
9014
|
authProvidersVaultOptionsSchema,
|
|
8112
9015
|
authUserSchema,
|
|
9016
|
+
authoritiesClaimsMappingSchema,
|
|
9017
|
+
authoritiesConfigSchema,
|
|
9018
|
+
authoritiesMetadataSchema,
|
|
9019
|
+
authoritiesPolicySchema,
|
|
8113
9020
|
authorizationCodeRecordSchema,
|
|
8114
9021
|
authorizationVaultEntrySchema,
|
|
8115
9022
|
authorizedPromptSchema,
|
|
8116
9023
|
authorizedToolSchema,
|
|
8117
9024
|
baseLayout,
|
|
9025
|
+
basicApplier,
|
|
8118
9026
|
basicAuthCredentialSchema,
|
|
9027
|
+
bearerApplier,
|
|
8119
9028
|
bearerCredentialSchema,
|
|
9029
|
+
buildAuthContext,
|
|
8120
9030
|
buildConsentPage,
|
|
8121
9031
|
buildErrorPage,
|
|
8122
9032
|
buildFederatedLoginPage,
|
|
@@ -8181,15 +9091,16 @@ export {
|
|
|
8181
9091
|
generatePkceChallenge,
|
|
8182
9092
|
getCredentialOptionsSchema,
|
|
8183
9093
|
getKey,
|
|
8184
|
-
getMachineId,
|
|
8185
9094
|
getNextProvider,
|
|
8186
9095
|
getProviderApps,
|
|
8187
9096
|
getProviderScopes,
|
|
8188
9097
|
getTokenSignatureFingerprint,
|
|
8189
9098
|
hasOnlyLocalhostRedirectUris,
|
|
9099
|
+
headerApplier,
|
|
8190
9100
|
hkdfSha2563 as hkdfSha256,
|
|
8191
9101
|
incrementalAuthConfigSchema,
|
|
8192
9102
|
isCimdClientId,
|
|
9103
|
+
isFrontMcpCredentials,
|
|
8193
9104
|
isJwt,
|
|
8194
9105
|
isLocalMode,
|
|
8195
9106
|
isOrchestratedLocal,
|
|
@@ -8227,17 +9138,22 @@ export {
|
|
|
8227
9138
|
providerConfigSchema,
|
|
8228
9139
|
publicAccessConfigSchema,
|
|
8229
9140
|
publicAuthOptionsSchema,
|
|
9141
|
+
queryApplier,
|
|
9142
|
+
rbacPermissionsPolicySchema,
|
|
9143
|
+
rbacRolesPolicySchema,
|
|
9144
|
+
rebacPolicySchema,
|
|
8230
9145
|
redisConfigSchema,
|
|
8231
9146
|
redisVaultEntrySchema,
|
|
8232
9147
|
remoteAuthSchema,
|
|
8233
9148
|
remoteProviderConfigSchema,
|
|
8234
9149
|
renderToHtml,
|
|
8235
9150
|
resetCachedKey,
|
|
9151
|
+
resolveRequiredScopes,
|
|
9152
|
+
resourceIdRefSchema,
|
|
8236
9153
|
safeDecrypt,
|
|
8237
9154
|
serviceAccountCredentialSchema,
|
|
8238
9155
|
sessionIdPayloadSchema,
|
|
8239
9156
|
sessionJwtPayloadSchema,
|
|
8240
|
-
setMachineIdOverride,
|
|
8241
9157
|
signSession,
|
|
8242
9158
|
skippedAppBehaviorSchema,
|
|
8243
9159
|
sseTransportStateSchema,
|