@burdenoff/be-sdk 2026.803.1 → 2026.803.3
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/dist/{chunk-YH6PCW6L.js → chunk-G27GXB7D.js} +12 -4
- package/dist/chunk-G27GXB7D.js.map +1 -0
- package/dist/{chunk-S32JOMMW.js → chunk-N3YN6ZII.js} +16 -4
- package/dist/chunk-N3YN6ZII.js.map +1 -0
- package/dist/{chunk-KUM4N4CO.js → chunk-RJK4MPDW.js} +147 -20
- package/dist/chunk-RJK4MPDW.js.map +1 -0
- package/dist/{chunk-VOJROV6C.js → chunk-VDYBUTFI.js} +3 -3
- package/dist/{chunk-VOJROV6C.js.map → chunk-VDYBUTFI.js.map} +1 -1
- package/dist/{chunk-GTX65XAP.js → chunk-WW6P2S6L.js} +28 -2
- package/dist/chunk-WW6P2S6L.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/init/index.js +3 -2
- package/dist/instrumentation/index.js +1 -1
- package/dist/rbac/index.d.ts +1 -0
- package/dist/rbac/index.js +1 -1
- package/dist/resource-caps/index.d.ts +18 -3
- package/dist/resource-caps/index.js +2 -1
- package/dist/server/index.js +50 -5
- package/dist/server/index.js.map +1 -1
- package/dist/telemetry/index.js +2 -2
- package/dist/tracker/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-GTX65XAP.js.map +0 -1
- package/dist/chunk-KUM4N4CO.js.map +0 -1
- package/dist/chunk-S32JOMMW.js.map +0 -1
- package/dist/chunk-YH6PCW6L.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { configureResourceCaps } from './chunk-
|
|
1
|
+
import { configureResourceCaps } from './chunk-RJK4MPDW.js';
|
|
2
|
+
import { createCounter } from './chunk-Q6UAOZFZ.js';
|
|
2
3
|
import { GatewayClient } from './chunk-ZVZ4RAIH.js';
|
|
3
4
|
import { LayerManager } from './chunk-7UJXIX4I.js';
|
|
4
5
|
import { logger } from './chunk-CBZNP6RF.js';
|
|
@@ -26,6 +27,7 @@ async function initializeBurdenoffSDK(config) {
|
|
|
26
27
|
const { layerManager, gatewayClient } = await initializeLayer(config);
|
|
27
28
|
if (gatewayClient && config.layer) {
|
|
28
29
|
const layerType = config.layer.type;
|
|
30
|
+
const fallbackCounter = createCounter("resource_caps.clientless_fallback_total", "Total number of times resource caps fell back because no billing source was configured at bootstrap");
|
|
29
31
|
configureResourceCaps({
|
|
30
32
|
transport: /* @__PURE__ */ __name(async (query, variables) => {
|
|
31
33
|
const options = {
|
|
@@ -37,7 +39,13 @@ async function initializeBurdenoffSDK(config) {
|
|
|
37
39
|
};
|
|
38
40
|
const response = layerType === "global" ? await gatewayClient.internalQuery(options) : await gatewayClient.crossLayerQuery(options);
|
|
39
41
|
return response?.data ?? null;
|
|
40
|
-
}, "transport")
|
|
42
|
+
}, "transport"),
|
|
43
|
+
// Emitting a dedicated clientless-fallback counter at bootstrap means
|
|
44
|
+
// a service that somehow starts without a billing transport is
|
|
45
|
+
// immediately visible in metrics (BOFF-4809). The resource-caps module
|
|
46
|
+
// itself also emits `resource_caps.plan_resolution_total`, but that
|
|
47
|
+
// only fires on the first cap check; this counter fires at bootstrap.
|
|
48
|
+
onFallback: /* @__PURE__ */ __name(() => fallbackCounter.inc(), "onFallback")
|
|
41
49
|
});
|
|
42
50
|
logger.info("[SDK Init] Resource caps wired to billing", {
|
|
43
51
|
layer: layerType
|
|
@@ -259,5 +267,5 @@ async function initializeLayerStreams(config) {
|
|
|
259
267
|
__name(initializeLayerStreams, "initializeLayerStreams");
|
|
260
268
|
|
|
261
269
|
export { getSDKState, init_exports, initializeBurdenoffSDK, isSDKInitialized, resetSDK };
|
|
262
|
-
//# sourceMappingURL=chunk-
|
|
263
|
-
//# sourceMappingURL=chunk-
|
|
270
|
+
//# sourceMappingURL=chunk-G27GXB7D.js.map
|
|
271
|
+
//# sourceMappingURL=chunk-G27GXB7D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/init/index.ts"],"names":["sdkState","isInitialized","initializeBurdenoffSDK","config","logger","warn","info","startTime","Date","now","initializeLogging","layerManager","gatewayClient","initializeLayer","layer","layerType","type","fallbackCounter","createCounter","configureResourceCaps","transport","query","variables","options","timeout","skipRetry","skipCircuitBreaker","response","internalQuery","crossLayerQuery","data","onFallback","inc","prisma","initializeDatabase","valkey","initializeCache","eventPublisher","initializeEventQueue","autoCreateStreams","initializeLayerStreams","graphSync","initializeGraphSync","clickhouse","initializeAnalytics","initializeObservability","graphSyncEnabled","graph","enabled","analyticsEnabled","analytics","observabilityEnabled","observability","metrics","layerAwareEnabled","duration","initializedState","serviceName","error","getSDKState","Error","isSDKInitialized","resetSDK","loggingConfig","logging","isDevelopment","app","nodeEnv","level","setLevel","console","setConsoleEnabled","format","database","url","maxConnections","enableQueryLogging","undefined","cacheConfig","cache","defaultTTL","_config","process","env","EventQueueFactory","publisher","createPublisherFromEnv","connect","message","String","note","eventsEnabled","productSource","streamName","syncInterval","batchSize","requestTimeout","openTelemetry","port","endpoint","samplingRate","LayerManager","serviceIdentity","GatewayClient","internalGatewayUrl","getInternalGatewayUrl","crossLayerGatewayUrl","getCrossLayerGatewayUrl","debug"],"mappings":"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","file":"chunk-G27GXB7D.js","sourcesContent":["/**\n * Burdenoff SDK Initialization Module\n *\n * Provides a unified initialization function for all state services\n * including database, cache, analytics, event queue, and graph sync.\n *\n * @module init\n * @category Initialization\n */\n\nimport { logger } from '../logger/index.js';\nimport { LayerManager } from '../layer/index.js';\nimport { GatewayClient } from '../gateway/index.js';\nimport { configureResourceCaps } from '../resource-caps/index.js';\nimport { createCounter } from '../instrumentation/metrics-collector.js';\nimport type { BurdenoffSDKInitConfig, InitializedSDKState } from './types.js';\n\n/**\n * Global SDK state\n */\nlet sdkState: InitializedSDKState | null = null;\nlet isInitialized = false;\n\n/**\n * Initialize Burdenoff SDK with unified configuration\n *\n * This function initializes all configured state services in the correct order:\n * 1. Logging configuration\n * 2. Database (Prisma with PostgreSQL)\n * 3. Cache (Valkey)\n * 4. Event Queue (Redis Streams)\n * 5. Graph Sync (Redis Streams-based — Apache AGE writes happen inside wspace-graph-svc)\n * 6. Analytics (ClickHouse)\n * 7. Observability (Metrics, OpenTelemetry)\n *\n * @param config - SDK initialization configuration\n * @returns Initialized SDK state\n *\n * @example\n * ```typescript\n * import { initializeBurdenoffSDK } from '@burdenoff/be-sdk/init';\n *\n * const state = await initializeBurdenoffSDK({\n * database: {\n * url: process.env.DATABASE_URL!,\n * maxConnections: 20,\n * },\n * graph: {\n * enabled: true,\n * eventsEnabled: true,\n * },\n * cache: {\n * valkey: {\n * url: process.env.VALKEY_URL!,\n * },\n * },\n * });\n * ```\n */\nexport async function initializeBurdenoffSDK(config: BurdenoffSDKInitConfig): Promise<InitializedSDKState> {\n if (isInitialized && sdkState) {\n logger.warn('[SDK Init] SDK already initialized, returning existing state');\n return sdkState;\n }\n\n logger.info('[SDK Init] Starting SDK initialization...');\n const startTime = Date.now();\n\n try {\n // 1. Configure logging\n await initializeLogging(config);\n\n // 2. Initialize layer manager (if configured)\n const { layerManager, gatewayClient } = await initializeLayer(config);\n\n // 2b. Wire resource caps to billing so plan-based limits actually apply.\n // `userBillingPlan` lives in the GLOBAL layer: global services reach it\n // on their own internal gateway; wspace services go cross-layer via the\n // public global gateway (service JWT). Without this, every resource cap\n // silently collapses to the free-tier fallback regardless of the\n // customer's plan (BOFF-4805). Primes the process-wide singleton so all\n // existing `getResourceCaps()` call sites resolve real plans unchanged.\n if (gatewayClient && config.layer) {\n const layerType = config.layer.type;\n const fallbackCounter = createCounter(\n 'resource_caps.clientless_fallback_total',\n 'Total number of times resource caps fell back because no billing source was configured at bootstrap'\n );\n configureResourceCaps({\n transport: async (query, variables) => {\n // Cap checks run on entity-create paths and ALWAYS fall back to the\n // configured billing-failure tier on failure, so a billing outage\n // must degrade fast rather than stall writes. Bound the lookup with a\n // short timeout and no retries instead of the gateway defaults\n // (~30s × 3 ≈ 90s). Results are cached 60s, so healthy lookups rarely\n // hit the gateway anyway. `skipCircuitBreaker` keeps this best-effort\n // probe OUT of the shared gateway circuit: its failures already\n // degrade to the fallback here, so they must not count toward opening\n // the internal/cross-layer circuit and fail-fast unrelated M2M calls\n // during a billing outage.\n const options = { query, variables, timeout: 8000, skipRetry: true, skipCircuitBreaker: true };\n const response =\n layerType === 'global'\n ? await gatewayClient.internalQuery(options)\n : await gatewayClient.crossLayerQuery(options);\n return response?.data ?? null;\n },\n // Emitting a dedicated clientless-fallback counter at bootstrap means\n // a service that somehow starts without a billing transport is\n // immediately visible in metrics (BOFF-4809). The resource-caps module\n // itself also emits `resource_caps.plan_resolution_total`, but that\n // only fires on the first cap check; this counter fires at bootstrap.\n onFallback: () => fallbackCounter.inc(),\n });\n logger.info('[SDK Init] Resource caps wired to billing', { layer: layerType });\n } else {\n logger.warn('[SDK Init] No layer/gateway configured — resource caps will use free-tier fallbacks (BOFF-4805)');\n }\n\n // 3. Initialize database (required)\n const prisma = await initializeDatabase(config);\n\n // 4. Initialize cache (optional)\n const valkey = await initializeCache(config);\n\n // 5. Initialize event queue (optional) — Redis Streams via REDIS_URL\n const eventPublisher = await initializeEventQueue(config);\n\n // 6. Initialize layer streams (if layer configured)\n if (config.layer?.autoCreateStreams !== false && config.layer) {\n await initializeLayerStreams(config);\n }\n\n // 7. Initialize graph sync (optional) — publisher emits to Redis Streams,\n // never opens a graph-DB connection\n const graphSync = await initializeGraphSync(config);\n\n // 8. Initialize analytics (optional)\n const clickhouse = await initializeAnalytics(config);\n\n // 9. Initialize observability (optional)\n await initializeObservability(config);\n\n // Create SDK state\n // graphSync is a publisher-side placeholder; services emit Redis Streams\n // events and wspace-graph-svc owns the sole Apache AGE connection.\n void graphSync;\n sdkState = {\n prisma,\n valkey,\n clickhouse,\n eventPublisher,\n layerManager,\n gatewayClient,\n graphSyncEnabled: config.graph?.enabled ?? false,\n analyticsEnabled: !!config.analytics?.clickhouse,\n observabilityEnabled: config.observability?.metrics?.enabled ?? false,\n layerAwareEnabled: !!config.layer,\n };\n\n isInitialized = true;\n\n const duration = Date.now() - startTime;\n // sdkState is guaranteed non-null here since we just assigned it above\n const initializedState = sdkState;\n logger.info(`[SDK Init] SDK initialized successfully in ${duration}ms`, {\n graphSyncEnabled: initializedState.graphSyncEnabled,\n analyticsEnabled: initializedState.analyticsEnabled,\n observabilityEnabled: initializedState.observabilityEnabled,\n layerAwareEnabled: initializedState.layerAwareEnabled,\n layer: config.layer?.type,\n serviceName: config.layer?.serviceName,\n });\n\n return initializedState;\n } catch (error) {\n logger.error('[SDK Init] Failed to initialize SDK:', error);\n throw error;\n }\n}\n\n/**\n * Get current SDK state\n * @throws Error if SDK is not initialized\n */\nexport function getSDKState(): InitializedSDKState {\n if (!isInitialized || !sdkState) {\n throw new Error('SDK not initialized. Call initializeBurdenoffSDK() first.');\n }\n return sdkState;\n}\n\n/**\n * Check if SDK is initialized\n */\nexport function isSDKInitialized(): boolean {\n return isInitialized;\n}\n\n/**\n * Reset SDK state (useful for testing)\n */\nexport async function resetSDK(): Promise<void> {\n logger.info('[SDK Init] Resetting SDK state...');\n\n if (sdkState) {\n // Cleanup resources\n // Note: Individual cleanup will be handled by service-specific shutdown handlers\n sdkState = null;\n }\n\n isInitialized = false;\n logger.info('[SDK Init] SDK state reset');\n}\n\n/**\n * Initialize logging configuration\n */\nasync function initializeLogging(config: BurdenoffSDKInitConfig): Promise<void> {\n logger.info('[SDK Init] Configuring logging...');\n\n const loggingConfig = config.logging ?? {};\n const isDevelopment = config.app?.nodeEnv === 'development';\n\n // Set log level\n const level = loggingConfig.level ?? 'info';\n logger.setLevel(level);\n\n // Set console logging\n const console = loggingConfig.console ?? true;\n logger.setConsoleEnabled(console);\n\n logger.info('[SDK Init] Logging configured', {\n level,\n console,\n format: loggingConfig.format ?? (isDevelopment ? 'pretty' : 'json'),\n });\n}\n\n/**\n * Initialize database (Prisma with PostgreSQL)\n */\nasync function initializeDatabase(config: BurdenoffSDKInitConfig): Promise<unknown> {\n logger.info('[SDK Init] Initializing database...');\n\n // Note: Database initialization is handled by createPrismaClient in prisma/client.ts\n // This is called by the application (e.g., workspaces-backend)\n // We just validate the config here\n if (!config.database?.url) {\n throw new Error('Database URL is required');\n }\n\n logger.info('[SDK Init] Database configuration validated', {\n maxConnections: config.database.maxConnections ?? 20,\n enableQueryLogging: config.database.enableQueryLogging ?? false,\n });\n\n // Return undefined as database client is created separately\n return undefined;\n}\n\n/**\n * Initialize cache (Valkey)\n */\nasync function initializeCache(config: BurdenoffSDKInitConfig): Promise<unknown> {\n const cacheConfig = config.cache?.valkey;\n\n if (!cacheConfig) {\n logger.info('[SDK Init] Cache not configured, skipping');\n return undefined;\n }\n\n logger.info('[SDK Init] Initializing Valkey cache...');\n\n // Note: Valkey initialization is handled by cache module\n // This is a placeholder for future implementation\n logger.info('[SDK Init] Valkey cache configuration validated', {\n url: cacheConfig.url ? '***' : undefined,\n defaultTTL: cacheConfig.defaultTTL ?? 3600,\n });\n\n return undefined;\n}\n\n/**\n * Initialize event queue (Redis Streams).\n *\n * NATS was retired on 2026-05-16. The publisher is created from\n * `REDIS_URL` (set platform-wide in KV). Legacy `config.eventQueue.nats`\n * values are ignored — kept on the type only as a back-compat shim.\n */\nasync function initializeEventQueue(_config: BurdenoffSDKInitConfig): Promise<unknown> {\n if (!process.env['REDIS_URL']) {\n logger.info('[SDK Init] REDIS_URL not set, skipping event queue init');\n return undefined;\n }\n\n try {\n const { EventQueueFactory } = await import('../event-queue/factory/EventQueueFactory.js');\n const publisher = EventQueueFactory.createPublisherFromEnv();\n await publisher.connect();\n\n logger.info('[SDK Init] Redis Streams event publisher connected');\n\n return publisher;\n } catch (error) {\n logger.warn('[SDK Init] Failed to connect Redis Streams event publisher (non-fatal)', {\n error: error instanceof Error ? error.message : String(error),\n note: 'Service will continue without event publishing. Use direct API calls as fallback.',\n });\n return undefined;\n }\n}\n\n/**\n * Initialize graph sync (Redis Streams publisher side).\n *\n * Services publish entity events to Redis Streams; the `wspace-graph-svc`\n * consumer (and only it) persists them into Apache AGE via Azure PG\n * sidecar. This SDK function does no DB work — it just validates that the\n * publisher-side config is sensible and logs it.\n */\nasync function initializeGraphSync(config: BurdenoffSDKInitConfig): Promise<unknown> {\n if (!config.graph?.enabled) {\n logger.info('[SDK Init] Graph sync not enabled, skipping');\n return undefined;\n }\n\n logger.info('[SDK Init] Graph sync enabled (publisher-only mode)', {\n eventsEnabled: config.graph.eventsEnabled ?? true,\n productSource: config.graph.productSource,\n streamName: config.graph.streamName ?? 'graph_events',\n syncInterval: config.graph.syncInterval ?? 1000,\n batchSize: config.graph.batchSize ?? 10,\n });\n\n return undefined;\n}\n\n/**\n * Initialize analytics (ClickHouse)\n */\nasync function initializeAnalytics(config: BurdenoffSDKInitConfig): Promise<unknown> {\n if (!config.analytics?.clickhouse) {\n logger.info('[SDK Init] Analytics not configured, skipping');\n return undefined;\n }\n\n logger.info('[SDK Init] Initializing ClickHouse for analytics...');\n\n // Note: ClickHouse initialization is handled by analytics module\n // This is a placeholder for future implementation\n logger.info('[SDK Init] ClickHouse configuration validated', {\n url: config.analytics.clickhouse.url,\n database: config.analytics.clickhouse.database,\n requestTimeout: config.analytics.clickhouse.requestTimeout ?? 60000,\n });\n\n return undefined;\n}\n\n/**\n * Initialize observability (metrics, tracing)\n */\nasync function initializeObservability(config: BurdenoffSDKInitConfig): Promise<void> {\n if (!config.observability?.metrics?.enabled && !config.observability?.openTelemetry?.enabled) {\n logger.info('[SDK Init] Observability not configured, skipping');\n return;\n }\n\n logger.info('[SDK Init] Initializing observability...');\n\n // Note: Observability initialization is handled by observability module\n // This is a placeholder for future implementation\n if (config.observability.metrics?.enabled) {\n logger.info('[SDK Init] Metrics configuration validated', {\n port: config.observability.metrics.port ?? 9090,\n endpoint: config.observability.metrics.endpoint ?? '/metrics',\n });\n }\n\n if (config.observability.openTelemetry?.enabled) {\n logger.info('[SDK Init] OpenTelemetry configuration validated', {\n serviceName: config.observability.openTelemetry.serviceName,\n samplingRate: config.observability.openTelemetry.samplingRate ?? 1.0,\n });\n }\n}\n\n/**\n * Initialize layer manager and gateway client\n */\nasync function initializeLayer(\n config: BurdenoffSDKInitConfig\n): Promise<{ layerManager?: LayerManager; gatewayClient?: GatewayClient }> {\n if (!config.layer) {\n logger.info('[SDK Init] Layer configuration not provided, skipping layer initialization');\n return {};\n }\n\n logger.info('[SDK Init] Initializing layer manager...', {\n layer: config.layer.type,\n serviceName: config.layer.serviceName,\n });\n\n // Create layer manager\n const layerManager = new LayerManager({\n layer: config.layer.type,\n serviceName: config.layer.serviceName,\n serviceIdentity: config.layer.serviceIdentity,\n });\n\n // Create gateway client\n const gatewayClient = new GatewayClient({\n layer: config.layer.type,\n serviceName: config.layer.serviceName,\n serviceIdentity: config.layer.serviceIdentity,\n internalGatewayUrl: layerManager.getInternalGatewayUrl(),\n crossLayerGatewayUrl: layerManager.getCrossLayerGatewayUrl(),\n });\n\n logger.info('[SDK Init] Layer manager initialized', {\n layer: config.layer.type,\n serviceName: config.layer.serviceName,\n internalGatewayUrl: layerManager.getInternalGatewayUrl(),\n crossLayerGatewayUrl: layerManager.getCrossLayerGatewayUrl(),\n });\n\n return { layerManager, gatewayClient };\n}\n\n/**\n * Initialize layer-specific Redis streams.\n *\n * No-op since the 2026-05-16 NATS retirement: Redis Streams are created\n * on demand by `XGROUP CREATE ... MKSTREAM` inside the consumer, so no\n * upfront connect-and-provision step is needed.\n */\nasync function initializeLayerStreams(config: BurdenoffSDKInitConfig): Promise<void> {\n if (!config.layer) {\n return;\n }\n logger.debug('[SDK Init] Layer streams init is a no-op for Redis Streams (auto-created on first XADD/XGROUP)', {\n layer: config.layer.type,\n });\n}\n\n// Export types\nexport type * from './types.js';\n"]}
|
|
@@ -66,8 +66,16 @@ var RBACClient = class RBACClient2 {
|
|
|
66
66
|
client;
|
|
67
67
|
cache;
|
|
68
68
|
config;
|
|
69
|
+
/**
|
|
70
|
+
* Per-request timeout (ms) for the RBAC service call.
|
|
71
|
+
* Bounds each checkPermission so a slow/cold RBAC gateway cannot hang the
|
|
72
|
+
* request indefinitely (previously the federation gateway killed the hung
|
|
73
|
+
* call at ~90s → 502). Defaults to 5000ms (matches RBACDirectiveConfig.timeout).
|
|
74
|
+
*/
|
|
75
|
+
timeoutMs;
|
|
69
76
|
constructor(config) {
|
|
70
77
|
this.client = new GraphQLClient(config.rbacServiceUrl);
|
|
78
|
+
this.timeoutMs = config.timeout ?? 5e3;
|
|
71
79
|
this.config = {
|
|
72
80
|
failClosed: config.failClosed !== false,
|
|
73
81
|
layer: config.layer || "wspace"
|
|
@@ -146,8 +154,12 @@ var RBACClient = class RBACClient2 {
|
|
|
146
154
|
input,
|
|
147
155
|
layer: this.config.layer
|
|
148
156
|
});
|
|
149
|
-
const result = await this.client.request(
|
|
150
|
-
|
|
157
|
+
const result = await this.client.request({
|
|
158
|
+
document: CHECK_PERMISSION_QUERY,
|
|
159
|
+
variables: {
|
|
160
|
+
input
|
|
161
|
+
},
|
|
162
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
151
163
|
});
|
|
152
164
|
const hasPermission = result.checkPermission.allowed;
|
|
153
165
|
const decisionPath = result.checkPermission.decisionPath;
|
|
@@ -1491,5 +1503,5 @@ var RBACModule = class {
|
|
|
1491
1503
|
};
|
|
1492
1504
|
|
|
1493
1505
|
export { RBACClient, RBACModule, createRBACClientFromEnv, createRBACDirective, createRBACDirectiveForLayer, createRBACDirectiveFromEnv };
|
|
1494
|
-
//# sourceMappingURL=chunk-
|
|
1495
|
-
//# sourceMappingURL=chunk-
|
|
1506
|
+
//# sourceMappingURL=chunk-N3YN6ZII.js.map
|
|
1507
|
+
//# sourceMappingURL=chunk-N3YN6ZII.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rbac/directive.ts","../src/rbac/index.ts"],"names":["LRUCache","cache","Map","maxSize","ttl","get","key","entry","undefined","Date","now","expiry","delete","set","value","size","firstKey","keys","next","clear","invalidateByPrefix","prefix","count","startsWith","RBACClient","client","config","timeoutMs","GraphQLClient","rbacServiceUrl","timeout","failClosed","layer","enableCaching","cacheMaxSize","cacheTTL","parsePermission","permission","colonIndex","indexOf","resourceType","action","substring","checkPermission","actorId","actorType","scopeId","resourceId","cacheKey","cached","logger","debug","hasPermission","reason","CHECK_PERMISSION_QUERY","input","result","request","document","variables","signal","AbortSignal","allowed","decisionPath","error","warn","clearCache","invalidateForActor","info","entriesRemoved","getLayer","getValueAtPath","obj","path","parts","split","current","part","getDirectiveArgument","directive","name","arg","arguments","find","a","kind","parseFieldArguments","field","variableValues","args","argName","argValue","parseObjectValue","fields","fieldName","fieldValue","toActorId","userId","sanitizeHeadersForLogging","headers","sanitized","Object","entries","lowerKey","toLowerCase","includes","getHeader","context","requestHeaders","contextHeaders","validateBypassTimestamp","timestamp","timestampMs","parseInt","isNaN","age","MAX_AGE","errorMessage","Error","message","checkBypassHeaders","shouldBypass","hasRequest","hasRequestHeaders","hasContextHeaders","requestHeadersType","contextHeadersType","allHeaders","forEach","sanitizedHeaders","contextHeadersObj","bypassHeader","bypassSource","bypassTimestamp","bypassAttempted","hasRbacBypass","hasBypassSource","hasBypassTimestamp","bypassContext","bypassFailureReason","source","verifyAuthentication","contextValue","ctx","user","actor","id","email","workspace_id","workspace","hasUser","GraphQLError","extensions","code","resolveResourceId","resourceIdField","selection","_rbacClient","_ctx","fieldArgs","availableArgs","hint","defaultPaths","contextWorkspaceId","triedPaths","join","resourceResolver","resolved","originalResourceId","resolvedResourceId","extractScopeId","workspaceId","tenantId","tenant","extractActorType","actorTypeHeader","upperType","toUpperCase","checkAndEnforcePermission","rbacClient","reasonSuffix","createRBACDirective","skipRbac","process","env","isProduction","onExecute","operation","definitions","def","operationName","schema","typeName","type","getType","getFields","selectionSet","selections","fieldDef","astNode","directives","d","bypassCheckResult","resource","operationType","buildRBACServiceUrl","routing","DEFAULT_GATEWAY_ROUTING","gateway","internalGateway","crossLayerGateway","host","port","graphqlPath","createRBACDirectiveForLayer","envPrefix","rbacLayer","createRBACDirectiveFromEnv","serviceName","createRBACClientFromEnv","options","DEFAULT_LAYER_RESOURCES","rbacGatewayUrl","RBACModule","requirePermission","ValidationError","query","response","tenantQuery","PermissionDeniedError","getUserRoles","contextWithWorkspace","actorRoleAssignments","map","assignment","role","description","defaultPermissions","assignRoleToUser","roleId","mutation","removeRoleFromUser","findQuery","findResponse","assignmentId","createRole","permissionCount","length","createRoleMutation","createRoleVariables","scopeType","createResponse","normalizedPermissions","perm","level","permMap","levelPriority","ADMIN","EDITOR","VIEWER","NONE","existing","setPermissionMutation","failedPermissions","errorMsg","String","push","failedTypes","p","roleQuery","roleResponse","getAvailablePermissions","resourceTypesQuery","hasWorkspace","resourceTypesResponse","permissions","actionsQuery","resourceTypes","actionsResponse","actionDefinitions","checkMultiplePermissions","checks","inputs","check","some","c","checkPermissions","getEffectivePermissions","effectivePermissions","initializeWorkspaceRoles","ownerId","updateRole","updates","deleteRole","reassignToRoleId","success","listRoles","filter","includeSystem","pagination","limit","offset","roles","getRole"],"mappings":"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","file":"chunk-N3YN6ZII.js","sourcesContent":["/**\n * RBAC Directive Plugin\n *\n * Centralized GraphQL directive enforcement for @requiresPermission\n * This plugin is shared across all microservices for consistent RBAC implementation.\n *\n * @module rbac/directive\n * @example\n * ```typescript\n * import { createRBACDirective } from '@burdenoff/be-sdk/rbac/directive';\n *\n * const server = await createServer({\n * yogaPlugins: [\n * createRBACDirective({\n * // Use Workspaces Gateway (RBAC is part of workspaces supergraph)\n * rbacServiceUrl: process.env.RBAC_GATEWAY_URL || 'http://localhost:4001/graphql',\n * enableCaching: true,\n * }),\n * ],\n * });\n * ```\n */\n\nimport type { Plugin } from '@envelop/core';\nimport {\n GraphQLError,\n type OperationDefinitionNode,\n type FieldNode,\n type ArgumentNode,\n type ObjectValueNode,\n type DirectiveNode,\n type DefinitionNode,\n} from 'graphql';\nimport { GraphQLClient } from 'graphql-request';\nimport { logger } from '../logger/index.js';\nimport type { ServiceLayer } from '../types/layer.js';\nimport { DEFAULT_GATEWAY_ROUTING } from '../types/layer.js';\n\n/**\n * User from context\n */\ninterface ContextUser {\n id: string;\n email?: string;\n workspace_id?: string;\n}\n\n/**\n * Actor type for PBAC\n */\ntype ActorType = 'USER' | 'BOT' | 'INTEGRATION' | 'DELEGATED_AGENT';\n\n/**\n * Expected context shape\n */\ninterface RBACContext {\n user?: ContextUser;\n actor?: { id?: string; email?: string } | null;\n actorId?: string;\n workspace?: { id: string };\n tenant?: { id: string };\n request?: {\n headers?: {\n get?: (name: string) => string | undefined;\n authorization?: string;\n 'x-rbac-bypass'?: string;\n 'x-bypass-source'?: string;\n 'x-bypass-timestamp'?: string;\n 'x-actor-id'?: string;\n 'x-actor-type'?: string;\n 'x-workspace-id'?: string;\n 'x-tenant-id'?: string;\n };\n };\n headers?: {\n authorization?: string;\n 'x-rbac-bypass'?: string;\n 'x-bypass-source'?: string;\n 'x-bypass-timestamp'?: string;\n 'x-actor-id'?: string;\n 'x-actor-type'?: string;\n 'x-workspace-id'?: string;\n 'x-tenant-id'?: string;\n };\n}\n\n/**\n * RBAC layer - determines which RBAC service to use\n */\nexport type RBACLayer = 'wspace' | 'global';\n\n/**\n * Configuration for RBAC directive plugin\n */\nexport interface RBACDirectiveConfig {\n /**\n * URL of the RBAC microservice GraphQL endpoint via Gateway\n * - wspace layer: Workspaces Gateway (wspace-rbac-svc)\n * - global layer: Global Gateway (global-rbac-svc)\n * @example 'http://localhost:4001/graphql' (Workspaces Gateway)\n * @example 'http://localhost:4000/graphql' (Global Gateway)\n */\n rbacServiceUrl: string;\n\n /**\n * RBAC layer - determines scope handling\n * - 'wspace': Uses workspaceId as scopeId (workspace-scoped permissions)\n * - 'global': Uses tenantId or 'global' as scopeId (global/billing-scoped permissions)\n * @default 'wspace'\n */\n layer?: RBACLayer;\n\n /**\n * Enable in-memory caching of permission checks\n * Caching reduces latency and load on RBAC service\n * @default true\n */\n enableCaching?: boolean;\n\n /**\n * Cache TTL in milliseconds\n * @default 60000 (1 minute)\n */\n cacheTTL?: number;\n\n /**\n * Maximum cache size (number of entries)\n * @default 10000\n */\n cacheMaxSize?: number;\n\n /**\n * Timeout for RBAC service requests in milliseconds\n * @default 5000 (5 seconds)\n */\n timeout?: number;\n\n /**\n * Fail-closed security: deny access on errors\n * When true, any error checking permissions results in denial\n * When false, errors are logged but access is allowed (NOT RECOMMENDED)\n * @default true\n */\n failClosed?: boolean;\n\n /**\n * Custom resource resolver function\n * Converts resource identifiers to RBAC resource UUIDs\n * If not provided, uses resource ID directly\n */\n resourceResolver?: (identifier: string, resourceType?: string) => Promise<string | null>;\n\n /**\n * Skip RBAC checks entirely (DEVELOPMENT ONLY)\n * When true, all RBAC checks are bypassed and requests are allowed.\n * ⚠️ WARNING: This should NEVER be enabled in production!\n *\n * Can also be set via SKIP_RBAC=true environment variable.\n * Environment variable takes precedence if set.\n *\n * Use cases:\n * - Local development before RBAC is fully configured\n * - Testing without RBAC service running\n * - Debugging permission issues\n *\n * @default false\n */\n skipRbac?: boolean;\n}\n\n/**\n * Permission check result from RBAC service\n */\ninterface CheckPermissionResult {\n hasPermission: boolean;\n reason?: string;\n}\n\n/**\n * Simple LRU cache for permission checks\n */\nclass LRUCache<K, V> {\n private cache = new Map<K, { value: V; expiry: number }>();\n private maxSize: number;\n private ttl: number;\n\n constructor(maxSize: number, ttl: number) {\n this.maxSize = maxSize;\n this.ttl = ttl;\n }\n\n get(key: K): V | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n if (Date.now() > entry.expiry) {\n this.cache.delete(key);\n return undefined;\n }\n\n // Move to end (LRU)\n this.cache.delete(key);\n this.cache.set(key, entry);\n\n return entry.value;\n }\n\n set(key: K, value: V): void {\n // Remove oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== undefined) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, {\n value,\n expiry: Date.now() + this.ttl,\n });\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n /**\n * Invalidate all entries whose key starts with the given prefix.\n * Used to evict all cached permissions for a specific actor.\n */\n invalidateByPrefix(prefix: string): number {\n let count = 0;\n for (const key of [...this.cache.keys()]) {\n if (typeof key === 'string' && key.startsWith(prefix)) {\n this.cache.delete(key);\n count++;\n }\n }\n return count;\n }\n}\n\n/**\n * Input for PBAC permission check\n */\ninterface PermissionCheckInput {\n actorId: string;\n actorType: ActorType;\n scopeId: string;\n resourceType: string;\n action: string;\n resourceId?: string;\n}\n\n/**\n * RBAC service client for permission checks\n */\nclass RBACClient {\n private client: GraphQLClient;\n private cache?: LRUCache<string, boolean>;\n private config: Required<Pick<RBACDirectiveConfig, 'failClosed'>> & { layer: RBACLayer };\n /**\n * Per-request timeout (ms) for the RBAC service call.\n * Bounds each checkPermission so a slow/cold RBAC gateway cannot hang the\n * request indefinitely (previously the federation gateway killed the hung\n * call at ~90s → 502). Defaults to 5000ms (matches RBACDirectiveConfig.timeout).\n */\n private timeoutMs: number;\n\n constructor(config: RBACDirectiveConfig) {\n this.client = new GraphQLClient(config.rbacServiceUrl);\n this.timeoutMs = config.timeout ?? 5000;\n\n this.config = {\n failClosed: config.failClosed !== false,\n layer: config.layer || 'wspace',\n };\n\n if (config.enableCaching !== false) {\n this.cache = new LRUCache<string, boolean>(\n config.cacheMaxSize || 10000,\n config.cacheTTL || 60000 // 1 minute\n );\n }\n }\n\n /**\n * Parse permission string into resourceType and action\n * @example \"project:read\" => { resourceType: \"project\", action: \"read\" }\n * @example \"rbac:role:create\" => { resourceType: \"rbac\", action: \"role:create\" }\n */\n private parsePermission(permission: string): { resourceType: string; action: string } {\n const colonIndex = permission.indexOf(':');\n if (colonIndex === -1) {\n // No colon - treat entire string as resourceType with \"read\" action\n return { resourceType: permission, action: 'read' };\n }\n return {\n resourceType: permission.substring(0, colonIndex),\n action: permission.substring(colonIndex + 1),\n };\n }\n\n /**\n * Check if actor has permission using the new PBAC checkPermission query\n */\n async checkPermission(\n actorId: string,\n actorType: ActorType,\n scopeId: string,\n permission: string,\n resourceId?: string\n ): Promise<CheckPermissionResult> {\n const { resourceType, action } = this.parsePermission(permission);\n const cacheKey = `${actorId}:${actorType}:${scopeId}:${resourceType}:${action}:${resourceId || ''}`;\n\n // Check cache\n if (this.cache) {\n const cached = this.cache.get(cacheKey);\n if (cached !== undefined) {\n logger.debug('[RBAC Directive] Cache hit', {\n actorId,\n actorType,\n scopeId,\n resourceType,\n action,\n resourceId,\n hasPermission: cached,\n });\n return {\n hasPermission: cached,\n reason: cached ? 'Cached: Permission granted' : 'Cached: Permission denied',\n };\n }\n }\n\n // Query RBAC service using new PBAC format\n const CHECK_PERMISSION_QUERY = `\n query CheckPermission($input: PermissionCheckInput!) {\n checkPermission(input: $input) {\n allowed\n decisionPath\n roleName\n roleLevel\n overrideType\n }\n }\n `;\n\n const input: PermissionCheckInput = {\n actorId,\n actorType,\n scopeId,\n resourceType,\n action,\n resourceId,\n };\n\n try {\n logger.debug('[RBAC Directive] Checking permission via RBAC service (PBAC)', {\n input,\n layer: this.config.layer,\n });\n\n // Bound the request with an AbortSignal so a slow/cold RBAC gateway\n // cannot hang indefinitely. On timeout the request rejects with an\n // AbortError, which is handled by the catch below (fail-closed by default).\n const result = await this.client.request<\n {\n checkPermission: {\n allowed: boolean;\n decisionPath: string;\n roleName?: string;\n roleLevel?: string;\n overrideType?: string;\n };\n },\n { input: PermissionCheckInput }\n >({\n document: CHECK_PERMISSION_QUERY,\n variables: { input },\n signal: AbortSignal.timeout(this.timeoutMs),\n });\n\n const hasPermission = result.checkPermission.allowed;\n const decisionPath = result.checkPermission.decisionPath;\n\n // Cache result\n if (this.cache) {\n this.cache.set(cacheKey, hasPermission);\n }\n\n logger.debug('[RBAC Directive] Permission check result', {\n actorId,\n resourceType,\n action,\n hasPermission,\n decisionPath,\n });\n\n return {\n hasPermission,\n reason: decisionPath,\n };\n } catch (error) {\n logger.error('[RBAC Directive] RBAC service error', {\n error,\n input,\n layer: this.config.layer,\n });\n\n // Fail closed or open based on config\n if (this.config.failClosed) {\n return {\n hasPermission: false,\n reason: 'RBAC service unavailable - access denied (fail-closed)',\n };\n } else {\n logger.warn('[RBAC Directive] Fail-open mode: allowing access despite RBAC error');\n return {\n hasPermission: true,\n reason: 'RBAC service unavailable - access allowed (fail-open)',\n };\n }\n }\n }\n\n /**\n * Clear permission cache (useful for testing or when permissions change)\n */\n clearCache(): void {\n this.cache?.clear();\n }\n\n /**\n * Invalidate cached permissions for a specific actor.\n * Call this when an actor's roles or permissions change to avoid stale cache hits.\n *\n * @param actorId - The actor whose cached permissions should be evicted\n * @returns Number of cache entries invalidated\n */\n invalidateForActor(actorId: string): number {\n if (!this.cache) return 0;\n const count = this.cache.invalidateByPrefix(`${actorId}:`);\n if (count > 0) {\n logger.info('[RBAC Directive] Invalidated cached permissions for actor', { actorId, entriesRemoved: count });\n }\n return count;\n }\n\n /**\n * Get the configured layer\n */\n getLayer(): RBACLayer {\n return this.config.layer;\n }\n}\n\n/**\n * Extract value from nested object path\n * @example getValueAtPath({ input: { id: '123' } }, 'input.id') => '123'\n */\nfunction getValueAtPath(obj: Record<string, unknown>, path: string): string | undefined {\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n // Type guard: ensure current is an object before property access\n if (typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return typeof current === 'string' ? current : undefined;\n}\n\n/**\n * Extract directive argument value\n */\nfunction getDirectiveArgument(directive: { arguments?: readonly ArgumentNode[] }, name: string): string | undefined {\n const arg = directive.arguments?.find((a: ArgumentNode) => a.name.value === name);\n if (arg && arg.value.kind === 'StringValue') {\n return arg.value.value;\n }\n return undefined;\n}\n\n/**\n * Parse GraphQL arguments to plain object\n */\nfunction parseFieldArguments(field: FieldNode, variableValues: Record<string, unknown>): Record<string, unknown> {\n const args: Record<string, unknown> = {};\n\n for (const arg of field.arguments || []) {\n const argName = arg.name.value;\n const argValue = arg.value;\n\n if (argValue.kind === 'Variable') {\n args[argName] = variableValues[argValue.name.value];\n } else if (argValue.kind === 'ObjectValue') {\n args[argName] = parseObjectValue(argValue, variableValues);\n } else if ('value' in argValue) {\n args[argName] = argValue.value;\n }\n }\n\n return args;\n}\n\n/**\n * Parse GraphQL object value to plain object\n */\nfunction parseObjectValue(obj: ObjectValueNode, variableValues: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const field of obj.fields || []) {\n const fieldName = field.name.value;\n const fieldValue = field.value;\n\n if (fieldValue.kind === 'Variable') {\n result[fieldName] = variableValues[fieldValue.name.value];\n } else if (fieldValue.kind === 'ObjectValue') {\n result[fieldName] = parseObjectValue(fieldValue, variableValues);\n } else if ('value' in fieldValue) {\n result[fieldName] = fieldValue.value;\n }\n }\n\n return result;\n}\n\n/**\n * Convert user ID to actor ID format\n *\n * NOTE: This function currently performs no transformation (identity function).\n * It was added as an extension point for future actor ID transformations if needed.\n *\n * Historically, actor IDs used a different format (e.g., \"actor:user-123\"),\n * but this was simplified to use user IDs directly for consistency.\n *\n * Keep this function in place to:\n * 1. Maintain API compatibility with existing code\n * 2. Provide a centralized point for future ID transformations\n * 3. Make the ID transformation intent explicit in the code\n *\n * @param userId - User ID from context\n * @returns Actor ID (currently identical to user ID)\n * @example abc-123 => abc-123\n */\nfunction toActorId(userId: string): string {\n return userId;\n}\n\n/**\n * Sanitize headers for logging (redact sensitive values)\n * @param headers - Headers object to sanitize\n * @returns Sanitized headers with sensitive values redacted\n */\nfunction sanitizeHeadersForLogging(headers: Record<string, string>): Record<string, string> {\n const sanitized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n const lowerKey = key.toLowerCase();\n\n // Redact sensitive headers\n if (\n lowerKey.includes('auth') ||\n lowerKey.includes('token') ||\n lowerKey.includes('password') ||\n lowerKey.includes('secret') ||\n lowerKey.includes('key') ||\n lowerKey.includes('credential')\n ) {\n sanitized[key] = '***REDACTED***';\n } else {\n sanitized[key] = value;\n }\n }\n\n return sanitized;\n}\n\n/**\n * Get header value from context (checks both request.headers and headers)\n */\nfunction getHeader(context: RBACContext, key: string): string | undefined {\n // Try request.headers first (if available)\n if (context.request?.headers) {\n // If it has a get method, use it\n if (typeof context.request.headers.get === 'function') {\n const value = context.request.headers.get(key);\n if (value) return value;\n }\n // Otherwise treat as object\n const requestHeaders = context.request.headers as Record<string, string | undefined>;\n const value = requestHeaders[key];\n if (value) return value;\n }\n\n // Fallback to context.headers\n if (context.headers) {\n const contextHeaders = context.headers as Record<string, string | undefined>;\n const value = contextHeaders[key];\n if (value) return value;\n }\n\n return undefined;\n}\n\n/**\n * Validate bypass timestamp to prevent replay attacks\n * @param timestamp - Timestamp string in milliseconds\n * @returns true if timestamp is fresh (< 1 minute old)\n */\nfunction validateBypassTimestamp(timestamp: string): boolean {\n try {\n const timestampMs = parseInt(timestamp, 10);\n if (isNaN(timestampMs)) {\n return false;\n }\n\n const now = Date.now();\n const age = now - timestampMs;\n const MAX_AGE = 60 * 1000; // 1 minute (sufficient for network latency, reduces replay attack window)\n\n if (age > MAX_AGE || age < 0) {\n logger.warn('[RBAC Directive] Stale bypass timestamp', {\n age,\n timestamp: timestampMs,\n now,\n });\n return false;\n }\n\n return true;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n logger.warn('[RBAC Directive] Invalid bypass timestamp format', {\n timestamp,\n error: errorMessage,\n });\n return false;\n }\n}\n\n/**\n * Bypass check result with context information\n */\ninterface BypassCheckResult {\n shouldBypass: boolean;\n bypassContext?: {\n bypassAttempted: boolean;\n bypassSource?: string;\n bypassTimestamp?: string;\n bypassFailureReason?: string;\n };\n}\n\n/**\n * Check if request should bypass RBAC based on headers\n * This is used for internal service-to-service communication\n *\n * ⚠️ ARCHITECTURE NOTE: Header Transformation Flow\n * ================================================\n * These headers are TRANSFORMED by the Internal API Gateway before reaching this directive.\n *\n * Flow:\n * 1. Service A (internal-client.ts) → Internal API Gateway\n * Headers sent: x-bypass-permission, x-service-identity, x-call-type\n *\n * 2. Internal API Gateway → Service B (this RBAC directive)\n * Headers transformed to: x-rbac-bypass, x-bypass-source, x-bypass-timestamp\n *\n * This directive validates the TRANSFORMED headers from the gateway, not the original\n * headers from the internal client. The mismatch between internal-client.ts:101-106\n * and this function is INTENTIONAL and part of the security architecture.\n *\n * DO NOT \"fix\" internal-client.ts to send these headers - the gateway handles transformation.\n *\n * Headers required (after gateway transformation):\n * - x-rbac-bypass: \"true\"\n * - x-bypass-source: Service identity (e.g., \"scheduler-service\")\n * - x-bypass-timestamp: Unix timestamp in milliseconds\n *\n * @param context - GraphQL context containing headers\n * @returns Bypass check result with context for error reporting\n */\nfunction checkBypassHeaders(context: RBACContext): BypassCheckResult {\n // First check for actor type bypass (service or super_admin bypasses RBAC)\n const actorType = getHeader(context, 'x-actor-type');\n const actorId = getHeader(context, 'x-actor-id');\n\n if (actorType === 'service' || actorType === 'super_admin') {\n logger.debug('[RBAC Directive] Actor type bypass - service/super_admin', {\n actorType,\n actorId,\n });\n return { shouldBypass: true };\n }\n\n // Debug: Log all available headers\n logger.debug('[RBAC Directive] Checking bypass headers - context structure', {\n hasRequest: !!context.request,\n hasRequestHeaders: !!context.request?.headers,\n hasContextHeaders: !!context.headers,\n requestHeadersType: context.request?.headers ? typeof context.request.headers : 'undefined',\n contextHeadersType: context.headers ? typeof context.headers : 'undefined',\n actorType,\n actorId,\n });\n\n // Debug: Try to extract and log all headers (sanitized)\n const allHeaders: Record<string, string> = {};\n if (context.request?.headers) {\n if (typeof context.request.headers.get === 'function') {\n // Headers object with get method\n logger.debug('[RBAC Directive] Headers object has get method');\n } else {\n // Plain object\n const headers = context.request.headers as Record<string, string | undefined>;\n Object.keys(headers).forEach((key) => {\n const value = headers[key];\n if (value) allHeaders[key] = value;\n });\n const sanitizedHeaders = sanitizeHeadersForLogging(allHeaders);\n logger.debug('[RBAC Directive] Request headers (plain object)', { headers: sanitizedHeaders });\n }\n }\n if (context.headers) {\n const headers = context.headers as Record<string, string | undefined>;\n const contextHeadersObj: Record<string, string> = {};\n Object.keys(headers).forEach((key) => {\n const value = headers[key];\n if (value) contextHeadersObj[key] = value;\n });\n const sanitizedHeaders = sanitizeHeadersForLogging(contextHeadersObj);\n logger.debug('[RBAC Directive] Context headers', { headers: sanitizedHeaders });\n }\n\n const bypassHeader = getHeader(context, 'x-rbac-bypass');\n const bypassSource = getHeader(context, 'x-bypass-source');\n const bypassTimestamp = getHeader(context, 'x-bypass-timestamp');\n\n logger.debug('[RBAC Directive] Extracted bypass headers', {\n bypassHeader,\n bypassSource,\n bypassTimestamp,\n });\n\n // Check if bypass headers are present\n const bypassAttempted = !!(bypassHeader || bypassSource || bypassTimestamp);\n\n // Must have all three headers\n if (!bypassHeader || !bypassSource || !bypassTimestamp) {\n logger.debug('[RBAC Directive] Missing bypass headers - bypass NOT granted', {\n hasRbacBypass: !!bypassHeader,\n hasBypassSource: !!bypassSource,\n hasBypassTimestamp: !!bypassTimestamp,\n });\n\n if (bypassAttempted) {\n return {\n shouldBypass: false,\n bypassContext: {\n bypassAttempted: true,\n bypassSource,\n bypassTimestamp,\n bypassFailureReason: 'Missing required bypass headers',\n },\n };\n }\n\n return { shouldBypass: false };\n }\n\n // Verify bypass is 'true'\n if (bypassHeader !== 'true') {\n logger.warn('[RBAC Directive] Invalid bypass header value', { value: bypassHeader });\n return {\n shouldBypass: false,\n bypassContext: {\n bypassAttempted: true,\n bypassSource,\n bypassTimestamp,\n bypassFailureReason: `Invalid bypass header value: ${bypassHeader}`,\n },\n };\n }\n\n // Validate timestamp freshness (prevent replay attacks)\n if (!validateBypassTimestamp(bypassTimestamp)) {\n logger.warn('[RBAC Directive] Bypass rejected: stale timestamp', {\n source: bypassSource,\n timestamp: bypassTimestamp,\n });\n return {\n shouldBypass: false,\n bypassContext: {\n bypassAttempted: true,\n bypassSource,\n bypassTimestamp,\n bypassFailureReason: 'Stale or invalid timestamp (replay attack prevention)',\n },\n };\n }\n\n // All checks passed\n logger.debug('[RBAC Directive] Valid bypass headers detected', {\n source: bypassSource,\n timestamp: bypassTimestamp,\n });\n\n return { shouldBypass: true };\n}\n\n/**\n * Verify user authentication from context\n */\nfunction verifyAuthentication(contextValue: unknown, fieldName: string, permission: string): ContextUser {\n const ctx = contextValue as RBACContext;\n const user =\n ctx.user ??\n (ctx.actor?.id\n ? {\n id: ctx.actor.id,\n email: ctx.actor.email,\n workspace_id: ctx.workspace?.id,\n }\n : ctx.actorId\n ? {\n id: ctx.actorId,\n workspace_id: ctx.workspace?.id,\n }\n : undefined);\n\n logger.debug('[RBAC Directive] Checking authentication', {\n hasUser: !!user,\n userId: user?.id,\n fieldName,\n });\n\n if (!user?.id) {\n logger.warn('[RBAC Directive] Authentication required but user not found', {\n fieldName,\n permission,\n });\n throw new GraphQLError('Authentication required', {\n extensions: {\n code: 'UNAUTHENTICATED',\n field: fieldName,\n permission,\n },\n });\n }\n\n return user;\n}\n\n/**\n * Resolve resource ID from field arguments and configuration\n */\nasync function resolveResourceId(\n resourceIdField: string | undefined,\n selection: FieldNode,\n variableValues: Record<string, unknown> | null | undefined,\n config: RBACDirectiveConfig,\n _rbacClient: RBACClient,\n _ctx: RBACContext,\n permission: string,\n fieldName: string\n): Promise<string> {\n let resourceId: string | undefined;\n\n // Parse GraphQL arguments\n const fieldArgs = parseFieldArguments(selection, variableValues || {});\n\n if (resourceIdField) {\n // Explicit resourceIdField specified - use that path\n resourceId = getValueAtPath(fieldArgs, resourceIdField);\n\n if (!resourceId) {\n logger.error('[RBAC Directive] Resource ID not found at specified path', {\n resourceIdField,\n fieldName,\n permission,\n availableArgs: Object.keys(fieldArgs),\n });\n\n throw new GraphQLError(\n `Resource ID not found at specified path \"${resourceIdField}\" for permission \"${permission}\"`,\n {\n extensions: {\n code: 'INVALID_RESOURCE_CONFIGURATION',\n field: fieldName,\n permission,\n resourceIdField,\n hint: `Check that the field path \"${resourceIdField}\" exists in your arguments`,\n },\n }\n );\n }\n\n logger.debug('[RBAC Directive] Using explicit resourceIdField', {\n resourceIdField,\n resourceId,\n fieldName,\n });\n } else {\n // No resourceIdField specified - try common conventions\n const defaultPaths = ['id', 'input.id'];\n\n for (const path of defaultPaths) {\n resourceId = getValueAtPath(fieldArgs, path);\n if (resourceId) {\n logger.debug('[RBAC Directive] Auto-resolved resource ID from convention', {\n path,\n resourceId,\n fieldName,\n permission,\n });\n break;\n }\n }\n\n if (!resourceId) {\n // Fall back to context-based resource ID from headers\n // This is useful for list operations where the resource isn't in arguments\n const contextWorkspaceId = _ctx.workspace?.id;\n\n if (contextWorkspaceId) {\n resourceId = contextWorkspaceId;\n logger.debug('[RBAC Directive] Using workspace ID from context headers', {\n resourceId,\n fieldName,\n permission,\n });\n } else {\n logger.error('[RBAC Directive] No resource ID available for permission check', {\n permission,\n fieldName,\n triedPaths: defaultPaths,\n availableArgs: Object.keys(fieldArgs),\n });\n\n throw new GraphQLError(\n `Cannot check permission \"${permission}\": No resource ID available. ` +\n `Tried default paths: ${defaultPaths.join(', ')}. ` +\n `Either provide one of these fields in your arguments, specify resourceIdField in the directive, or pass x-workspace-id header.`,\n {\n extensions: {\n code: 'INVALID_RESOURCE_CONFIGURATION',\n field: fieldName,\n permission,\n triedPaths: defaultPaths,\n hint: 'Add resourceIdField parameter to @requiresPermission directive (e.g., resourceIdField: \"input.workspaceId\") or pass x-workspace-id header',\n },\n }\n );\n }\n }\n }\n\n // Apply custom resource resolver if configured\n if (resourceId && config.resourceResolver) {\n const resolved = await config.resourceResolver(resourceId, permission.split(':')[0]);\n\n if (!resolved) {\n logger.warn('[RBAC Directive] Custom resource resolver returned null', {\n originalResourceId: resourceId,\n permission,\n fieldName,\n });\n\n throw new GraphQLError('Resource not found or invalid', {\n extensions: {\n code: 'FORBIDDEN',\n field: fieldName,\n permission,\n resourceId,\n hint: 'Resource resolver could not resolve the resource ID',\n },\n });\n }\n\n logger.debug('[RBAC Directive] Custom resource resolver applied', {\n originalResourceId: resourceId,\n resolvedResourceId: resolved,\n fieldName,\n });\n\n return resolved;\n }\n\n // Return the resource ID as-is (assume it's already a valid UUID/identifier)\n return resourceId;\n}\n\n/**\n * Extract scope ID from context based on layer\n */\nfunction extractScopeId(ctx: RBACContext, layer: RBACLayer): string {\n if (layer === 'wspace') {\n // Workspace layer: use workspaceId\n const workspaceId = getHeader(ctx, 'x-workspace-id') || ctx.workspace?.id;\n\n if (!workspaceId) {\n throw new GraphQLError('Workspace ID required for workspace-layer RBAC', {\n extensions: { code: 'BAD_REQUEST', hint: 'Pass x-workspace-id header or ensure workspace context is set' },\n });\n }\n return workspaceId;\n } else {\n // Global layer: use tenantId or 'global' for superadmin\n const tenantId = getHeader(ctx, 'x-tenant-id') || ctx.tenant?.id || 'global'; // Default to global scope for superadmin operations\n\n return tenantId;\n }\n}\n\n/**\n * Extract actor type from context\n */\nfunction extractActorType(ctx: RBACContext): ActorType {\n const actorTypeHeader = getHeader(ctx, 'x-actor-type');\n\n if (actorTypeHeader) {\n const upperType = actorTypeHeader.toUpperCase();\n if (['USER', 'BOT', 'INTEGRATION', 'DELEGATED_AGENT'].includes(upperType)) {\n return upperType as ActorType;\n }\n }\n\n // Default to USER\n return 'USER';\n}\n\n/**\n * Check permission and throw error if denied\n */\nasync function checkAndEnforcePermission(\n rbacClient: RBACClient,\n ctx: RBACContext,\n actorId: string,\n permission: string,\n resolvedResourceId: string | undefined,\n userId: string,\n fieldName: string,\n bypassContext?: {\n bypassAttempted: boolean;\n bypassSource?: string;\n bypassTimestamp?: string;\n bypassFailureReason?: string;\n }\n): Promise<void> {\n const layer = rbacClient.getLayer();\n const actorType = extractActorType(ctx);\n const scopeId = extractScopeId(ctx, layer);\n\n logger.info('[RBAC Directive] Checking permission', {\n userId,\n actorId,\n actorType,\n scopeId,\n permission,\n resourceId: resolvedResourceId,\n fieldName,\n layer,\n bypassAttempted: bypassContext?.bypassAttempted ?? false,\n });\n\n const { hasPermission, reason } = await rbacClient.checkPermission(\n actorId,\n actorType,\n scopeId,\n permission,\n resolvedResourceId\n );\n\n if (!hasPermission) {\n logger.warn('[RBAC Directive] Permission denied', {\n userId,\n actorType,\n scopeId,\n permission,\n reason,\n fieldName,\n bypassContext,\n });\n\n const reasonSuffix = reason ? ` - ${reason}` : '';\n const errorMessage = `Forbidden: Missing permission \"${permission}\"${reasonSuffix}`;\n\n // Include bypass context in error extensions for debugging\n const extensions: Record<string, unknown> = {\n code: 'FORBIDDEN',\n permission,\n reason,\n field: fieldName,\n resourceId: resolvedResourceId,\n scopeId,\n layer,\n };\n\n // Add bypass context if a bypass was attempted but failed\n if (bypassContext?.bypassAttempted) {\n extensions['bypassAttempted'] = true;\n extensions['bypassSource'] = bypassContext.bypassSource;\n extensions['bypassTimestamp'] = bypassContext.bypassTimestamp;\n extensions['bypassFailureReason'] = bypassContext.bypassFailureReason;\n }\n\n throw new GraphQLError(errorMessage, { extensions });\n }\n\n logger.info('[RBAC Directive] Permission granted', {\n userId,\n permission,\n fieldName,\n reason,\n });\n}\n\n/**\n * Create RBAC directive enforcement plugin\n *\n * This plugin:\n * 1. Intercepts GraphQL operations BEFORE execution\n * 2. Checks for @requiresPermission directive on fields\n * 3. Validates user authentication\n * 4. Extracts resource ID from field arguments\n * 5. Calls RBAC service to check permissions\n * 6. Allows or denies operation based on permission check\n *\n * @param config - RBAC directive configuration\n * @returns Envelop plugin instance\n *\n * @example\n * ```typescript\n * // In microservice server initialization\n * const server = await createServer({\n * yogaPlugins: [\n * createRBACDirective({\n * // Use Workspaces Gateway (RBAC is part of workspaces supergraph)\n * rbacServiceUrl: process.env.RBAC_GATEWAY_URL || 'http://localhost:4001/graphql',\n * enableCaching: true,\n * cacheTTL: 300000, // 5 minutes\n * failClosed: true, // Deny access on errors\n * }),\n * useGraphQLModules(application),\n * ],\n * });\n * ```\n */\nexport function createRBACDirective(config: RBACDirectiveConfig): Plugin {\n // Check for SKIP_RBAC - environment variable takes precedence over config\n const skipRbac = process.env['SKIP_RBAC'] === 'true' || config.skipRbac === true;\n\n if (skipRbac) {\n const isProduction = process.env['NODE_ENV'] === 'production';\n\n // CRITICAL: Prevent SKIP_RBAC in production environments\n if (isProduction) {\n throw new Error(\n '[RBAC Directive] FATAL: SKIP_RBAC cannot be enabled in production environments. ' +\n 'This would bypass all authorization checks and is a critical security vulnerability. ' +\n 'Remove SKIP_RBAC=true from your environment configuration.'\n );\n }\n\n logger.warn('[RBAC Directive] ⚠️ RBAC CHECKS ARE DISABLED (SKIP_RBAC=true) - DO NOT USE IN PRODUCTION!');\n return {\n async onExecute({ args }): Promise<void> {\n // Log which operation is being executed without RBAC checks for audit trail\n const { document } = args;\n const operation = document.definitions.find(\n (def: DefinitionNode): def is OperationDefinitionNode => def.kind === 'OperationDefinition'\n );\n const operationName = operation?.name?.value || 'anonymous';\n logger.warn('[RBAC Directive] RBAC check skipped for operation', { operationName });\n },\n };\n }\n\n const rbacClient = new RBACClient(config);\n\n return {\n // 🔒 CRITICAL: Use onExecute (not onExecuteDone) to block BEFORE execution\n async onExecute({ args }): Promise<void> {\n logger.debug('[RBAC Directive] onExecute called');\n const { schema, document, contextValue, variableValues } = args;\n\n // Find the operation definition\n const operation = document.definitions.find(\n (def: DefinitionNode): def is OperationDefinitionNode => def.kind === 'OperationDefinition'\n );\n\n if (!operation) {\n logger.debug('[RBAC Directive] No operation definition found, skipping');\n return;\n }\n\n // Get the type based on operation (Query or Mutation)\n const typeName = operation.operation === 'mutation' ? 'Mutation' : 'Query';\n const type = schema.getType(typeName);\n\n if (!type || !('getFields' in type)) {\n logger.debug(`[RBAC Directive] Type ${typeName} not found, skipping`);\n return;\n }\n\n const fields = type.getFields();\n\n // Check each selected field for @requiresPermission directive\n for (const selection of operation.selectionSet.selections) {\n if (selection.kind !== 'Field') {\n continue;\n }\n\n const fieldName = selection.name.value;\n const fieldDef = fields[fieldName];\n\n if (!fieldDef?.astNode) {\n continue;\n }\n\n // Find @requiresPermission directive\n const directive = fieldDef.astNode.directives?.find(\n (d: DirectiveNode) => d.name.value === 'requiresPermission'\n );\n\n if (!directive) {\n // No directive on this field, continue\n continue;\n }\n\n // Extract directive arguments\n const permission = getDirectiveArgument(directive, 'permission');\n const resourceIdField = getDirectiveArgument(directive, 'resourceIdField');\n\n if (!permission) {\n throw new GraphQLError(\n 'Invalid @requiresPermission directive: permission argument is required and must be a string',\n {\n extensions: { code: 'INTERNAL_SERVER_ERROR', field: fieldName },\n }\n );\n }\n\n // CHECK FOR BYPASS HEADERS FIRST (internal service-to-service calls)\n const ctx = contextValue as RBACContext;\n const bypassCheckResult = checkBypassHeaders(ctx);\n\n if (bypassCheckResult.shouldBypass) {\n // Log bypass for audit trail\n const bypassSource = getHeader(ctx, 'x-bypass-source');\n const bypassTimestamp = getHeader(ctx, 'x-bypass-timestamp');\n\n logger.info('[RBAC Directive] RBAC bypassed for internal service call', {\n field: fieldName,\n permission,\n resource: resourceIdField,\n bypassSource,\n bypassTimestamp,\n operationType: operation.operation,\n });\n\n // Skip RBAC check, continue to next field\n continue;\n }\n\n // REGULAR RBAC FLOW (user requests)\n // Check authentication\n // SECURITY: This directive REQUIRES authenticated context to be set by upstream middleware\n // We do NOT decode/verify JWT tokens here - that must be done by auth middleware\n const user = verifyAuthentication(contextValue, fieldName, permission);\n\n // Resolve resource ID (optional - not all permissions need a specific resource)\n let resolvedResourceId: string | undefined;\n try {\n resolvedResourceId = await resolveResourceId(\n resourceIdField,\n selection as FieldNode,\n variableValues,\n config,\n rbacClient,\n ctx,\n permission,\n fieldName\n );\n } catch (error) {\n // If resourceIdField was not specified and we couldn't resolve it,\n // that's OK for permission checks that don't need a specific resource\n if (!resourceIdField) {\n logger.debug('[RBAC Directive] No resource ID resolved, checking permission at scope level', {\n fieldName,\n permission,\n });\n } else {\n // If resourceIdField WAS specified but we couldn't resolve, that's an error\n throw error;\n }\n }\n\n // Convert user ID to actor ID and check permission\n const actorId = toActorId(user.id);\n await checkAndEnforcePermission(\n rbacClient,\n ctx,\n actorId,\n permission,\n resolvedResourceId,\n user.id,\n fieldName,\n bypassCheckResult.bypassContext\n );\n }\n\n // All checks passed - allow execution\n },\n };\n}\n\n/**\n * Export RBACClient for direct use if needed\n */\nexport { RBACClient };\n\n// ========================================================================\n// Layer-Aware Factory Functions\n// ========================================================================\n\n/**\n * Layer-aware RBAC configuration\n */\nexport interface LayerAwareRBACConfig extends Omit<RBACDirectiveConfig, 'rbacServiceUrl' | 'layer'> {\n /**\n * Override RBAC service URL (optional)\n * If not provided, will be resolved from layer defaults\n */\n rbacServiceUrl?: string;\n}\n\n/**\n * Build RBAC service URL for a layer\n *\n * @param layer - Service layer ('wspace' or 'global')\n * @returns RBAC service URL\n */\nfunction buildRBACServiceUrl(layer: ServiceLayer): string {\n const routing = DEFAULT_GATEWAY_ROUTING[layer];\n\n // RBAC is accessed via the internal gateway for the current layer\n // wspace layer → wspace-int-gateway (RBAC is part of workspaces supergraph)\n // global layer → global-int-gateway (needs to call wspace layer for RBAC)\n const gateway = layer === 'wspace' ? routing.internalGateway : routing.crossLayerGateway;\n\n return `http://${gateway.host}:${gateway.port}${gateway.graphqlPath}`;\n}\n\n/**\n * Create RBAC directive plugin for a specific layer\n *\n * This factory function automatically configures the RBAC directive with\n * the correct internal gateway URL based on the service layer.\n *\n * @param layer - Service layer ('wspace' or 'global')\n * @param config - Optional configuration overrides\n * @returns RBAC directive plugin configured for the layer\n *\n * @example\n * ```typescript\n * // In a workspace layer service\n * const rbacPlugin = createRBACDirectiveForLayer('wspace', {\n * enableCaching: true,\n * cacheTTL: 300000,\n * });\n *\n * // In a global layer service\n * const rbacPlugin = createRBACDirectiveForLayer('global', {\n * enableCaching: true,\n * });\n * ```\n */\nexport function createRBACDirectiveForLayer(layer: ServiceLayer, config?: LayerAwareRBACConfig): Plugin {\n const envPrefix = layer.toUpperCase();\n\n // Resolve RBAC service URL with priority:\n // 1. Explicit config.rbacServiceUrl\n // 2. Layer-specific env var (WSPACE_RBAC_GATEWAY_URL or GLOBAL_RBAC_GATEWAY_URL)\n // 3. Generic env var (RBAC_GATEWAY_URL)\n // 4. Layer defaults\n const rbacServiceUrl =\n config?.rbacServiceUrl ||\n process.env[`${envPrefix}_RBAC_GATEWAY_URL`] ||\n process.env['RBAC_GATEWAY_URL'] ||\n buildRBACServiceUrl(layer);\n\n // Map ServiceLayer to RBACLayer (they're compatible but different types)\n const rbacLayer: RBACLayer = layer;\n\n logger.info('[RBAC Directive] Creating layer-aware RBAC directive', {\n layer: rbacLayer,\n rbacServiceUrl,\n enableCaching: config?.enableCaching ?? true,\n });\n\n return createRBACDirective({\n rbacServiceUrl,\n layer: rbacLayer,\n enableCaching: config?.enableCaching ?? true,\n cacheTTL: config?.cacheTTL,\n cacheMaxSize: config?.cacheMaxSize,\n timeout: config?.timeout,\n failClosed: config?.failClosed,\n resourceResolver: config?.resourceResolver,\n skipRbac: config?.skipRbac,\n });\n}\n\n/**\n * Create RBAC directive from environment with automatic layer detection\n *\n * @param serviceName - Service name for layer detection\n * @param config - Optional configuration overrides\n * @returns RBAC directive plugin\n */\nexport function createRBACDirectiveFromEnv(serviceName: string, config?: LayerAwareRBACConfig): Plugin {\n // Detect layer from service name or environment\n const layer =\n (process.env['SERVICE_LAYER'] as ServiceLayer) || (serviceName.startsWith('global-') ? 'global' : 'wspace');\n\n return createRBACDirectiveForLayer(layer, config);\n}\n","/**\n * RBAC Module\n * Role-Based Access Control - Permission checking and resource management\n */\n\nimport type { BurdenoffGraphQLClient } from '../client/graphql.js';\nimport type { SDKContext } from '../types/index.js';\nimport { PermissionDeniedError, ValidationError } from '../types/index.js';\nimport { logger } from '../logger/index.js';\n\nimport { RBACClient } from './directive.js';\nimport type { ServiceLayer } from '../types/layer.js';\nimport { DEFAULT_LAYER_RESOURCES } from '../types/layer.js';\n\n// Export centralized RBAC directive plugin\nexport {\n createRBACDirective,\n createRBACDirectiveForLayer,\n createRBACDirectiveFromEnv,\n type RBACDirectiveConfig,\n type LayerAwareRBACConfig,\n RBACClient,\n} from './directive.js';\n\n/**\n * Build an `RBACClient` from env vars (mirrors `createRBACDirectiveFromEnv`).\n *\n * Resolution order for the gateway URL:\n * 1. explicit `rbacServiceUrl` option\n * 2. `<LAYER>_RBAC_GATEWAY_URL`\n * 3. `RBAC_GATEWAY_URL`\n * 4. layer default\n */\nexport function createRBACClientFromEnv(\n options: { rbacServiceUrl?: string; layer?: ServiceLayer; failClosed?: boolean } = {}\n): RBACClient {\n const layer: ServiceLayer = options.layer ?? ((process.env['SERVICE_LAYER'] as ServiceLayer) || 'wspace');\n const envPrefix = layer.toUpperCase();\n const rbacServiceUrl =\n options.rbacServiceUrl ||\n process.env[`${envPrefix}_RBAC_GATEWAY_URL`] ||\n process.env['RBAC_GATEWAY_URL'] ||\n DEFAULT_LAYER_RESOURCES[layer].rbacGatewayUrl;\n return new RBACClient({\n rbacServiceUrl,\n layer,\n failClosed: options.failClosed,\n });\n}\n\nexport type PBACActorType = 'USER' | 'BOT' | 'INTEGRATION' | 'DELEGATED_AGENT';\n\nexport type PBACPermissionLevel = 'ADMIN' | 'EDITOR' | 'VIEWER' | 'NONE';\n\nexport interface CheckPermissionOptions {\n userId: string;\n action: string;\n resourceType: string;\n resourceId?: string;\n workspaceId?: string;\n /** Actor type for the PBAC system. Defaults to 'USER' */\n actorType?: PBACActorType;\n}\n\nexport interface EffectivePermissionEntry {\n resourceType: string;\n level: PBACPermissionLevel;\n allowedActions: string[];\n source: string;\n}\n\nexport interface RoleDefaultPermission {\n resourceType: string;\n level: PBACPermissionLevel;\n}\n\nexport interface Role {\n id: string;\n name: string;\n description?: string;\n /** Default permission levels per resource type (PBAC) */\n defaultPermissions?: RoleDefaultPermission[];\n}\n\nexport interface Permission {\n id: string;\n action: string;\n resourceType: string;\n description?: string;\n}\n\n/**\n * RBAC Module\n */\nexport class RBACModule {\n constructor(\n private client: BurdenoffGraphQLClient,\n private context: SDKContext\n ) {}\n\n /**\n * Check if user has permission (returns boolean)\n */\n public async checkPermission(options: CheckPermissionOptions): Promise<boolean> {\n try {\n await this.requirePermission(options);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Require permission (throws if denied)\n */\n public async requirePermission(options: CheckPermissionOptions): Promise<void> {\n if (!options.userId) {\n throw new ValidationError('User ID is required');\n }\n\n if (!options.action) {\n throw new ValidationError('Action is required');\n }\n\n if (!options.resourceType) {\n throw new ValidationError('Resource type is required');\n }\n\n logger.debug('[RBAC] Checking permission', options);\n\n // Use the new PBAC PermissionCheckInput format\n // Note: The new unified RBAC uses actorId + actorType + scopeId instead of userId + workspaceId\n const query = `\n query CheckPermission($input: PermissionCheckInput!) {\n checkPermission(input: $input) {\n allowed\n decisionPath\n }\n }\n `;\n\n const variables = {\n input: {\n actorId: options.userId,\n actorType: options.actorType || 'USER',\n scopeId: options.workspaceId || this.context.workspaceId || this.context.tenantId || '',\n resourceType: options.resourceType,\n action: options.action,\n resourceId: options.resourceId,\n },\n };\n\n // RBAC operations should go to the workspace supergraph if we have a workspaceId,\n // otherwise fall back to tenant supergraph\n const response =\n options.workspaceId || this.context.workspaceId\n ? await this.client.query<{\n checkPermission: { allowed: boolean; decisionPath: string };\n }>(query, variables, this.context)\n : await this.client.tenantQuery<{\n checkPermission: { allowed: boolean; decisionPath: string };\n }>(query, variables, this.context);\n\n if (!response.checkPermission.allowed) {\n throw new PermissionDeniedError(`Permission denied: ${response.checkPermission.decisionPath}`, {\n action: options.action,\n resourceType: options.resourceType,\n resourceId: options.resourceId,\n userId: options.userId,\n });\n }\n\n logger.debug('[RBAC] Permission granted', {\n ...options,\n decisionPath: response.checkPermission.decisionPath,\n });\n }\n\n /**\n * Get user roles in workspace\n * Uses the new PBAC actorRoleAssignments query\n */\n public async getUserRoles(userId: string, workspaceId: string): Promise<Role[]> {\n logger.debug('[RBAC] Getting user roles', { userId, workspaceId });\n\n // Use the new PBAC actorRoleAssignments query\n const query = `\n query GetActorRoleAssignments($actorId: String!, $scopeId: String!) {\n actorRoleAssignments(actorId: $actorId, scopeId: $scopeId) {\n id\n role {\n id\n name\n description\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n }\n `;\n\n const variables = {\n actorId: userId,\n scopeId: workspaceId,\n };\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n // Use workspace supergraph for workspace-scoped RBAC\n const response = await this.client.query<{\n actorRoleAssignments: Array<{\n id: string;\n role: {\n id: string;\n name: string;\n description?: string;\n defaultPermissions: RoleDefaultPermission[];\n };\n }>;\n }>(query, variables, contextWithWorkspace);\n\n // Map the roles to the expected format\n return response.actorRoleAssignments.map((assignment) => ({\n id: assignment.role.id,\n name: assignment.role.name,\n description: assignment.role.description,\n defaultPermissions: assignment.role.defaultPermissions,\n }));\n }\n\n /**\n * Assign role to user\n * Uses the new PBAC assignRoleToActor mutation\n */\n public async assignRoleToUser(\n userId: string,\n roleId: string,\n workspaceId: string,\n actorType: 'USER' | 'BOT' | 'INTEGRATION' | 'DELEGATED_AGENT' = 'USER'\n ): Promise<boolean> {\n logger.debug('[RBAC] Assigning role to user', { userId, roleId, workspaceId, actorType });\n\n // Use the new PBAC assignRoleToActor mutation\n const mutation = `\n mutation AssignRoleToActor($input: AssignRoleInput!) {\n assignRoleToActor(input: $input) {\n id\n actorId\n roleId\n scopeId\n }\n }\n `;\n\n const variables = {\n input: {\n actorId: userId,\n actorType,\n roleId,\n scopeId: workspaceId,\n },\n };\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n // Use workspace supergraph for workspace-scoped RBAC\n await this.client.query(mutation, variables, contextWithWorkspace);\n\n logger.info('[RBAC] Role assigned to actor', { userId, roleId, workspaceId });\n\n return true;\n }\n\n /**\n * Remove role from user\n * Uses the new PBAC removeRoleFromActor mutation\n * Note: This first finds the assignment ID, then removes it\n */\n public async removeRoleFromUser(userId: string, roleId: string, workspaceId: string): Promise<boolean> {\n logger.debug('[RBAC] Removing role from user', { userId, roleId, workspaceId });\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n // First, find the assignment to get its ID\n const findQuery = `\n query FindAssignment($actorId: String!, $scopeId: String!) {\n actorRoleAssignments(actorId: $actorId, scopeId: $scopeId) {\n id\n roleId\n }\n }\n `;\n\n const findResponse = await this.client.query<{\n actorRoleAssignments: Array<{ id: string; roleId: string }>;\n }>(findQuery, { actorId: userId, scopeId: workspaceId }, contextWithWorkspace);\n\n const assignment = findResponse.actorRoleAssignments.find((a) => a.roleId === roleId);\n\n if (!assignment) {\n logger.warn('[RBAC] No role assignment found to remove', { userId, roleId, workspaceId });\n return false;\n }\n\n // Use the new PBAC removeRoleFromActor mutation\n const mutation = `\n mutation RemoveRoleFromActor($assignmentId: ID!) {\n removeRoleFromActor(assignmentId: $assignmentId)\n }\n `;\n\n await this.client.query(mutation, { assignmentId: assignment.id }, contextWithWorkspace);\n\n logger.info('[RBAC] Role removed from actor', { userId, roleId, workspaceId, assignmentId: assignment.id });\n\n return true;\n }\n\n /**\n * Create custom role with default permissions\n *\n * Uses the new PBAC createRole mutation and setRoleDefaultPermission for permissions.\n *\n * @param name - Role name\n * @param description - Role description\n * @param defaultPermissions - Array of default permission configurations\n * (e.g., [{ resourceType: 'project', level: 'ADMIN' }])\n * OR legacy permission strings (converted to ADMIN level)\n * @param workspaceId - Workspace ID (scopeId)\n */\n public async createRole(\n name: string,\n description: string,\n defaultPermissions: RoleDefaultPermission[] | string[],\n workspaceId: string\n ): Promise<Role> {\n logger.debug('[RBAC] Creating role', { name, workspaceId, permissionCount: defaultPermissions.length });\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n // Step 1: Create the role using new PBAC mutation\n const createRoleMutation = `\n mutation CreateRole($input: CreateRoleInput!) {\n createRole(input: $input) {\n id\n name\n description\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n `;\n\n const createRoleVariables = {\n input: {\n name,\n description,\n scopeId: workspaceId,\n scopeType: 'workspace',\n },\n };\n\n // Use workspace supergraph for workspace-scoped RBAC\n const createResponse = await this.client.query<{\n createRole: {\n id: string;\n name: string;\n description?: string;\n defaultPermissions: Array<{ resourceType: string; level: string }>;\n };\n }>(createRoleMutation, createRoleVariables, contextWithWorkspace);\n\n const roleId = createResponse.createRole.id;\n logger.info('[RBAC] Role created', { name, roleId });\n\n // Step 2: Set default permissions if provided\n if (defaultPermissions.length > 0) {\n logger.debug('[RBAC] Setting default permissions for role', { roleId, count: defaultPermissions.length });\n\n // Convert legacy string permissions to new format\n const normalizedPermissions: RoleDefaultPermission[] = defaultPermissions.map((perm) => {\n if (typeof perm === 'string') {\n // Legacy format: \"resourceType:action\" - convert to ADMIN level\n const resourceType = perm.split(':')[0] || perm;\n return { resourceType, level: 'ADMIN' };\n }\n return perm;\n });\n\n // Deduplicate by resourceType (keep the highest level)\n const permMap = new Map<string, PBACPermissionLevel>();\n const levelPriority: Record<PBACPermissionLevel, number> = { ADMIN: 4, EDITOR: 3, VIEWER: 2, NONE: 1 };\n\n for (const perm of normalizedPermissions) {\n const existing = permMap.get(perm.resourceType);\n if (!existing || levelPriority[perm.level] > levelPriority[existing]) {\n permMap.set(perm.resourceType, perm.level);\n }\n }\n\n // Set each default permission\n const setPermissionMutation = `\n mutation SetRoleDefaultPermission($input: SetRoleDefaultPermissionInput!) {\n setRoleDefaultPermission(input: $input) {\n id\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n `;\n\n // Track failed permissions to report at the end\n const failedPermissions: Array<{ resourceType: string; level: string; error: string }> = [];\n\n for (const [resourceType, level] of permMap) {\n try {\n await this.client.query(\n setPermissionMutation,\n {\n input: {\n roleId,\n resourceType,\n level,\n },\n },\n contextWithWorkspace\n );\n logger.debug('[RBAC] Set default permission', { roleId, resourceType, level });\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error('[RBAC] Failed to set default permission', {\n roleId,\n resourceType,\n level,\n error: errorMsg,\n });\n failedPermissions.push({ resourceType, level, error: errorMsg });\n }\n }\n\n // If any permissions failed, throw an error with details\n if (failedPermissions.length > 0) {\n const failedTypes = failedPermissions.map((p) => p.resourceType).join(', ');\n throw new ValidationError(\n `Role created but failed to set ${failedPermissions.length} default permission(s): ${failedTypes}. ` +\n `Role ID: ${roleId}. Check logs for details.`\n );\n }\n\n logger.info('[RBAC] Default permissions set for role', { roleId, count: permMap.size });\n }\n\n // Fetch the updated role\n const roleQuery = `\n query GetRole($id: ID!) {\n role(id: $id) {\n id\n name\n description\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n `;\n\n const roleResponse = await this.client.query<{\n role: {\n id: string;\n name: string;\n description?: string;\n defaultPermissions: RoleDefaultPermission[];\n } | null;\n }>(roleQuery, { id: roleId }, contextWithWorkspace);\n\n const role = roleResponse.role || createResponse.createRole;\n\n // Return the role with mapped permissions (backward compatible format)\n return {\n id: role.id,\n name: role.name,\n description: role.description,\n defaultPermissions: role.defaultPermissions as RoleDefaultPermission[],\n };\n }\n\n /**\n * Get all available action definitions (replaces getAvailablePermissions)\n * Returns actions organized by resource type\n */\n public async getAvailablePermissions(): Promise<Permission[]> {\n logger.debug('[RBAC] Getting available action definitions');\n\n // Use the new PBAC resourceTypes and actionDefinitions queries\n const resourceTypesQuery = `\n query GetResourceTypes {\n resourceTypes\n }\n `;\n\n // Get from workspace supergraph if we have workspace context\n const hasWorkspace = !!this.context.workspaceId;\n\n const resourceTypesResponse = hasWorkspace\n ? await this.client.query<{ resourceTypes: string[] }>(resourceTypesQuery, {}, this.context)\n : await this.client.tenantQuery<{ resourceTypes: string[] }>(resourceTypesQuery, {}, this.context);\n\n const permissions: Permission[] = [];\n\n // Get action definitions for each resource type\n const actionsQuery = `\n query GetActionDefinitions($resourceType: String!) {\n actionDefinitions(resourceType: $resourceType) {\n id\n action\n resourceType\n description\n }\n }\n `;\n\n for (const resourceType of resourceTypesResponse.resourceTypes) {\n const actionsResponse = hasWorkspace\n ? await this.client.query<{\n actionDefinitions: Array<{ id: string; action: string; resourceType: string; description?: string }>;\n }>(actionsQuery, { resourceType }, this.context)\n : await this.client.tenantQuery<{\n actionDefinitions: Array<{ id: string; action: string; resourceType: string; description?: string }>;\n }>(actionsQuery, { resourceType }, this.context);\n\n for (const action of actionsResponse.actionDefinitions) {\n permissions.push({\n id: action.id,\n action: action.action,\n resourceType: action.resourceType,\n description: action.description,\n });\n }\n }\n\n return permissions;\n }\n\n /**\n * Check multiple permissions at once\n * Uses the new PBAC checkPermissions query\n */\n public async checkMultiplePermissions(\n checks: CheckPermissionOptions[]\n ): Promise<Array<{ allowed: boolean; reason?: string }>> {\n logger.debug('[RBAC] Checking multiple permissions', { count: checks.length });\n\n // Use the new PBAC checkPermissions query\n const query = `\n query CheckPermissions($inputs: [PermissionCheckInput!]!) {\n checkPermissions(inputs: $inputs) {\n allowed\n decisionPath\n }\n }\n `;\n\n // Convert to new PBAC input format\n const inputs = checks.map((check) => ({\n actorId: check.userId,\n actorType: check.actorType || 'USER',\n scopeId: check.workspaceId || this.context.workspaceId || this.context.tenantId || '',\n resourceType: check.resourceType,\n action: check.action,\n resourceId: check.resourceId,\n }));\n\n // Use workspace supergraph if any check has workspaceId\n const hasWorkspace = checks.some((c) => c.workspaceId) || !!this.context.workspaceId;\n\n const response = hasWorkspace\n ? await this.client.query<{\n checkPermissions: Array<{ allowed: boolean; decisionPath: string }>;\n }>(query, { inputs }, this.context)\n : await this.client.tenantQuery<{\n checkPermissions: Array<{ allowed: boolean; decisionPath: string }>;\n }>(query, { inputs }, this.context);\n\n // Map to backward-compatible format\n return response.checkPermissions.map((result) => ({\n allowed: result.allowed,\n reason: result.decisionPath,\n }));\n }\n\n /**\n * Get effective permissions for a user in a workspace\n * New method that uses the PBAC effectivePermissions query\n */\n public async getEffectivePermissions(\n userId: string,\n workspaceId: string,\n actorType: 'USER' | 'BOT' | 'INTEGRATION' | 'DELEGATED_AGENT' = 'USER'\n ): Promise<{\n actorId: string;\n scopeId: string;\n permissions: EffectivePermissionEntry[];\n }> {\n logger.debug('[RBAC] Getting effective permissions', { userId, workspaceId, actorType });\n\n const query = `\n query EffectivePermissions($actorId: String!, $actorType: ActorType!, $scopeId: String!) {\n effectivePermissions(actorId: $actorId, actorType: $actorType, scopeId: $scopeId) {\n actorId\n scopeId\n permissions {\n resourceType\n level\n allowedActions\n source\n }\n }\n }\n `;\n\n const variables = {\n actorId: userId,\n actorType,\n scopeId: workspaceId,\n };\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n const response = await this.client.query<{\n effectivePermissions: {\n actorId: string;\n scopeId: string;\n permissions: EffectivePermissionEntry[];\n };\n }>(query, variables, contextWithWorkspace);\n\n return response.effectivePermissions;\n }\n\n /**\n * Initialize workspace roles by cloning system roles\n * New method for workspace initialization\n */\n public async initializeWorkspaceRoles(\n workspaceId: string,\n ownerId: string\n ): Promise<{\n success: boolean;\n rolesCreated: number;\n roleNames: string[];\n ownerAssigned: boolean;\n message: string;\n }> {\n logger.debug('[RBAC] Initializing workspace roles', { workspaceId, ownerId });\n\n const mutation = `\n mutation InitializeWorkspaceRoles($workspaceId: String!, $ownerId: String!) {\n initializeWorkspaceRoles(workspaceId: $workspaceId, ownerId: $ownerId) {\n success\n rolesCreated\n roleNames\n ownerAssigned\n message\n }\n }\n `;\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n const response = await this.client.query<{\n initializeWorkspaceRoles: {\n success: boolean;\n rolesCreated: number;\n roleNames: string[];\n ownerAssigned: boolean;\n message: string;\n };\n }>(mutation, { workspaceId, ownerId }, contextWithWorkspace);\n\n logger.info('[RBAC] Workspace roles initialized', response.initializeWorkspaceRoles);\n\n return response.initializeWorkspaceRoles;\n }\n\n /**\n * Update an existing role\n * Uses the new PBAC updateRole mutation\n *\n * @param roleId - Role ID to update\n * @param updates - Fields to update (name, description, priority)\n * @param workspaceId - Workspace ID (scopeId)\n */\n public async updateRole(\n roleId: string,\n updates: {\n name?: string;\n description?: string;\n priority?: number;\n },\n workspaceId: string\n ): Promise<Role> {\n logger.debug('[RBAC] Updating role', { roleId, updates, workspaceId });\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n const mutation = `\n mutation UpdateRole($id: ID!, $input: UpdateRoleInput!) {\n updateRole(id: $id, input: $input) {\n id\n name\n description\n priority\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n `;\n\n const response = await this.client.query<{\n updateRole: {\n id: string;\n name: string;\n description?: string;\n priority: number;\n defaultPermissions: RoleDefaultPermission[];\n };\n }>(mutation, { id: roleId, input: updates }, contextWithWorkspace);\n\n logger.info('[RBAC] Role updated', { roleId, name: response.updateRole.name });\n\n // Return in backward-compatible format\n return {\n id: response.updateRole.id,\n name: response.updateRole.name,\n description: response.updateRole.description,\n defaultPermissions: response.updateRole.defaultPermissions,\n };\n }\n\n /**\n * Delete a role\n * Uses the new PBAC deleteRole mutation\n *\n * @param roleId - Role ID to delete\n * @param workspaceId - Workspace ID (scopeId)\n * @param reassignToRoleId - Optional role ID to reassign existing actors to\n */\n public async deleteRole(roleId: string, workspaceId: string, reassignToRoleId?: string): Promise<boolean> {\n logger.debug('[RBAC] Deleting role', { roleId, workspaceId, reassignToRoleId });\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n const mutation = `\n mutation DeleteRole($id: ID!, $reassignToRoleId: ID) {\n deleteRole(id: $id, reassignToRoleId: $reassignToRoleId)\n }\n `;\n\n const response = await this.client.query<{\n deleteRole: boolean;\n }>(mutation, { id: roleId, reassignToRoleId }, contextWithWorkspace);\n\n logger.info('[RBAC] Role deleted', { roleId, success: response.deleteRole });\n\n return response.deleteRole;\n }\n\n /**\n * List roles in a workspace\n * Uses the new PBAC roles query\n *\n * @param workspaceId - Workspace ID (scopeId)\n * @param options - Filter and pagination options\n */\n public async listRoles(\n workspaceId: string,\n options?: {\n includeSystem?: boolean;\n limit?: number;\n offset?: number;\n }\n ): Promise<Role[]> {\n logger.debug('[RBAC] Listing roles', { workspaceId, options });\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n const query = `\n query ListRoles($scopeId: String!, $filter: RoleFilterInput, $pagination: PaginationInput) {\n roles(scopeId: $scopeId, filter: $filter, pagination: $pagination) {\n id\n name\n description\n isSystem\n priority\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n `;\n\n const variables = {\n scopeId: workspaceId,\n filter: options?.includeSystem !== undefined ? { includeSystem: options.includeSystem } : undefined,\n pagination: {\n limit: options?.limit ?? 50,\n offset: options?.offset ?? 0,\n },\n };\n\n const response = await this.client.query<{\n roles: Array<{\n id: string;\n name: string;\n description?: string;\n isSystem: boolean;\n priority: number;\n defaultPermissions: RoleDefaultPermission[];\n }>;\n }>(query, variables, contextWithWorkspace);\n\n logger.debug('[RBAC] Roles listed', { workspaceId, count: response.roles.length });\n\n return response.roles.map((role) => ({\n id: role.id,\n name: role.name,\n description: role.description,\n defaultPermissions: role.defaultPermissions,\n }));\n }\n\n /**\n * Get a specific role by ID\n * Uses the new PBAC role query\n *\n * @param roleId - Role ID\n * @param workspaceId - Workspace ID (scopeId)\n */\n public async getRole(roleId: string, workspaceId: string): Promise<Role | null> {\n logger.debug('[RBAC] Getting role', { roleId, workspaceId });\n\n const contextWithWorkspace = {\n ...this.context,\n workspaceId,\n };\n\n const query = `\n query GetRole($id: ID!) {\n role(id: $id) {\n id\n name\n description\n isSystem\n priority\n defaultPermissions {\n resourceType\n level\n }\n }\n }\n `;\n\n const response = await this.client.query<{\n role: {\n id: string;\n name: string;\n description?: string;\n isSystem: boolean;\n priority: number;\n defaultPermissions: RoleDefaultPermission[];\n } | null;\n }>(query, { id: roleId }, contextWithWorkspace);\n\n if (!response.role) {\n logger.debug('[RBAC] Role not found', { roleId });\n return null;\n }\n\n // Return in backward-compatible format\n return {\n id: response.role.id,\n name: response.role.name,\n description: response.role.description,\n defaultPermissions: response.role.defaultPermissions,\n };\n }\n}\n"]}
|