@kysera/rls 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -21
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/native/index.d.ts +1 -1
- package/dist/{types-Dtg6Lt1k.d.ts → types-6eCXh_Jd.d.ts} +10 -0
- package/package.json +3 -3
- package/src/policy/types.ts +12 -0
- package/src/transformer/mutation.ts +5 -4
package/README.md
CHANGED
|
@@ -622,13 +622,15 @@ Create an RLS context object with validation.
|
|
|
622
622
|
import { createRLSContext } from '@kysera/rls';
|
|
623
623
|
|
|
624
624
|
const ctx = createRLSContext({
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
625
|
+
auth: {
|
|
626
|
+
userId: 123,
|
|
627
|
+
roles: ['user', 'editor'],
|
|
628
|
+
tenantId: 'acme-corp',
|
|
629
|
+
organizationIds: ['org-1'],
|
|
630
|
+
permissions: ['posts:read', 'posts:write'],
|
|
631
|
+
isSystem: false,
|
|
632
|
+
},
|
|
633
|
+
timestamp: new Date(),
|
|
632
634
|
});
|
|
633
635
|
|
|
634
636
|
// Use with runAsync
|
|
@@ -832,12 +834,9 @@ Generate PostgreSQL `CREATE POLICY` statements from your RLS schema.
|
|
|
832
834
|
import { PostgresRLSGenerator } from '@kysera/rls/native';
|
|
833
835
|
|
|
834
836
|
const generator = new PostgresRLSGenerator(rlsSchema, {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
tenantId: 'current_setting(\'app.tenant_id\')::uuid',
|
|
839
|
-
roles: 'current_setting(\'app.roles\')::text[]',
|
|
840
|
-
},
|
|
837
|
+
force: true, // Force RLS on table owners
|
|
838
|
+
schemaName: 'public', // Schema name (default: public)
|
|
839
|
+
policyPrefix: 'rls_', // Prefix for generated policy names
|
|
841
840
|
});
|
|
842
841
|
|
|
843
842
|
// Generate policies for a table
|
|
@@ -847,14 +846,15 @@ console.log(sql);
|
|
|
847
846
|
/*
|
|
848
847
|
Output:
|
|
849
848
|
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
|
|
849
|
+
ALTER TABLE posts FORCE ROW LEVEL SECURITY;
|
|
850
850
|
|
|
851
|
-
CREATE POLICY
|
|
851
|
+
CREATE POLICY rls_tenant_isolation ON posts
|
|
852
852
|
FOR ALL
|
|
853
|
-
USING (tenant_id =
|
|
853
|
+
USING (tenant_id = current_user_tenant_id());
|
|
854
854
|
|
|
855
|
-
CREATE POLICY
|
|
855
|
+
CREATE POLICY rls_author_access ON posts
|
|
856
856
|
FOR UPDATE
|
|
857
|
-
USING (author_id =
|
|
857
|
+
USING (author_id = current_user_id());
|
|
858
858
|
*/
|
|
859
859
|
```
|
|
860
860
|
|
|
@@ -866,10 +866,9 @@ Generate migration files for PostgreSQL RLS policies.
|
|
|
866
866
|
import { RLSMigrationGenerator } from '@kysera/rls/native';
|
|
867
867
|
|
|
868
868
|
const migrationGen = new RLSMigrationGenerator(rlsSchema, {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
},
|
|
869
|
+
force: true, // Force RLS on table owners
|
|
870
|
+
schemaName: 'public', // Schema name (default: public)
|
|
871
|
+
policyPrefix: 'rls_', // Prefix for generated policy names
|
|
873
872
|
migrationPath: './migrations',
|
|
874
873
|
timestamp: true,
|
|
875
874
|
});
|
|
@@ -1146,6 +1145,7 @@ export {
|
|
|
1146
1145
|
withRLSContext,
|
|
1147
1146
|
withRLSContextAsync,
|
|
1148
1147
|
} from '@kysera/rls';
|
|
1148
|
+
export type { RLSContext } from '@kysera/rls';
|
|
1149
1149
|
|
|
1150
1150
|
// Errors
|
|
1151
1151
|
export {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RLSSchema, O as Operation, P as PolicyCondition, a as PolicyHints, b as PolicyDefinition, F as FilterCondition, T as TableRLSConfig, C as CompiledPolicy, c as CompiledFilterPolicy, d as RLSContext, e as RLSAuthContext, f as RLSRequestContext, g as PolicyEvaluationContext } from './types-
|
|
2
|
-
export { h as PolicyType } from './types-
|
|
1
|
+
import { R as RLSSchema, O as Operation, P as PolicyCondition, a as PolicyHints, b as PolicyDefinition, F as FilterCondition, T as TableRLSConfig, C as CompiledPolicy, c as CompiledFilterPolicy, d as RLSContext, e as RLSAuthContext, f as RLSRequestContext, g as PolicyEvaluationContext } from './types-6eCXh_Jd.js';
|
|
2
|
+
export { h as PolicyType } from './types-6eCXh_Jd.js';
|
|
3
3
|
import { KyseraLogger, ErrorCode } from '@kysera/core';
|
|
4
4
|
import { Plugin } from '@kysera/repository';
|
|
5
5
|
import 'kysely';
|
package/dist/index.js
CHANGED
|
@@ -839,9 +839,9 @@ var SelectTransformer = class {
|
|
|
839
839
|
|
|
840
840
|
// src/transformer/mutation.ts
|
|
841
841
|
var MutationGuard = class {
|
|
842
|
-
|
|
842
|
+
// executor is kept for future use with database-dependent policies
|
|
843
|
+
constructor(registry, _executor) {
|
|
843
844
|
this.registry = registry;
|
|
844
|
-
this.executor = executor;
|
|
845
845
|
}
|
|
846
846
|
/**
|
|
847
847
|
* Check if CREATE operation is allowed
|
|
@@ -1069,7 +1069,7 @@ var MutationGuard = class {
|
|
|
1069
1069
|
data,
|
|
1070
1070
|
table,
|
|
1071
1071
|
operation,
|
|
1072
|
-
|
|
1072
|
+
...ctx.meta !== void 0 && { meta: ctx.meta }
|
|
1073
1073
|
};
|
|
1074
1074
|
}
|
|
1075
1075
|
/**
|
|
@@ -1081,8 +1081,8 @@ var MutationGuard = class {
|
|
|
1081
1081
|
return result instanceof Promise ? await result : result;
|
|
1082
1082
|
} catch (error) {
|
|
1083
1083
|
throw new RLSPolicyViolation(
|
|
1084
|
-
evalCtx.operation,
|
|
1085
|
-
evalCtx.table,
|
|
1084
|
+
evalCtx.operation ?? "unknown",
|
|
1085
|
+
evalCtx.table ?? "unknown",
|
|
1086
1086
|
`Policy evaluation error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1087
1087
|
);
|
|
1088
1088
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/policy/schema.ts","../src/policy/builder.ts","../src/policy/registry.ts","../src/context/storage.ts","../src/context/manager.ts","../src/transformer/select.ts","../src/transformer/mutation.ts","../src/plugin.ts","../src/utils/helpers.ts"],"names":["allow","deny","validate","filter","silentLogger"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * RLS Error Classes\n *\n * This module provides specialized error classes for Row-Level Security operations.\n * All errors extend the base RLSError class and use unified error codes from @kysera/core\n * for consistency across the Kysera ecosystem.\n *\n * @module @kysera/rls/errors\n */\n\nimport type { ErrorCode } from '@kysera/core';\n\n// ============================================================================\n// RLS Error Codes\n// ============================================================================\n\n/**\n * RLS-specific error codes\n *\n * These codes extend the unified error codes from @kysera/core with\n * RLS-specific error conditions.\n */\nexport const RLSErrorCodes = {\n /** RLS context is missing or not set */\n RLS_CONTEXT_MISSING: 'RLS_CONTEXT_MISSING' as ErrorCode,\n /** RLS policy violation occurred */\n RLS_POLICY_VIOLATION: 'RLS_POLICY_VIOLATION' as ErrorCode,\n /** RLS policy definition is invalid */\n RLS_POLICY_INVALID: 'RLS_POLICY_INVALID' as ErrorCode,\n /** RLS schema definition is invalid */\n RLS_SCHEMA_INVALID: 'RLS_SCHEMA_INVALID' as ErrorCode,\n /** RLS context validation failed */\n RLS_CONTEXT_INVALID: 'RLS_CONTEXT_INVALID' as ErrorCode,\n} as const;\n\n/**\n * Type for RLS error codes\n */\nexport type RLSErrorCode = typeof RLSErrorCodes[keyof typeof RLSErrorCodes];\n\n// ============================================================================\n// Base RLS Error\n// ============================================================================\n\n/**\n * Base class for all RLS-related errors\n *\n * Provides common error functionality including error codes and JSON serialization.\n *\n * @example\n * ```typescript\n * throw new RLSError('Something went wrong', RLSErrorCodes.RLS_POLICY_INVALID);\n * ```\n */\nexport class RLSError extends Error {\n public readonly code: RLSErrorCode;\n\n /**\n * Creates a new RLS error\n *\n * @param message - Error message\n * @param code - RLS error code\n */\n constructor(message: string, code: RLSErrorCode) {\n super(message);\n this.name = 'RLSError';\n this.code = code;\n }\n\n /**\n * Serializes the error to JSON\n *\n * @returns JSON representation of the error\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n };\n }\n}\n\n// ============================================================================\n// Context Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS context is missing\n *\n * This error occurs when an operation requiring RLS context is executed\n * outside of a context scope (i.e., without calling withRLSContext()).\n *\n * @example\n * ```typescript\n * // This will throw RLSContextError\n * const result = await db.selectFrom('posts').execute();\n *\n * // Correct usage with context\n * await withRLSContext(rlsContext, async () => {\n * const result = await db.selectFrom('posts').execute();\n * });\n * ```\n */\nexport class RLSContextError extends RLSError {\n /**\n * Creates a new RLS context error\n *\n * @param message - Error message (defaults to standard message)\n */\n constructor(message: string = 'No RLS context found. Ensure code runs within withRLSContext()') {\n super(message, RLSErrorCodes.RLS_CONTEXT_MISSING);\n this.name = 'RLSContextError';\n }\n}\n\n/**\n * Error thrown when RLS context validation fails\n *\n * This error occurs when the provided RLS context is invalid or missing\n * required fields.\n *\n * @example\n * ```typescript\n * // Missing required userId field\n * const invalidContext = {\n * auth: {\n * roles: ['user']\n * // userId is missing!\n * },\n * timestamp: new Date()\n * };\n *\n * // This will throw RLSContextValidationError\n * validateRLSContext(invalidContext);\n * ```\n */\nexport class RLSContextValidationError extends RLSError {\n public readonly field: string;\n\n /**\n * Creates a new context validation error\n *\n * @param message - Error message\n * @param field - Field that failed validation\n */\n constructor(message: string, field: string) {\n super(message, RLSErrorCodes.RLS_CONTEXT_INVALID);\n this.name = 'RLSContextValidationError';\n this.field = field;\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n field: this.field,\n };\n }\n}\n\n// ============================================================================\n// Policy Errors\n// ============================================================================\n\n/**\n * Error thrown when an RLS policy violation occurs\n *\n * This error is thrown when a database operation is denied by RLS policies.\n * It provides detailed information about the violation including the operation,\n * table, and reason for denial.\n *\n * @example\n * ```typescript\n * // User tries to update a post they don't own\n * throw new RLSPolicyViolation(\n * 'update',\n * 'posts',\n * 'User does not own this post',\n * 'ownership_policy'\n * );\n * ```\n */\nexport class RLSPolicyViolation extends RLSError {\n public readonly operation: string;\n public readonly table: string;\n public readonly reason: string;\n public readonly policyName?: string;\n\n /**\n * Creates a new policy violation error\n *\n * @param operation - Database operation that was denied (read, create, update, delete)\n * @param table - Table name where violation occurred\n * @param reason - Reason for the policy violation\n * @param policyName - Name of the policy that denied access (optional)\n */\n constructor(\n operation: string,\n table: string,\n reason: string,\n policyName?: string\n ) {\n super(\n `RLS policy violation: ${operation} on ${table} - ${reason}`,\n RLSErrorCodes.RLS_POLICY_VIOLATION\n );\n this.name = 'RLSPolicyViolation';\n this.operation = operation;\n this.table = table;\n this.reason = reason;\n if (policyName !== undefined) {\n this.policyName = policyName;\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n ...super.toJSON(),\n operation: this.operation,\n table: this.table,\n reason: this.reason,\n };\n if (this.policyName !== undefined) {\n json['policyName'] = this.policyName;\n }\n return json;\n }\n}\n\n// ============================================================================\n// Schema Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS schema validation fails\n *\n * This error occurs when the RLS schema definition is invalid or contains\n * configuration errors.\n *\n * @example\n * ```typescript\n * // Invalid policy definition\n * const invalidSchema = {\n * posts: {\n * policies: [\n * {\n * type: 'invalid-type', // Invalid policy type!\n * operation: 'read',\n * condition: (ctx) => true\n * }\n * ]\n * }\n * };\n *\n * // This will throw RLSSchemaError\n * validateRLSSchema(invalidSchema);\n * ```\n */\nexport class RLSSchemaError extends RLSError {\n public readonly details: Record<string, unknown>;\n\n /**\n * Creates a new schema validation error\n *\n * @param message - Error message\n * @param details - Additional details about the validation failure\n */\n constructor(message: string, details: Record<string, unknown> = {}) {\n super(message, RLSErrorCodes.RLS_SCHEMA_INVALID);\n this.name = 'RLSSchemaError';\n this.details = details;\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n details: this.details,\n };\n }\n}\n","/**\n * RLS schema definition and validation\n *\n * Provides functions to define, validate, and merge RLS schemas.\n */\n\nimport type { RLSSchema, TableRLSConfig, PolicyDefinition } from './types.js';\nimport { RLSSchemaError } from '../errors.js';\n\n/**\n * Define RLS schema with full type safety\n *\n * @example\n * ```typescript\n * interface Database {\n * users: { id: number; email: string; tenant_id: number };\n * posts: { id: number; user_id: number; tenant_id: number };\n * }\n *\n * const schema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * // Users can read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * // Filter by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Admins bypass all checks\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * posts: {\n * policies: [\n * // Filter posts by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Users can only edit their own posts\n * allow(['update', 'delete'], ctx => ctx.auth.userId === ctx.row.user_id),\n * // Validate new posts belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * defaultDeny: true, // Require explicit allow\n * },\n * });\n * ```\n */\nexport function defineRLSSchema<DB>(\n schema: RLSSchema<DB>\n): RLSSchema<DB> {\n // Validate schema\n validateSchema(schema);\n return schema;\n}\n\n/**\n * Validate RLS schema\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validateSchema<DB>(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue;\n\n const tableConfig = config as TableRLSConfig;\n\n if (!Array.isArray(tableConfig.policies)) {\n throw new RLSSchemaError(\n `Invalid policies for table \"${table}\": must be an array`,\n { table }\n );\n }\n\n // Validate each policy\n for (let i = 0; i < tableConfig.policies.length; i++) {\n const policy = tableConfig.policies[i];\n if (policy !== undefined) {\n validatePolicy(policy, table, i);\n }\n }\n\n // Validate skipFor if present (array of role names that bypass RLS)\n if (tableConfig.skipFor !== undefined) {\n if (!Array.isArray(tableConfig.skipFor)) {\n throw new RLSSchemaError(\n `Invalid skipFor for table \"${table}\": must be an array of role names`,\n { table }\n );\n }\n\n // skipFor contains role names (strings), not operations\n for (const role of tableConfig.skipFor) {\n if (typeof role !== 'string' || role.trim() === '') {\n throw new RLSSchemaError(\n `Invalid role in skipFor for table \"${table}\": must be a non-empty string`,\n { table }\n );\n }\n }\n }\n\n // Validate defaultDeny if present\n if (tableConfig.defaultDeny !== undefined && typeof tableConfig.defaultDeny !== 'boolean') {\n throw new RLSSchemaError(\n `Invalid defaultDeny for table \"${table}\": must be a boolean`,\n { table }\n );\n }\n }\n}\n\n/**\n * Validate a single policy\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validatePolicy(\n policy: PolicyDefinition,\n table: string,\n index: number\n): void {\n if (!policy.type) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" missing type`,\n { table, index }\n );\n }\n\n const validTypes = ['allow', 'deny', 'filter', 'validate'];\n if (!validTypes.includes(policy.type)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid type: ${policy.type}`,\n { table, index, type: policy.type }\n );\n }\n\n if (!policy.operation) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" missing operation`,\n { table, index }\n );\n }\n\n const validOps = ['read', 'create', 'update', 'delete', 'all'];\n const ops = Array.isArray(policy.operation) ? policy.operation : [policy.operation];\n\n for (const op of ops) {\n if (!validOps.includes(op)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid operation: ${op}`,\n { table, index, operation: op }\n );\n }\n }\n\n if (policy.condition === undefined || policy.condition === null) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" missing condition`,\n { table, index }\n );\n }\n\n if (typeof policy.condition !== 'function' && typeof policy.condition !== 'string') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" condition must be a function or string`,\n { table, index }\n );\n }\n\n // Validate priority if present\n if (policy.priority !== undefined && typeof policy.priority !== 'number') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" priority must be a number`,\n { table, index }\n );\n }\n\n // Validate name if present\n if (policy.name !== undefined && typeof policy.name !== 'string') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" name must be a string`,\n { table, index }\n );\n }\n}\n\n/**\n * Merge multiple RLS schemas\n * Later schemas override earlier ones for the same table\n *\n * @example\n * ```typescript\n * const baseSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * },\n * });\n *\n * const adminSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * });\n *\n * // Merged schema will have both filters and admin allow\n * const merged = mergeRLSSchemas(baseSchema, adminSchema);\n * ```\n */\nexport function mergeRLSSchemas<DB>(\n ...schemas: RLSSchema<DB>[]\n): RLSSchema<DB> {\n const merged: RLSSchema<DB> = {};\n\n for (const schema of schemas) {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue;\n\n const existingConfig = merged[table as keyof DB] as TableRLSConfig | undefined;\n const newConfig = config as TableRLSConfig;\n\n if (existingConfig) {\n // Merge policies (append new policies)\n existingConfig.policies = [\n ...existingConfig.policies,\n ...newConfig.policies,\n ];\n\n // Merge skipFor (combine arrays and deduplicate)\n if (newConfig.skipFor) {\n const existingSkipFor = existingConfig.skipFor ?? [];\n const combinedSkipFor = [...existingSkipFor, ...newConfig.skipFor];\n existingConfig.skipFor = Array.from(new Set(combinedSkipFor));\n }\n\n // Override defaultDeny if explicitly set in new config\n if (newConfig.defaultDeny !== undefined) {\n existingConfig.defaultDeny = newConfig.defaultDeny;\n }\n } else {\n // Deep copy the config to avoid mutation\n merged[table as keyof DB] = {\n policies: [...newConfig.policies],\n skipFor: newConfig.skipFor ? [...newConfig.skipFor] : undefined,\n defaultDeny: newConfig.defaultDeny,\n } as any;\n }\n }\n }\n\n // Validate merged schema\n validateSchema(merged);\n\n return merged;\n}\n","/**\n * Fluent policy builders for Row-Level Security\n *\n * Provides intuitive builder functions for creating RLS policies:\n * - allow: Grants access when condition is true\n * - deny: Blocks access when condition is true (overrides allow)\n * - filter: Adds WHERE conditions to SELECT queries\n * - validate: Validates mutation data before execution\n */\n\nimport type {\n Operation,\n PolicyDefinition,\n PolicyCondition,\n FilterCondition,\n PolicyHints,\n} from './types.js';\n\n/**\n * Options for policy definitions\n */\nexport interface PolicyOptions {\n /** Policy name for debugging and identification */\n name?: string;\n /** Priority (higher runs first, deny policies default to 100) */\n priority?: number;\n /** Performance optimization hints */\n hints?: PolicyHints;\n}\n\n/**\n * Create an allow policy\n * Grants access when condition evaluates to true\n *\n * @example\n * ```typescript\n * // Allow users to read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Allow admins to do everything\n * allow('all', ctx => ctx.auth.roles.includes('admin'))\n *\n * // Allow with multiple operations\n * allow(['read', 'update'], ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Named policy with priority\n * allow('read', ctx => ctx.auth.roles.includes('verified'), {\n * name: 'verified-users-only',\n * priority: 10\n * })\n * ```\n */\nexport function allow(\n operation: Operation | Operation[],\n condition: PolicyCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const policy: PolicyDefinition = {\n type: 'allow',\n operation,\n condition: condition as PolicyCondition,\n priority: options?.priority ?? 0,\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n\n/**\n * Create a deny policy\n * Blocks access when condition evaluates to true (overrides allow)\n * If no condition is provided, always denies\n *\n * @example\n * ```typescript\n * // Deny access to banned users\n * deny('all', ctx => ctx.auth.attributes?.banned === true)\n *\n * // Deny deletions on archived records\n * deny('delete', ctx => ctx.row.archived === true)\n *\n * // Deny all access to sensitive table\n * deny('all')\n *\n * // Named deny with high priority\n * deny('all', ctx => ctx.auth.attributes?.suspended === true, {\n * name: 'block-suspended-users',\n * priority: 200\n * })\n * ```\n */\nexport function deny(\n operation: Operation | Operation[],\n condition?: PolicyCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const policy: PolicyDefinition = {\n type: 'deny',\n operation,\n condition: (condition ?? (() => true)) as PolicyCondition,\n priority: options?.priority ?? 100, // Deny policies run first by default\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n\n/**\n * Create a filter policy\n * Adds WHERE conditions to SELECT queries\n *\n * @example\n * ```typescript\n * // Filter by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n *\n * // Filter by organization with soft delete\n * filter('read', ctx => ({\n * organization_id: ctx.auth.organizationIds?.[0],\n * deleted_at: null\n * }))\n *\n * // Named filter\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }), {\n * name: 'tenant-filter'\n * })\n * ```\n */\nexport function filter(\n operation: 'read' | 'all',\n condition: FilterCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const policy: PolicyDefinition = {\n type: 'filter',\n operation: operation === 'all' ? 'read' : operation,\n condition: condition as unknown as PolicyCondition,\n priority: options?.priority ?? 0,\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n\n/**\n * Create a validate policy\n * Validates mutation data before execution\n *\n * @example\n * ```typescript\n * // Validate user can only set their own user_id\n * validate('create', ctx => ctx.data.userId === ctx.auth.userId)\n *\n * // Validate status transitions\n * validate('update', ctx => {\n * const { status } = ctx.data;\n * return !status || ['draft', 'published'].includes(status);\n * })\n *\n * // Apply to both create and update\n * validate('all', ctx => ctx.data.price >= 0)\n *\n * // Named validation\n * validate('create', ctx => validateEmail(ctx.data.email), {\n * name: 'validate-email'\n * })\n * ```\n */\nexport function validate(\n operation: 'create' | 'update' | 'all',\n condition: PolicyCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const ops: Operation[] = operation === 'all'\n ? ['create', 'update']\n : [operation];\n\n const policy: PolicyDefinition = {\n type: 'validate',\n operation: ops,\n condition: condition as PolicyCondition,\n priority: options?.priority ?? 0,\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n","/**\n * Policy Registry\n * Central registry for managing RLS policies across all tables\n *\n * The PolicyRegistry compiles and stores RLS policies for efficient runtime lookup.\n * It categorizes policies by type (allow/deny/filter/validate) and operation,\n * and provides methods to query policies for specific tables and operations.\n */\n\nimport type {\n Operation,\n PolicyDefinition,\n FilterCondition,\n RLSSchema,\n TableRLSConfig,\n CompiledPolicy,\n CompiledFilterPolicy,\n} from './types.js';\nimport { RLSSchemaError } from '../errors.js';\nimport { silentLogger, type KyseraLogger } from '@kysera/core';\n\n/**\n * Internal compiled policy with operations as Set for efficient lookup\n */\ninterface InternalCompiledPolicy {\n name: string;\n operations: Set<Operation>;\n type: 'allow' | 'deny' | 'validate';\n evaluate: (ctx: any) => boolean | Promise<boolean>;\n priority: number;\n}\n\n/**\n * Table policy configuration\n */\ninterface TablePolicyConfig {\n allows: InternalCompiledPolicy[];\n denies: InternalCompiledPolicy[];\n filters: CompiledFilterPolicy[];\n validates: InternalCompiledPolicy[];\n skipFor: string[]; // Role names that bypass RLS\n defaultDeny: boolean;\n}\n\n/**\n * Policy Registry\n * Manages and provides access to RLS policies\n */\nexport class PolicyRegistry<DB = unknown> {\n private tables = new Map<string, TablePolicyConfig>();\n private compiled = false;\n private logger: KyseraLogger;\n\n constructor(schema?: RLSSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger;\n if (schema) {\n this.loadSchema(schema);\n }\n }\n\n /**\n * Load and compile policies from schema\n *\n * @example\n * ```typescript\n * const registry = new PolicyRegistry<Database>();\n * registry.loadSchema({\n * users: {\n * policies: [\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * defaultDeny: true,\n * },\n * });\n * ```\n */\n loadSchema(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue;\n this.registerTable(table, config as TableRLSConfig);\n }\n this.compiled = true;\n }\n\n /**\n * Register policies for a single table\n *\n * @param table - Table name\n * @param config - Table RLS configuration\n */\n registerTable(table: string, config: TableRLSConfig): void {\n const tableConfig: TablePolicyConfig = {\n allows: [],\n denies: [],\n filters: [],\n validates: [],\n skipFor: config.skipFor ?? [],\n defaultDeny: config.defaultDeny ?? true,\n };\n\n // Compile and categorize policies\n for (let i = 0; i < config.policies.length; i++) {\n const policy = config.policies[i];\n if (!policy) continue;\n\n const policyName = policy.name ?? `${table}_policy_${i}`;\n\n try {\n if (policy.type === 'filter') {\n const compiled = this.compileFilterPolicy(policy, policyName);\n tableConfig.filters.push(compiled);\n } else {\n const compiled = this.compilePolicy(policy, policyName);\n\n switch (policy.type) {\n case 'allow':\n tableConfig.allows.push(compiled);\n break;\n case 'deny':\n tableConfig.denies.push(compiled);\n break;\n case 'validate':\n tableConfig.validates.push(compiled);\n break;\n }\n }\n } catch (error) {\n throw new RLSSchemaError(\n `Failed to compile policy \"${policyName}\" for table \"${table}\": ${error instanceof Error ? error.message : String(error)}`,\n { table, policy: policyName }\n );\n }\n }\n\n // Sort by priority (higher priority first)\n tableConfig.allows.sort((a, b) => b.priority - a.priority);\n tableConfig.denies.sort((a, b) => b.priority - a.priority);\n tableConfig.validates.sort((a, b) => b.priority - a.priority);\n\n this.tables.set(table, tableConfig);\n }\n\n /**\n * Register policies - supports both schema and table-based registration\n *\n * @overload Register a full schema\n * @overload Register policies for a single table (deprecated)\n */\n register(schemaOrTable: RLSSchema<DB>): void;\n register(\n schemaOrTable: keyof DB & string,\n policies: PolicyDefinition[],\n options?: {\n skipFor?: string[];\n defaultDeny?: boolean;\n }\n ): void;\n register(\n schemaOrTable: RLSSchema<DB> | (keyof DB & string),\n policies?: PolicyDefinition[],\n options?: {\n skipFor?: string[]; // Role names that bypass RLS\n defaultDeny?: boolean;\n }\n ): void {\n // If first argument is an object with policies, treat as schema\n if (typeof schemaOrTable === 'object' && schemaOrTable !== null) {\n this.loadSchema(schemaOrTable);\n return;\n }\n\n // Otherwise, treat as table-based registration\n const table = schemaOrTable as keyof DB & string;\n if (!policies) {\n throw new RLSSchemaError('Policies are required when registering by table name', { table });\n }\n\n const config: TableRLSConfig = {\n policies,\n };\n\n if (options?.skipFor !== undefined) {\n config.skipFor = options.skipFor;\n }\n\n if (options?.defaultDeny !== undefined) {\n config.defaultDeny = options.defaultDeny;\n }\n\n this.registerTable(table, config);\n }\n\n /**\n * Compile a policy definition into an internal compiled policy\n *\n * @param policy - Policy definition to compile\n * @param name - Policy name for debugging\n * @returns Compiled policy ready for evaluation\n */\n private compilePolicy(policy: PolicyDefinition, name: string): InternalCompiledPolicy {\n const operations = Array.isArray(policy.operation)\n ? policy.operation\n : [policy.operation];\n\n // Expand 'all' to all operations\n const expandedOps = operations.flatMap(op =>\n op === 'all' ? (['read', 'create', 'update', 'delete'] as const) : [op]\n ) as Operation[];\n\n return {\n name,\n operations: new Set(expandedOps),\n type: policy.type as 'allow' | 'deny' | 'validate',\n evaluate: policy.condition as (ctx: any) => boolean | Promise<boolean>,\n priority: policy.priority ?? (policy.type === 'deny' ? 100 : 0),\n };\n }\n\n /**\n * Compile a filter policy\n *\n * @param policy - Filter policy definition\n * @param name - Policy name for debugging\n * @returns Compiled filter policy\n */\n private compileFilterPolicy(policy: PolicyDefinition, name: string): CompiledFilterPolicy {\n const condition = policy.condition as unknown as FilterCondition;\n\n return {\n operation: 'read',\n getConditions: condition as (ctx: any) => Record<string, unknown>,\n name,\n };\n }\n\n /**\n * Convert internal compiled policy to public CompiledPolicy\n */\n private toCompiledPolicy(internal: InternalCompiledPolicy): CompiledPolicy {\n return {\n name: internal.name,\n type: internal.type,\n operation: Array.from(internal.operations),\n evaluate: internal.evaluate,\n priority: internal.priority,\n };\n }\n\n /**\n * Get allow policies for a table and operation\n */\n getAllows(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table);\n if (!config) return [];\n\n return config.allows\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p));\n }\n\n /**\n * Get deny policies for a table and operation\n */\n getDenies(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table);\n if (!config) return [];\n\n return config.denies\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p));\n }\n\n /**\n * Get validate policies for a table and operation\n */\n getValidates(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table);\n if (!config) return [];\n\n return config.validates\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p));\n }\n\n /**\n * Get filter policies for a table\n */\n getFilters(table: string): CompiledFilterPolicy[] {\n const config = this.tables.get(table);\n return config?.filters ?? [];\n }\n\n /**\n * Get roles that skip RLS for a table\n */\n getSkipFor(table: string): string[] {\n const config = this.tables.get(table);\n return config?.skipFor ?? [];\n }\n\n /**\n * Check if table has default deny\n */\n hasDefaultDeny(table: string): boolean {\n const config = this.tables.get(table);\n return config?.defaultDeny ?? true;\n }\n\n /**\n * Check if a table is registered\n */\n hasTable(table: string): boolean {\n return this.tables.has(table);\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys());\n }\n\n /**\n * Check if registry is compiled\n */\n isCompiled(): boolean {\n return this.compiled;\n }\n\n /**\n * Validate that all policies are properly defined\n *\n * This method checks for common issues:\n * - Tables with no policies and defaultDeny=false (warns)\n * - Tables with skipFor operations but no corresponding policies\n */\n validate(): void {\n for (const [table, config] of this.tables) {\n // Check that at least one operation has policies\n const hasPolicy =\n config.allows.length > 0 ||\n config.denies.length > 0 ||\n config.filters.length > 0 ||\n config.validates.length > 0;\n\n if (!hasPolicy && !config.defaultDeny) {\n // Warning: table has no policies and defaultDeny is false\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has no policies and defaultDeny is false. ` +\n `All operations will be allowed.`\n );\n }\n\n // Warn if skipFor includes operations that have policies\n if (config.skipFor.length > 0) {\n const opsWithPolicies = new Set<Operation>();\n\n for (const allow of config.allows) {\n allow.operations.forEach(op => opsWithPolicies.add(op));\n }\n for (const deny of config.denies) {\n deny.operations.forEach(op => opsWithPolicies.add(op));\n }\n for (const validate of config.validates) {\n validate.operations.forEach(op => opsWithPolicies.add(op));\n }\n if (config.filters.length > 0) {\n opsWithPolicies.add('read');\n }\n\n const skippedOpsWithPolicies = config.skipFor.filter(op => {\n // 'all' means skip all operations\n if (op === 'all') return opsWithPolicies.size > 0;\n // Check if this is an operation name (for backwards compatibility)\n return opsWithPolicies.has(op as Operation);\n });\n\n if (skippedOpsWithPolicies.length > 0) {\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has skipFor operations that also have policies: ${skippedOpsWithPolicies.join(', ')}. ` +\n `The policies will be ignored for these operations.`\n );\n }\n }\n }\n }\n\n /**\n * Clear all policies\n */\n clear(): void {\n this.tables.clear();\n this.compiled = false;\n }\n\n /**\n * Remove policies for a specific table\n */\n remove(table: string): void {\n this.tables.delete(table);\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { RLSContext } from './types.js';\n\n/**\n * AsyncLocalStorage instance for RLS context\n * Provides automatic context propagation across async boundaries\n */\nexport const rlsStorage = new AsyncLocalStorage<RLSContext>();\n","import { rlsStorage } from './storage.js';\nimport type { RLSContext, RLSAuthContext, RLSRequestContext } from './types.js';\nimport { RLSContextError, RLSContextValidationError } from '../errors.js';\n\n/**\n * Options for creating RLS context\n */\nexport interface CreateRLSContextOptions<TUser = unknown, TMeta = unknown> {\n auth: RLSAuthContext<TUser>;\n request?: Partial<RLSRequestContext>;\n meta?: TMeta;\n}\n\n/**\n * Create a new RLS context\n */\nexport function createRLSContext<TUser = unknown, TMeta = unknown>(\n options: CreateRLSContextOptions<TUser, TMeta>\n): RLSContext<TUser, TMeta> {\n validateAuthContext(options.auth);\n\n const context: RLSContext<TUser, TMeta> = {\n auth: {\n ...options.auth,\n isSystem: options.auth.isSystem ?? false, // Default to false if not provided\n },\n timestamp: new Date(),\n };\n\n if (options.request) {\n context.request = {\n ...options.request,\n timestamp: options.request.timestamp ?? new Date(),\n } as RLSRequestContext;\n }\n\n if (options.meta !== undefined) {\n context.meta = options.meta;\n }\n\n return context;\n}\n\n/**\n * Validate auth context\n */\nfunction validateAuthContext(auth: RLSAuthContext): void {\n if (auth.userId === undefined || auth.userId === null) {\n throw new RLSContextValidationError('userId is required in auth context', 'userId');\n }\n\n if (!Array.isArray(auth.roles)) {\n throw new RLSContextValidationError('roles must be an array', 'roles');\n }\n}\n\n/**\n * RLS Context Manager\n * Manages RLS context using AsyncLocalStorage for automatic propagation\n */\nclass RLSContextManager {\n /**\n * Run a synchronous function within an RLS context\n */\n run<T>(context: RLSContext, fn: () => T): T {\n return rlsStorage.run(context, fn);\n }\n\n /**\n * Run an async function within an RLS context\n */\n async runAsync<T>(context: RLSContext, fn: () => Promise<T>): Promise<T> {\n return rlsStorage.run(context, fn);\n }\n\n /**\n * Get current RLS context\n * @throws RLSContextError if no context is set\n */\n getContext(): RLSContext {\n const ctx = rlsStorage.getStore();\n if (!ctx) {\n throw new RLSContextError();\n }\n return ctx;\n }\n\n /**\n * Get current RLS context or null if not set\n */\n getContextOrNull(): RLSContext | null {\n return rlsStorage.getStore() ?? null;\n }\n\n /**\n * Check if running within RLS context\n */\n hasContext(): boolean {\n return rlsStorage.getStore() !== undefined;\n }\n\n /**\n * Get current auth context\n * @throws RLSContextError if no context is set\n */\n getAuth(): RLSAuthContext {\n return this.getContext().auth;\n }\n\n /**\n * Get current user ID\n * @throws RLSContextError if no context is set\n */\n getUserId(): string | number {\n return this.getAuth().userId;\n }\n\n /**\n * Get current tenant ID\n * @throws RLSContextError if no context is set\n */\n getTenantId(): string | number | undefined {\n return this.getAuth().tenantId;\n }\n\n /**\n * Check if current user has a specific role\n */\n hasRole(role: string): boolean {\n const ctx = this.getContextOrNull();\n return ctx?.auth.roles.includes(role) ?? false;\n }\n\n /**\n * Check if current user has a specific permission\n */\n hasPermission(permission: string): boolean {\n const ctx = this.getContextOrNull();\n return ctx?.auth.permissions?.includes(permission) ?? false;\n }\n\n /**\n * Check if current context is a system context (bypasses RLS)\n */\n isSystem(): boolean {\n const ctx = this.getContextOrNull();\n return ctx?.auth.isSystem ?? false;\n }\n\n /**\n * Create a system context for operations that should bypass RLS\n */\n asSystem<T>(fn: () => T): T {\n const currentCtx = this.getContextOrNull();\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context');\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true },\n };\n\n return this.run(systemCtx, fn);\n }\n\n /**\n * Create a system context for async operations\n */\n async asSystemAsync<T>(fn: () => Promise<T>): Promise<T> {\n const currentCtx = this.getContextOrNull();\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context');\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true },\n };\n\n return this.runAsync(systemCtx, fn);\n }\n}\n\n// Export singleton instance\nexport const rlsContext = new RLSContextManager();\n\n/**\n * Convenience function to run code within RLS context\n */\nexport function withRLSContext<T>(context: RLSContext, fn: () => T): T {\n return rlsContext.run(context, fn);\n}\n\n/**\n * Convenience function to run async code within RLS context\n */\nexport async function withRLSContextAsync<T>(\n context: RLSContext,\n fn: () => Promise<T>\n): Promise<T> {\n return rlsContext.runAsync(context, fn);\n}\n","/**\n * SELECT Query Transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\n\nimport type { SelectQueryBuilder } from 'kysely';\nimport type { PolicyRegistry } from '../policy/registry.js';\nimport type { PolicyEvaluationContext } from '../policy/types.js';\nimport type { RLSContext } from '../context/types.js';\nimport { rlsContext } from '../context/manager.js';\nimport { RLSError, RLSErrorCodes } from '../errors.js';\n\n/**\n * SELECT query transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\nexport class SelectTransformer<DB = unknown> {\n constructor(private registry: PolicyRegistry<DB>) {}\n\n /**\n * Transform a SELECT query by applying filter policies\n *\n * @param qb - The query builder to transform\n * @param table - Table name being queried\n * @returns Transformed query builder with RLS filters applied\n *\n * @example\n * ```typescript\n * const transformer = new SelectTransformer(registry);\n * let query = db.selectFrom('posts').selectAll();\n * query = transformer.transform(query, 'posts');\n * // Query now includes WHERE conditions from RLS policies\n * ```\n */\n transform<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n // Check for context\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) {\n // No context - return original query\n // In production, you might want to throw an error here\n return qb;\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n return qb;\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table);\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return qb;\n }\n\n // Get filter policies for this table\n const filters = this.registry.getFilters(table);\n if (filters.length === 0) {\n return qb;\n }\n\n // Apply each filter as WHERE condition\n let result = qb;\n for (const filter of filters) {\n const conditions = this.evaluateFilter(filter, ctx, table);\n result = this.applyConditions(result, conditions, table);\n }\n\n return result;\n }\n\n /**\n * Evaluate a filter policy to get WHERE conditions\n *\n * @param filter - The filter policy to evaluate\n * @param ctx - RLS context\n * @param table - Table name\n * @returns WHERE clause conditions as key-value pairs\n */\n private evaluateFilter(\n filter: { name: string; getConditions: (ctx: PolicyEvaluationContext) => Record<string, unknown> | Promise<Record<string, unknown>> },\n ctx: RLSContext,\n table: string\n ): Record<string, unknown> {\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> }),\n };\n\n const result = filter.getConditions(evalCtx);\n\n // Note: If async filters are needed, this method signature would need to change\n // For now, we assume synchronous filter evaluation\n if (result instanceof Promise) {\n throw new RLSError(\n `Async filter policies are not supported in SELECT transformers. ` +\n `Filter '${filter.name}' on table '${table}' returned a Promise. ` +\n `Use synchronous conditions for filter policies.`,\n RLSErrorCodes.RLS_POLICY_INVALID\n );\n }\n\n return result;\n }\n\n /**\n * Apply filter conditions to query builder\n *\n * @param qb - Query builder to modify\n * @param conditions - WHERE clause conditions\n * @param table - Table name (for qualified column names)\n * @returns Modified query builder\n */\n private applyConditions<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n conditions: Record<string, unknown>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n let result = qb;\n\n for (const [column, value] of Object.entries(conditions)) {\n // Use table-qualified column name to avoid ambiguity in joins\n const qualifiedColumn = `${table}.${column}` as any;\n\n if (value === null) {\n // NULL check\n result = result.where(qualifiedColumn, 'is', null);\n } else if (value === undefined) {\n // Skip undefined values\n continue;\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n // Empty array means no matches - add impossible condition\n // This ensures the query returns no rows\n result = result.where(qualifiedColumn, '=', '__RLS_NO_MATCH__' as any);\n } else {\n // IN clause for array values\n result = result.where(qualifiedColumn, 'in', value as any);\n }\n } else {\n // Equality check\n result = result.where(qualifiedColumn, '=', value as any);\n }\n }\n\n return result;\n }\n}\n","/**\n * Mutation Guard\n * Validates CREATE, UPDATE, DELETE operations against RLS policies\n */\n\nimport type { Kysely } from 'kysely';\nimport type { PolicyRegistry } from '../policy/registry.js';\nimport type { PolicyEvaluationContext, Operation } from '../policy/types.js';\nimport type { RLSContext } from '../context/types.js';\nimport { rlsContext } from '../context/manager.js';\nimport { RLSPolicyViolation } from '../errors.js';\n\n/**\n * Mutation guard\n * Validates mutations (CREATE, UPDATE, DELETE) against allow/deny/validate policies\n */\nexport class MutationGuard<DB = unknown> {\n constructor(\n private registry: PolicyRegistry<DB>,\n private executor?: Kysely<DB>\n ) {}\n\n /**\n * Check if CREATE operation is allowed\n *\n * @param table - Table name\n * @param data - Data being inserted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * await guard.checkCreate('posts', { title: 'Hello', tenant_id: 1 });\n * ```\n */\n async checkCreate(\n table: string,\n data: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'create', undefined, data);\n }\n\n /**\n * Check if UPDATE operation is allowed\n *\n * @param table - Table name\n * @param existingRow - Current row data\n * @param data - Data being updated\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const existingPost = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * await guard.checkUpdate('posts', existingPost, { title: 'Updated' });\n * ```\n */\n async checkUpdate(\n table: string,\n existingRow: Record<string, unknown>,\n data: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'update', existingRow, data);\n }\n\n /**\n * Check if DELETE operation is allowed\n *\n * @param table - Table name\n * @param existingRow - Row to be deleted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const existingPost = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * await guard.checkDelete('posts', existingPost);\n * ```\n */\n async checkDelete(\n table: string,\n existingRow: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'delete', existingRow);\n }\n\n /**\n * Check if READ operation is allowed on a specific row\n *\n * @param table - Table name\n * @param row - Row to check access for\n * @returns true if access is allowed\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const post = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * const canRead = await guard.checkRead('posts', post);\n * ```\n */\n async checkRead(\n table: string,\n row: Record<string, unknown>\n ): Promise<boolean> {\n try {\n await this.checkMutation(table, 'read', row);\n return true;\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n return false;\n }\n throw error;\n }\n }\n\n /**\n * Generic check for any operation (helper for testing)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @returns true if access is allowed, false otherwise\n */\n async canMutate(\n operation: Operation,\n table: string,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<boolean> {\n try {\n await this.checkMutation(table, operation, row, data);\n return true;\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n return false;\n }\n throw error;\n }\n }\n\n /**\n * Validate mutation data (for validate policies)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param data - New data (for CREATE/UPDATE)\n * @param row - Existing row (for UPDATE)\n * @returns true if valid, false otherwise\n */\n async validateMutation(\n operation: Operation,\n table: string,\n data: Record<string, unknown>,\n row?: Record<string, unknown>\n ): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) {\n return false;\n }\n\n // System users bypass validation\n if (ctx.auth.isSystem) {\n return true;\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table);\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true;\n }\n\n // Get validate policies for this operation\n const validates = this.registry.getValidates(table, operation);\n if (validates.length === 0) {\n return true;\n }\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n row: row,\n data: data,\n table: table,\n operation: operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> }),\n };\n\n // All validate policies must pass\n for (const validate of validates) {\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx);\n if (!result) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Check mutation against RLS policies\n *\n * @param table - Table name\n * @param operation - Operation type\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @throws RLSPolicyViolation if access is denied\n */\n private async checkMutation(\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<void> {\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) {\n throw new RLSPolicyViolation(\n operation,\n table,\n 'No RLS context available'\n );\n }\n\n // System users bypass all checks\n if (ctx.auth.isSystem) {\n return;\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table);\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return;\n }\n\n // Evaluate deny policies first (they override allows)\n const denies = this.registry.getDenies(table, operation);\n for (const deny of denies) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data);\n const result = await this.evaluatePolicy(deny.evaluate, evalCtx);\n\n if (result) {\n throw new RLSPolicyViolation(\n operation,\n table,\n `Denied by policy: ${deny.name}`\n );\n }\n }\n\n // Evaluate validate policies (for CREATE/UPDATE)\n if ((operation === 'create' || operation === 'update') && data) {\n const validates = this.registry.getValidates(table, operation);\n for (const validate of validates) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data);\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx);\n\n if (!result) {\n throw new RLSPolicyViolation(\n operation,\n table,\n `Validation failed: ${validate.name}`\n );\n }\n }\n }\n\n // Evaluate allow policies\n const allows = this.registry.getAllows(table, operation);\n const defaultDeny = this.registry.hasDefaultDeny(table);\n\n if (defaultDeny && allows.length === 0) {\n throw new RLSPolicyViolation(\n operation,\n table,\n 'No allow policies defined (default deny)'\n );\n }\n\n if (allows.length > 0) {\n // At least one allow policy must pass\n let allowed = false;\n\n for (const allow of allows) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data);\n const result = await this.evaluatePolicy(allow.evaluate, evalCtx);\n\n if (result) {\n allowed = true;\n break;\n }\n }\n\n if (!allowed) {\n throw new RLSPolicyViolation(\n operation,\n table,\n 'No allow policies matched'\n );\n }\n }\n }\n\n /**\n * Create policy evaluation context\n */\n private createEvalContext(\n ctx: RLSContext,\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n row,\n data,\n table,\n operation,\n metadata: ctx.meta,\n };\n }\n\n /**\n * Evaluate a policy condition\n */\n private async evaluatePolicy(\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n evalCtx: PolicyEvaluationContext\n ): Promise<boolean> {\n try {\n const result = condition(evalCtx);\n return result instanceof Promise ? await result : result;\n } catch (error) {\n // Policy evaluation errors are treated as denial\n throw new RLSPolicyViolation(\n evalCtx.operation,\n evalCtx.table,\n `Policy evaluation error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Filter an array of rows, keeping only accessible ones\n * Useful for post-query filtering when query-level filtering is not possible\n *\n * @param table - Table name\n * @param rows - Array of rows to filter\n * @returns Filtered array containing only accessible rows\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const allPosts = await db.selectFrom('posts').selectAll().execute();\n * const accessiblePosts = await guard.filterRows('posts', allPosts);\n * ```\n */\n async filterRows<T extends Record<string, unknown>>(\n table: string,\n rows: T[]\n ): Promise<T[]> {\n const results: T[] = [];\n\n for (const row of rows) {\n if (await this.checkRead(table, row)) {\n results.push(row);\n }\n }\n\n return results;\n }\n}\n","/**\n * RLS Plugin for Kysera Repository\n *\n * Implements Row-Level Security as a Kysera plugin, providing:\n * - Automatic query filtering for SELECT operations\n * - Policy enforcement for CREATE, UPDATE, DELETE operations\n * - Repository method extensions for RLS-aware operations\n * - System context bypass for privileged operations\n *\n * @module @kysera/rls\n */\n\nimport type { Plugin, QueryBuilderContext, AnyQueryBuilder } from '@kysera/repository';\nimport type { Kysely } from 'kysely';\nimport type { RLSSchema, Operation } from './policy/types.js';\nimport { PolicyRegistry } from './policy/registry.js';\nimport { SelectTransformer } from './transformer/select.js';\nimport { MutationGuard } from './transformer/mutation.js';\nimport { rlsContext } from './context/manager.js';\nimport { RLSContextError, RLSPolicyViolation, RLSError, RLSErrorCodes } from './errors.js';\nimport { silentLogger, type KyseraLogger } from '@kysera/core';\n\n/**\n * RLS Plugin configuration options\n */\nexport interface RLSPluginOptions<DB = unknown> {\n /** RLS policy schema */\n schema: RLSSchema<DB>;\n\n /** Tables to skip RLS for (always bypass policies) */\n skipTables?: string[];\n\n /** Roles that bypass RLS entirely (e.g., ['admin', 'superuser']) */\n bypassRoles?: string[];\n\n /** Logger instance for RLS operations */\n logger?: KyseraLogger;\n\n /** Require RLS context for all operations (throws if missing) */\n requireContext?: boolean;\n\n /** Enable audit logging of policy decisions */\n auditDecisions?: boolean;\n\n /** Custom error handler for policy violations */\n onViolation?: (violation: RLSPolicyViolation) => void;\n}\n\n/**\n * Base repository interface for type safety\n * @internal\n */\ninterface BaseRepository {\n tableName: string;\n executor: Kysely<Record<string, unknown>>;\n findById?: (id: unknown) => Promise<unknown>;\n create?: (data: unknown) => Promise<unknown>;\n update?: (id: unknown, data: unknown) => Promise<unknown>;\n delete?: (id: unknown) => Promise<unknown>;\n}\n\n/**\n * Create RLS plugin for Kysera\n *\n * The RLS plugin provides declarative row-level security for your database operations.\n * It automatically filters SELECT queries and validates mutations (CREATE, UPDATE, DELETE)\n * against your policy schema.\n *\n * @example\n * ```typescript\n * import { rlsPlugin, defineRLSSchema, allow, filter } from '@kysera/rls';\n * import { createORM } from '@kysera/repository';\n *\n * // Define your RLS schema\n * const schema = defineRLSSchema<Database>({\n * resources: {\n * policies: [\n * // Filter reads by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Allow updates for resource owners\n * allow('update', ctx => ctx.auth.userId === ctx.row.owner_id),\n * // Validate creates belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * },\n * });\n *\n * // Create ORM with RLS plugin\n * const orm = await createORM(db, [\n * rlsPlugin({ schema }),\n * ]);\n *\n * // Use within RLS context\n * await rlsContext.runAsync(\n * {\n * auth: { userId: 1, tenantId: 100, roles: ['user'], isSystem: false },\n * timestamp: new Date(),\n * },\n * async () => {\n * // All queries automatically filtered by tenant_id\n * const resources = await orm.resources.findAll();\n * }\n * );\n * ```\n *\n * @param options - Plugin configuration options\n * @returns Kysera plugin instance\n */\nexport function rlsPlugin<DB>(options: RLSPluginOptions<DB>): Plugin {\n const {\n schema,\n skipTables = [],\n bypassRoles = [],\n logger = silentLogger,\n requireContext = false,\n auditDecisions = false,\n onViolation,\n } = options;\n\n // Registry and transformers (initialized in onInit)\n let registry: PolicyRegistry<DB>;\n let selectTransformer: SelectTransformer<DB>;\n let mutationGuard: MutationGuard<DB>;\n\n return {\n name: '@kysera/rls',\n version: '0.5.1',\n\n // Run after soft-delete (priority 0), before audit\n priority: 50,\n\n // No dependencies by default\n dependencies: [],\n\n /**\n * Initialize plugin - compile policies\n */\n async onInit<TDB>(executor: Kysely<TDB>): Promise<void> {\n logger.info?.('[RLS] Initializing RLS plugin', {\n tables: Object.keys(schema).length,\n skipTables: skipTables.length,\n bypassRoles: bypassRoles.length,\n });\n\n // Create and compile registry\n registry = new PolicyRegistry<DB>(schema);\n registry.validate();\n\n // Create transformers\n selectTransformer = new SelectTransformer<DB>(registry);\n mutationGuard = new MutationGuard<DB>(registry, executor as unknown as Kysely<DB>);\n\n logger.info?.('[RLS] RLS plugin initialized successfully');\n },\n\n /**\n * Intercept queries to apply RLS filtering\n *\n * This hook is called for every query builder operation. For SELECT queries,\n * it applies filter policies as WHERE conditions. For mutations, it marks\n * that RLS validation is required (performed in extendRepository).\n */\n interceptQuery<QB extends AnyQueryBuilder>(\n qb: QB,\n context: QueryBuilderContext\n ): QB {\n const { operation, table, metadata } = context;\n\n // Skip if table is excluded\n if (skipTables.includes(table)) {\n logger.debug?.(`[RLS] Skipping RLS for excluded table: ${table}`);\n return qb;\n }\n\n // Skip if explicitly disabled via metadata\n if (metadata['skipRLS'] === true) {\n logger.debug?.(`[RLS] Skipping RLS (explicit skip): ${table}`);\n return qb;\n }\n\n // Check for context\n const ctx = rlsContext.getContextOrNull();\n\n if (!ctx) {\n if (requireContext) {\n throw new RLSContextError('RLS context required but not found');\n }\n logger.warn?.(`[RLS] No context for ${operation} on ${table}`);\n return qb;\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n logger.debug?.(`[RLS] Bypassing RLS (system user): ${table}`);\n return qb;\n }\n\n // Check bypass roles\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n logger.debug?.(`[RLS] Bypassing RLS (bypass role): ${table}`);\n return qb;\n }\n\n // Apply SELECT filtering\n if (operation === 'select') {\n try {\n const transformed = selectTransformer.transform(qb as any, table);\n\n if (auditDecisions) {\n logger.info?.('[RLS] Filter applied', {\n table,\n operation,\n userId: ctx.auth.userId,\n });\n }\n\n return transformed as QB;\n } catch (error) {\n logger.error?.('[RLS] Error applying filter', { table, error });\n throw error;\n }\n }\n\n // For mutations, mark that RLS check is needed (done in extendRepository)\n if (operation === 'insert' || operation === 'update' || operation === 'delete') {\n metadata['__rlsRequired'] = true;\n metadata['__rlsTable'] = table;\n }\n\n return qb;\n },\n\n /**\n * Extend repository with RLS-aware methods\n *\n * Wraps create, update, and delete methods to enforce RLS policies.\n * Also adds utility methods for bypassing RLS and checking access.\n */\n extendRepository<T extends object>(repo: T): T {\n const baseRepo = repo as unknown as BaseRepository;\n\n // Check if it's a valid repository\n if (!('tableName' in baseRepo) || !('executor' in baseRepo)) {\n return repo;\n }\n\n const table = baseRepo.tableName;\n\n // Skip excluded tables\n if (skipTables.includes(table)) {\n return repo;\n }\n\n // Skip if table not in schema\n if (!registry.hasTable(table)) {\n logger.debug?.(`[RLS] Table \"${table}\" not in RLS schema, skipping`);\n return repo;\n }\n\n logger.debug?.(`[RLS] Extending repository for table: ${table}`);\n\n // Store original methods\n const originalCreate = baseRepo.create?.bind(baseRepo);\n const originalUpdate = baseRepo.update?.bind(baseRepo);\n const originalDelete = baseRepo.delete?.bind(baseRepo);\n const originalFindById = baseRepo.findById?.bind(baseRepo);\n\n const extendedRepo = {\n ...baseRepo,\n\n /**\n * Wrapped create with RLS check\n */\n async create(data: unknown): Promise<unknown> {\n if (!originalCreate) {\n throw new RLSError('Repository does not support create operation', RLSErrorCodes.RLS_POLICY_INVALID);\n }\n\n const ctx = rlsContext.getContextOrNull();\n\n // Check RLS if context exists and not system/bypass\n if (ctx && !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n try {\n await mutationGuard.checkCreate(table, data as Record<string, unknown>);\n\n if (auditDecisions) {\n logger.info?.('[RLS] Create allowed', { table, userId: ctx.auth.userId });\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error);\n if (auditDecisions) {\n logger.warn?.('[RLS] Create denied', {\n table,\n userId: ctx.auth.userId,\n reason: error.reason\n });\n }\n }\n throw error;\n }\n }\n\n return originalCreate(data);\n },\n\n /**\n * Wrapped update with RLS check\n */\n async update(id: unknown, data: unknown): Promise<unknown> {\n if (!originalUpdate || !originalFindById) {\n throw new RLSError('Repository does not support update operation', RLSErrorCodes.RLS_POLICY_INVALID);\n }\n\n const ctx = rlsContext.getContextOrNull();\n\n if (ctx && !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n // Fetch existing row for policy evaluation\n const existingRow = await originalFindById(id);\n if (!existingRow) {\n // Let the original method handle not found\n return originalUpdate(id, data);\n }\n\n try {\n await mutationGuard.checkUpdate(\n table,\n existingRow as Record<string, unknown>,\n data as Record<string, unknown>\n );\n\n if (auditDecisions) {\n logger.info?.('[RLS] Update allowed', { table, id, userId: ctx.auth.userId });\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error);\n if (auditDecisions) {\n logger.warn?.('[RLS] Update denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n });\n }\n }\n throw error;\n }\n }\n\n return originalUpdate(id, data);\n },\n\n /**\n * Wrapped delete with RLS check\n */\n async delete(id: unknown): Promise<unknown> {\n if (!originalDelete || !originalFindById) {\n throw new RLSError('Repository does not support delete operation', RLSErrorCodes.RLS_POLICY_INVALID);\n }\n\n const ctx = rlsContext.getContextOrNull();\n\n if (ctx && !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n // Fetch existing row for policy evaluation\n const existingRow = await originalFindById(id);\n if (!existingRow) {\n // Let the original method handle not found\n return originalDelete(id);\n }\n\n try {\n await mutationGuard.checkDelete(table, existingRow as Record<string, unknown>);\n\n if (auditDecisions) {\n logger.info?.('[RLS] Delete allowed', { table, id, userId: ctx.auth.userId });\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error);\n if (auditDecisions) {\n logger.warn?.('[RLS] Delete denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n });\n }\n }\n throw error;\n }\n }\n\n return originalDelete(id);\n },\n\n /**\n * Bypass RLS for specific operation\n * Requires existing context\n *\n * @example\n * ```typescript\n * // Perform operation as system user\n * const result = await repo.withoutRLS(async () => {\n * return repo.findAll(); // No RLS filtering\n * });\n * ```\n */\n async withoutRLS<R>(fn: () => Promise<R>): Promise<R> {\n return rlsContext.asSystemAsync(fn);\n },\n\n /**\n * Check if current user can perform operation on a row\n *\n * @example\n * ```typescript\n * const post = await repo.findById(1);\n * const canUpdate = await repo.canAccess('update', post);\n * if (canUpdate) {\n * await repo.update(1, { title: 'New title' });\n * }\n * ```\n */\n async canAccess(operation: Operation, row: Record<string, unknown>): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) return false;\n if (ctx.auth.isSystem) return true;\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) return true;\n\n try {\n switch (operation) {\n case 'read':\n return await mutationGuard.checkRead(table, row);\n case 'create':\n await mutationGuard.checkCreate(table, row);\n return true;\n case 'update':\n await mutationGuard.checkUpdate(table, row, {});\n return true;\n case 'delete':\n await mutationGuard.checkDelete(table, row);\n return true;\n default:\n return false;\n }\n } catch (error) {\n logger.debug?.('[RLS] Access check failed', {\n table,\n operation,\n error: error instanceof Error ? error.message : String(error)\n });\n return false;\n }\n },\n };\n\n return extendedRepo as T;\n },\n };\n}\n","/**\n * Utility helper functions for RLS\n */\n\nimport type {\n RLSContext,\n PolicyEvaluationContext,\n Operation,\n} from '../policy/types.js';\n\n/**\n * Create a policy evaluation context from RLS context\n */\nexport function createEvaluationContext<\n TRow = unknown,\n TData = unknown\n>(\n rlsCtx: RLSContext,\n options?: {\n row?: TRow;\n data?: TData;\n }\n): PolicyEvaluationContext<unknown, TRow, TData> {\n const ctx: PolicyEvaluationContext<unknown, TRow, TData> = {\n auth: rlsCtx.auth,\n };\n\n if (options?.row !== undefined) {\n ctx.row = options.row;\n }\n\n if (options?.data !== undefined) {\n ctx.data = options.data;\n }\n\n if (rlsCtx.request !== undefined) {\n ctx.request = rlsCtx.request;\n }\n\n if (rlsCtx.meta !== undefined) {\n ctx.meta = rlsCtx.meta as Record<string, unknown>;\n }\n\n return ctx;\n}\n\n/**\n * Check if a condition function is async\n */\nexport function isAsyncFunction(fn: unknown): fn is (...args: unknown[]) => Promise<unknown> {\n return fn instanceof Function && fn.constructor.name === 'AsyncFunction';\n}\n\n/**\n * Safely evaluate a policy condition\n */\nexport async function safeEvaluate<T>(\n fn: () => T | Promise<T>,\n defaultValue: T\n): Promise<T> {\n try {\n const result = fn();\n if (result instanceof Promise) {\n return await result;\n }\n return result;\n } catch (error) {\n // Expected failure during policy evaluation - return default value\n // Logger not available in this utility function, error is handled gracefully\n return defaultValue;\n }\n}\n\n/**\n * Deep merge two objects\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceValue = source[key];\n const targetValue = result[key];\n\n if (\n sourceValue !== undefined &&\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[keyof T];\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as T[keyof T];\n }\n }\n\n return result;\n}\n\n/**\n * Create a simple hash for cache keys\n */\nexport function hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash.toString(36);\n}\n\n/**\n * Normalize operations to array format\n */\nexport function normalizeOperations(\n operation: Operation | Operation[]\n): Operation[] {\n if (Array.isArray(operation)) {\n if (operation.includes('all')) {\n return ['read', 'create', 'update', 'delete'];\n }\n return operation;\n }\n\n if (operation === 'all') {\n return ['read', 'create', 'update', 'delete'];\n }\n\n return [operation];\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/policy/schema.ts","../src/policy/builder.ts","../src/policy/registry.ts","../src/context/storage.ts","../src/context/manager.ts","../src/transformer/select.ts","../src/transformer/mutation.ts","../src/plugin.ts","../src/utils/helpers.ts"],"names":["allow","deny","validate","filter","silentLogger"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * RLS Error Classes\n *\n * This module provides specialized error classes for Row-Level Security operations.\n * All errors extend the base RLSError class and use unified error codes from @kysera/core\n * for consistency across the Kysera ecosystem.\n *\n * @module @kysera/rls/errors\n */\n\nimport type { ErrorCode } from '@kysera/core';\n\n// ============================================================================\n// RLS Error Codes\n// ============================================================================\n\n/**\n * RLS-specific error codes\n *\n * These codes extend the unified error codes from @kysera/core with\n * RLS-specific error conditions.\n */\nexport const RLSErrorCodes = {\n /** RLS context is missing or not set */\n RLS_CONTEXT_MISSING: 'RLS_CONTEXT_MISSING' as ErrorCode,\n /** RLS policy violation occurred */\n RLS_POLICY_VIOLATION: 'RLS_POLICY_VIOLATION' as ErrorCode,\n /** RLS policy definition is invalid */\n RLS_POLICY_INVALID: 'RLS_POLICY_INVALID' as ErrorCode,\n /** RLS schema definition is invalid */\n RLS_SCHEMA_INVALID: 'RLS_SCHEMA_INVALID' as ErrorCode,\n /** RLS context validation failed */\n RLS_CONTEXT_INVALID: 'RLS_CONTEXT_INVALID' as ErrorCode,\n} as const;\n\n/**\n * Type for RLS error codes\n */\nexport type RLSErrorCode = typeof RLSErrorCodes[keyof typeof RLSErrorCodes];\n\n// ============================================================================\n// Base RLS Error\n// ============================================================================\n\n/**\n * Base class for all RLS-related errors\n *\n * Provides common error functionality including error codes and JSON serialization.\n *\n * @example\n * ```typescript\n * throw new RLSError('Something went wrong', RLSErrorCodes.RLS_POLICY_INVALID);\n * ```\n */\nexport class RLSError extends Error {\n public readonly code: RLSErrorCode;\n\n /**\n * Creates a new RLS error\n *\n * @param message - Error message\n * @param code - RLS error code\n */\n constructor(message: string, code: RLSErrorCode) {\n super(message);\n this.name = 'RLSError';\n this.code = code;\n }\n\n /**\n * Serializes the error to JSON\n *\n * @returns JSON representation of the error\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n };\n }\n}\n\n// ============================================================================\n// Context Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS context is missing\n *\n * This error occurs when an operation requiring RLS context is executed\n * outside of a context scope (i.e., without calling withRLSContext()).\n *\n * @example\n * ```typescript\n * // This will throw RLSContextError\n * const result = await db.selectFrom('posts').execute();\n *\n * // Correct usage with context\n * await withRLSContext(rlsContext, async () => {\n * const result = await db.selectFrom('posts').execute();\n * });\n * ```\n */\nexport class RLSContextError extends RLSError {\n /**\n * Creates a new RLS context error\n *\n * @param message - Error message (defaults to standard message)\n */\n constructor(message: string = 'No RLS context found. Ensure code runs within withRLSContext()') {\n super(message, RLSErrorCodes.RLS_CONTEXT_MISSING);\n this.name = 'RLSContextError';\n }\n}\n\n/**\n * Error thrown when RLS context validation fails\n *\n * This error occurs when the provided RLS context is invalid or missing\n * required fields.\n *\n * @example\n * ```typescript\n * // Missing required userId field\n * const invalidContext = {\n * auth: {\n * roles: ['user']\n * // userId is missing!\n * },\n * timestamp: new Date()\n * };\n *\n * // This will throw RLSContextValidationError\n * validateRLSContext(invalidContext);\n * ```\n */\nexport class RLSContextValidationError extends RLSError {\n public readonly field: string;\n\n /**\n * Creates a new context validation error\n *\n * @param message - Error message\n * @param field - Field that failed validation\n */\n constructor(message: string, field: string) {\n super(message, RLSErrorCodes.RLS_CONTEXT_INVALID);\n this.name = 'RLSContextValidationError';\n this.field = field;\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n field: this.field,\n };\n }\n}\n\n// ============================================================================\n// Policy Errors\n// ============================================================================\n\n/**\n * Error thrown when an RLS policy violation occurs\n *\n * This error is thrown when a database operation is denied by RLS policies.\n * It provides detailed information about the violation including the operation,\n * table, and reason for denial.\n *\n * @example\n * ```typescript\n * // User tries to update a post they don't own\n * throw new RLSPolicyViolation(\n * 'update',\n * 'posts',\n * 'User does not own this post',\n * 'ownership_policy'\n * );\n * ```\n */\nexport class RLSPolicyViolation extends RLSError {\n public readonly operation: string;\n public readonly table: string;\n public readonly reason: string;\n public readonly policyName?: string;\n\n /**\n * Creates a new policy violation error\n *\n * @param operation - Database operation that was denied (read, create, update, delete)\n * @param table - Table name where violation occurred\n * @param reason - Reason for the policy violation\n * @param policyName - Name of the policy that denied access (optional)\n */\n constructor(\n operation: string,\n table: string,\n reason: string,\n policyName?: string\n ) {\n super(\n `RLS policy violation: ${operation} on ${table} - ${reason}`,\n RLSErrorCodes.RLS_POLICY_VIOLATION\n );\n this.name = 'RLSPolicyViolation';\n this.operation = operation;\n this.table = table;\n this.reason = reason;\n if (policyName !== undefined) {\n this.policyName = policyName;\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n ...super.toJSON(),\n operation: this.operation,\n table: this.table,\n reason: this.reason,\n };\n if (this.policyName !== undefined) {\n json['policyName'] = this.policyName;\n }\n return json;\n }\n}\n\n// ============================================================================\n// Schema Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS schema validation fails\n *\n * This error occurs when the RLS schema definition is invalid or contains\n * configuration errors.\n *\n * @example\n * ```typescript\n * // Invalid policy definition\n * const invalidSchema = {\n * posts: {\n * policies: [\n * {\n * type: 'invalid-type', // Invalid policy type!\n * operation: 'read',\n * condition: (ctx) => true\n * }\n * ]\n * }\n * };\n *\n * // This will throw RLSSchemaError\n * validateRLSSchema(invalidSchema);\n * ```\n */\nexport class RLSSchemaError extends RLSError {\n public readonly details: Record<string, unknown>;\n\n /**\n * Creates a new schema validation error\n *\n * @param message - Error message\n * @param details - Additional details about the validation failure\n */\n constructor(message: string, details: Record<string, unknown> = {}) {\n super(message, RLSErrorCodes.RLS_SCHEMA_INVALID);\n this.name = 'RLSSchemaError';\n this.details = details;\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n details: this.details,\n };\n }\n}\n","/**\n * RLS schema definition and validation\n *\n * Provides functions to define, validate, and merge RLS schemas.\n */\n\nimport type { RLSSchema, TableRLSConfig, PolicyDefinition } from './types.js';\nimport { RLSSchemaError } from '../errors.js';\n\n/**\n * Define RLS schema with full type safety\n *\n * @example\n * ```typescript\n * interface Database {\n * users: { id: number; email: string; tenant_id: number };\n * posts: { id: number; user_id: number; tenant_id: number };\n * }\n *\n * const schema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * // Users can read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * // Filter by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Admins bypass all checks\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * posts: {\n * policies: [\n * // Filter posts by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Users can only edit their own posts\n * allow(['update', 'delete'], ctx => ctx.auth.userId === ctx.row.user_id),\n * // Validate new posts belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * defaultDeny: true, // Require explicit allow\n * },\n * });\n * ```\n */\nexport function defineRLSSchema<DB>(\n schema: RLSSchema<DB>\n): RLSSchema<DB> {\n // Validate schema\n validateSchema(schema);\n return schema;\n}\n\n/**\n * Validate RLS schema\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validateSchema<DB>(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue;\n\n const tableConfig = config as TableRLSConfig;\n\n if (!Array.isArray(tableConfig.policies)) {\n throw new RLSSchemaError(\n `Invalid policies for table \"${table}\": must be an array`,\n { table }\n );\n }\n\n // Validate each policy\n for (let i = 0; i < tableConfig.policies.length; i++) {\n const policy = tableConfig.policies[i];\n if (policy !== undefined) {\n validatePolicy(policy, table, i);\n }\n }\n\n // Validate skipFor if present (array of role names that bypass RLS)\n if (tableConfig.skipFor !== undefined) {\n if (!Array.isArray(tableConfig.skipFor)) {\n throw new RLSSchemaError(\n `Invalid skipFor for table \"${table}\": must be an array of role names`,\n { table }\n );\n }\n\n // skipFor contains role names (strings), not operations\n for (const role of tableConfig.skipFor) {\n if (typeof role !== 'string' || role.trim() === '') {\n throw new RLSSchemaError(\n `Invalid role in skipFor for table \"${table}\": must be a non-empty string`,\n { table }\n );\n }\n }\n }\n\n // Validate defaultDeny if present\n if (tableConfig.defaultDeny !== undefined && typeof tableConfig.defaultDeny !== 'boolean') {\n throw new RLSSchemaError(\n `Invalid defaultDeny for table \"${table}\": must be a boolean`,\n { table }\n );\n }\n }\n}\n\n/**\n * Validate a single policy\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validatePolicy(\n policy: PolicyDefinition,\n table: string,\n index: number\n): void {\n if (!policy.type) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" missing type`,\n { table, index }\n );\n }\n\n const validTypes = ['allow', 'deny', 'filter', 'validate'];\n if (!validTypes.includes(policy.type)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid type: ${policy.type}`,\n { table, index, type: policy.type }\n );\n }\n\n if (!policy.operation) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" missing operation`,\n { table, index }\n );\n }\n\n const validOps = ['read', 'create', 'update', 'delete', 'all'];\n const ops = Array.isArray(policy.operation) ? policy.operation : [policy.operation];\n\n for (const op of ops) {\n if (!validOps.includes(op)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid operation: ${op}`,\n { table, index, operation: op }\n );\n }\n }\n\n if (policy.condition === undefined || policy.condition === null) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" missing condition`,\n { table, index }\n );\n }\n\n if (typeof policy.condition !== 'function' && typeof policy.condition !== 'string') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" condition must be a function or string`,\n { table, index }\n );\n }\n\n // Validate priority if present\n if (policy.priority !== undefined && typeof policy.priority !== 'number') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" priority must be a number`,\n { table, index }\n );\n }\n\n // Validate name if present\n if (policy.name !== undefined && typeof policy.name !== 'string') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" name must be a string`,\n { table, index }\n );\n }\n}\n\n/**\n * Merge multiple RLS schemas\n * Later schemas override earlier ones for the same table\n *\n * @example\n * ```typescript\n * const baseSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * },\n * });\n *\n * const adminSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * });\n *\n * // Merged schema will have both filters and admin allow\n * const merged = mergeRLSSchemas(baseSchema, adminSchema);\n * ```\n */\nexport function mergeRLSSchemas<DB>(\n ...schemas: RLSSchema<DB>[]\n): RLSSchema<DB> {\n const merged: RLSSchema<DB> = {};\n\n for (const schema of schemas) {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue;\n\n const existingConfig = merged[table as keyof DB] as TableRLSConfig | undefined;\n const newConfig = config as TableRLSConfig;\n\n if (existingConfig) {\n // Merge policies (append new policies)\n existingConfig.policies = [\n ...existingConfig.policies,\n ...newConfig.policies,\n ];\n\n // Merge skipFor (combine arrays and deduplicate)\n if (newConfig.skipFor) {\n const existingSkipFor = existingConfig.skipFor ?? [];\n const combinedSkipFor = [...existingSkipFor, ...newConfig.skipFor];\n existingConfig.skipFor = Array.from(new Set(combinedSkipFor));\n }\n\n // Override defaultDeny if explicitly set in new config\n if (newConfig.defaultDeny !== undefined) {\n existingConfig.defaultDeny = newConfig.defaultDeny;\n }\n } else {\n // Deep copy the config to avoid mutation\n merged[table as keyof DB] = {\n policies: [...newConfig.policies],\n skipFor: newConfig.skipFor ? [...newConfig.skipFor] : undefined,\n defaultDeny: newConfig.defaultDeny,\n } as any;\n }\n }\n }\n\n // Validate merged schema\n validateSchema(merged);\n\n return merged;\n}\n","/**\n * Fluent policy builders for Row-Level Security\n *\n * Provides intuitive builder functions for creating RLS policies:\n * - allow: Grants access when condition is true\n * - deny: Blocks access when condition is true (overrides allow)\n * - filter: Adds WHERE conditions to SELECT queries\n * - validate: Validates mutation data before execution\n */\n\nimport type {\n Operation,\n PolicyDefinition,\n PolicyCondition,\n FilterCondition,\n PolicyHints,\n} from './types.js';\n\n/**\n * Options for policy definitions\n */\nexport interface PolicyOptions {\n /** Policy name for debugging and identification */\n name?: string;\n /** Priority (higher runs first, deny policies default to 100) */\n priority?: number;\n /** Performance optimization hints */\n hints?: PolicyHints;\n}\n\n/**\n * Create an allow policy\n * Grants access when condition evaluates to true\n *\n * @example\n * ```typescript\n * // Allow users to read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Allow admins to do everything\n * allow('all', ctx => ctx.auth.roles.includes('admin'))\n *\n * // Allow with multiple operations\n * allow(['read', 'update'], ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Named policy with priority\n * allow('read', ctx => ctx.auth.roles.includes('verified'), {\n * name: 'verified-users-only',\n * priority: 10\n * })\n * ```\n */\nexport function allow(\n operation: Operation | Operation[],\n condition: PolicyCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const policy: PolicyDefinition = {\n type: 'allow',\n operation,\n condition: condition as PolicyCondition,\n priority: options?.priority ?? 0,\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n\n/**\n * Create a deny policy\n * Blocks access when condition evaluates to true (overrides allow)\n * If no condition is provided, always denies\n *\n * @example\n * ```typescript\n * // Deny access to banned users\n * deny('all', ctx => ctx.auth.attributes?.banned === true)\n *\n * // Deny deletions on archived records\n * deny('delete', ctx => ctx.row.archived === true)\n *\n * // Deny all access to sensitive table\n * deny('all')\n *\n * // Named deny with high priority\n * deny('all', ctx => ctx.auth.attributes?.suspended === true, {\n * name: 'block-suspended-users',\n * priority: 200\n * })\n * ```\n */\nexport function deny(\n operation: Operation | Operation[],\n condition?: PolicyCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const policy: PolicyDefinition = {\n type: 'deny',\n operation,\n condition: (condition ?? (() => true)) as PolicyCondition,\n priority: options?.priority ?? 100, // Deny policies run first by default\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n\n/**\n * Create a filter policy\n * Adds WHERE conditions to SELECT queries\n *\n * @example\n * ```typescript\n * // Filter by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n *\n * // Filter by organization with soft delete\n * filter('read', ctx => ({\n * organization_id: ctx.auth.organizationIds?.[0],\n * deleted_at: null\n * }))\n *\n * // Named filter\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }), {\n * name: 'tenant-filter'\n * })\n * ```\n */\nexport function filter(\n operation: 'read' | 'all',\n condition: FilterCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const policy: PolicyDefinition = {\n type: 'filter',\n operation: operation === 'all' ? 'read' : operation,\n condition: condition as unknown as PolicyCondition,\n priority: options?.priority ?? 0,\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n\n/**\n * Create a validate policy\n * Validates mutation data before execution\n *\n * @example\n * ```typescript\n * // Validate user can only set their own user_id\n * validate('create', ctx => ctx.data.userId === ctx.auth.userId)\n *\n * // Validate status transitions\n * validate('update', ctx => {\n * const { status } = ctx.data;\n * return !status || ['draft', 'published'].includes(status);\n * })\n *\n * // Apply to both create and update\n * validate('all', ctx => ctx.data.price >= 0)\n *\n * // Named validation\n * validate('create', ctx => validateEmail(ctx.data.email), {\n * name: 'validate-email'\n * })\n * ```\n */\nexport function validate(\n operation: 'create' | 'update' | 'all',\n condition: PolicyCondition,\n options?: PolicyOptions\n): PolicyDefinition {\n const ops: Operation[] = operation === 'all'\n ? ['create', 'update']\n : [operation];\n\n const policy: PolicyDefinition = {\n type: 'validate',\n operation: ops,\n condition: condition as PolicyCondition,\n priority: options?.priority ?? 0,\n };\n\n if (options?.name !== undefined) {\n policy.name = options.name;\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints;\n }\n\n return policy;\n}\n","/**\n * Policy Registry\n * Central registry for managing RLS policies across all tables\n *\n * The PolicyRegistry compiles and stores RLS policies for efficient runtime lookup.\n * It categorizes policies by type (allow/deny/filter/validate) and operation,\n * and provides methods to query policies for specific tables and operations.\n */\n\nimport type {\n Operation,\n PolicyDefinition,\n FilterCondition,\n RLSSchema,\n TableRLSConfig,\n CompiledPolicy,\n CompiledFilterPolicy,\n} from './types.js';\nimport { RLSSchemaError } from '../errors.js';\nimport { silentLogger, type KyseraLogger } from '@kysera/core';\n\n/**\n * Internal compiled policy with operations as Set for efficient lookup\n */\ninterface InternalCompiledPolicy {\n name: string;\n operations: Set<Operation>;\n type: 'allow' | 'deny' | 'validate';\n evaluate: (ctx: any) => boolean | Promise<boolean>;\n priority: number;\n}\n\n/**\n * Table policy configuration\n */\ninterface TablePolicyConfig {\n allows: InternalCompiledPolicy[];\n denies: InternalCompiledPolicy[];\n filters: CompiledFilterPolicy[];\n validates: InternalCompiledPolicy[];\n skipFor: string[]; // Role names that bypass RLS\n defaultDeny: boolean;\n}\n\n/**\n * Policy Registry\n * Manages and provides access to RLS policies\n */\nexport class PolicyRegistry<DB = unknown> {\n private tables = new Map<string, TablePolicyConfig>();\n private compiled = false;\n private logger: KyseraLogger;\n\n constructor(schema?: RLSSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger;\n if (schema) {\n this.loadSchema(schema);\n }\n }\n\n /**\n * Load and compile policies from schema\n *\n * @example\n * ```typescript\n * const registry = new PolicyRegistry<Database>();\n * registry.loadSchema({\n * users: {\n * policies: [\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * defaultDeny: true,\n * },\n * });\n * ```\n */\n loadSchema(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue;\n this.registerTable(table, config as TableRLSConfig);\n }\n this.compiled = true;\n }\n\n /**\n * Register policies for a single table\n *\n * @param table - Table name\n * @param config - Table RLS configuration\n */\n registerTable(table: string, config: TableRLSConfig): void {\n const tableConfig: TablePolicyConfig = {\n allows: [],\n denies: [],\n filters: [],\n validates: [],\n skipFor: config.skipFor ?? [],\n defaultDeny: config.defaultDeny ?? true,\n };\n\n // Compile and categorize policies\n for (let i = 0; i < config.policies.length; i++) {\n const policy = config.policies[i];\n if (!policy) continue;\n\n const policyName = policy.name ?? `${table}_policy_${i}`;\n\n try {\n if (policy.type === 'filter') {\n const compiled = this.compileFilterPolicy(policy, policyName);\n tableConfig.filters.push(compiled);\n } else {\n const compiled = this.compilePolicy(policy, policyName);\n\n switch (policy.type) {\n case 'allow':\n tableConfig.allows.push(compiled);\n break;\n case 'deny':\n tableConfig.denies.push(compiled);\n break;\n case 'validate':\n tableConfig.validates.push(compiled);\n break;\n }\n }\n } catch (error) {\n throw new RLSSchemaError(\n `Failed to compile policy \"${policyName}\" for table \"${table}\": ${error instanceof Error ? error.message : String(error)}`,\n { table, policy: policyName }\n );\n }\n }\n\n // Sort by priority (higher priority first)\n tableConfig.allows.sort((a, b) => b.priority - a.priority);\n tableConfig.denies.sort((a, b) => b.priority - a.priority);\n tableConfig.validates.sort((a, b) => b.priority - a.priority);\n\n this.tables.set(table, tableConfig);\n }\n\n /**\n * Register policies - supports both schema and table-based registration\n *\n * @overload Register a full schema\n * @overload Register policies for a single table (deprecated)\n */\n register(schemaOrTable: RLSSchema<DB>): void;\n register(\n schemaOrTable: keyof DB & string,\n policies: PolicyDefinition[],\n options?: {\n skipFor?: string[];\n defaultDeny?: boolean;\n }\n ): void;\n register(\n schemaOrTable: RLSSchema<DB> | (keyof DB & string),\n policies?: PolicyDefinition[],\n options?: {\n skipFor?: string[]; // Role names that bypass RLS\n defaultDeny?: boolean;\n }\n ): void {\n // If first argument is an object with policies, treat as schema\n if (typeof schemaOrTable === 'object' && schemaOrTable !== null) {\n this.loadSchema(schemaOrTable);\n return;\n }\n\n // Otherwise, treat as table-based registration\n const table = schemaOrTable as keyof DB & string;\n if (!policies) {\n throw new RLSSchemaError('Policies are required when registering by table name', { table });\n }\n\n const config: TableRLSConfig = {\n policies,\n };\n\n if (options?.skipFor !== undefined) {\n config.skipFor = options.skipFor;\n }\n\n if (options?.defaultDeny !== undefined) {\n config.defaultDeny = options.defaultDeny;\n }\n\n this.registerTable(table, config);\n }\n\n /**\n * Compile a policy definition into an internal compiled policy\n *\n * @param policy - Policy definition to compile\n * @param name - Policy name for debugging\n * @returns Compiled policy ready for evaluation\n */\n private compilePolicy(policy: PolicyDefinition, name: string): InternalCompiledPolicy {\n const operations = Array.isArray(policy.operation)\n ? policy.operation\n : [policy.operation];\n\n // Expand 'all' to all operations\n const expandedOps = operations.flatMap(op =>\n op === 'all' ? (['read', 'create', 'update', 'delete'] as const) : [op]\n ) as Operation[];\n\n return {\n name,\n operations: new Set(expandedOps),\n type: policy.type as 'allow' | 'deny' | 'validate',\n evaluate: policy.condition as (ctx: any) => boolean | Promise<boolean>,\n priority: policy.priority ?? (policy.type === 'deny' ? 100 : 0),\n };\n }\n\n /**\n * Compile a filter policy\n *\n * @param policy - Filter policy definition\n * @param name - Policy name for debugging\n * @returns Compiled filter policy\n */\n private compileFilterPolicy(policy: PolicyDefinition, name: string): CompiledFilterPolicy {\n const condition = policy.condition as unknown as FilterCondition;\n\n return {\n operation: 'read',\n getConditions: condition as (ctx: any) => Record<string, unknown>,\n name,\n };\n }\n\n /**\n * Convert internal compiled policy to public CompiledPolicy\n */\n private toCompiledPolicy(internal: InternalCompiledPolicy): CompiledPolicy {\n return {\n name: internal.name,\n type: internal.type,\n operation: Array.from(internal.operations),\n evaluate: internal.evaluate,\n priority: internal.priority,\n };\n }\n\n /**\n * Get allow policies for a table and operation\n */\n getAllows(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table);\n if (!config) return [];\n\n return config.allows\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p));\n }\n\n /**\n * Get deny policies for a table and operation\n */\n getDenies(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table);\n if (!config) return [];\n\n return config.denies\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p));\n }\n\n /**\n * Get validate policies for a table and operation\n */\n getValidates(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table);\n if (!config) return [];\n\n return config.validates\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p));\n }\n\n /**\n * Get filter policies for a table\n */\n getFilters(table: string): CompiledFilterPolicy[] {\n const config = this.tables.get(table);\n return config?.filters ?? [];\n }\n\n /**\n * Get roles that skip RLS for a table\n */\n getSkipFor(table: string): string[] {\n const config = this.tables.get(table);\n return config?.skipFor ?? [];\n }\n\n /**\n * Check if table has default deny\n */\n hasDefaultDeny(table: string): boolean {\n const config = this.tables.get(table);\n return config?.defaultDeny ?? true;\n }\n\n /**\n * Check if a table is registered\n */\n hasTable(table: string): boolean {\n return this.tables.has(table);\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys());\n }\n\n /**\n * Check if registry is compiled\n */\n isCompiled(): boolean {\n return this.compiled;\n }\n\n /**\n * Validate that all policies are properly defined\n *\n * This method checks for common issues:\n * - Tables with no policies and defaultDeny=false (warns)\n * - Tables with skipFor operations but no corresponding policies\n */\n validate(): void {\n for (const [table, config] of this.tables) {\n // Check that at least one operation has policies\n const hasPolicy =\n config.allows.length > 0 ||\n config.denies.length > 0 ||\n config.filters.length > 0 ||\n config.validates.length > 0;\n\n if (!hasPolicy && !config.defaultDeny) {\n // Warning: table has no policies and defaultDeny is false\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has no policies and defaultDeny is false. ` +\n `All operations will be allowed.`\n );\n }\n\n // Warn if skipFor includes operations that have policies\n if (config.skipFor.length > 0) {\n const opsWithPolicies = new Set<Operation>();\n\n for (const allow of config.allows) {\n allow.operations.forEach(op => opsWithPolicies.add(op));\n }\n for (const deny of config.denies) {\n deny.operations.forEach(op => opsWithPolicies.add(op));\n }\n for (const validate of config.validates) {\n validate.operations.forEach(op => opsWithPolicies.add(op));\n }\n if (config.filters.length > 0) {\n opsWithPolicies.add('read');\n }\n\n const skippedOpsWithPolicies = config.skipFor.filter(op => {\n // 'all' means skip all operations\n if (op === 'all') return opsWithPolicies.size > 0;\n // Check if this is an operation name (for backwards compatibility)\n return opsWithPolicies.has(op as Operation);\n });\n\n if (skippedOpsWithPolicies.length > 0) {\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has skipFor operations that also have policies: ${skippedOpsWithPolicies.join(', ')}. ` +\n `The policies will be ignored for these operations.`\n );\n }\n }\n }\n }\n\n /**\n * Clear all policies\n */\n clear(): void {\n this.tables.clear();\n this.compiled = false;\n }\n\n /**\n * Remove policies for a specific table\n */\n remove(table: string): void {\n this.tables.delete(table);\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { RLSContext } from './types.js';\n\n/**\n * AsyncLocalStorage instance for RLS context\n * Provides automatic context propagation across async boundaries\n */\nexport const rlsStorage = new AsyncLocalStorage<RLSContext>();\n","import { rlsStorage } from './storage.js';\nimport type { RLSContext, RLSAuthContext, RLSRequestContext } from './types.js';\nimport { RLSContextError, RLSContextValidationError } from '../errors.js';\n\n/**\n * Options for creating RLS context\n */\nexport interface CreateRLSContextOptions<TUser = unknown, TMeta = unknown> {\n auth: RLSAuthContext<TUser>;\n request?: Partial<RLSRequestContext>;\n meta?: TMeta;\n}\n\n/**\n * Create a new RLS context\n */\nexport function createRLSContext<TUser = unknown, TMeta = unknown>(\n options: CreateRLSContextOptions<TUser, TMeta>\n): RLSContext<TUser, TMeta> {\n validateAuthContext(options.auth);\n\n const context: RLSContext<TUser, TMeta> = {\n auth: {\n ...options.auth,\n isSystem: options.auth.isSystem ?? false, // Default to false if not provided\n },\n timestamp: new Date(),\n };\n\n if (options.request) {\n context.request = {\n ...options.request,\n timestamp: options.request.timestamp ?? new Date(),\n } as RLSRequestContext;\n }\n\n if (options.meta !== undefined) {\n context.meta = options.meta;\n }\n\n return context;\n}\n\n/**\n * Validate auth context\n */\nfunction validateAuthContext(auth: RLSAuthContext): void {\n if (auth.userId === undefined || auth.userId === null) {\n throw new RLSContextValidationError('userId is required in auth context', 'userId');\n }\n\n if (!Array.isArray(auth.roles)) {\n throw new RLSContextValidationError('roles must be an array', 'roles');\n }\n}\n\n/**\n * RLS Context Manager\n * Manages RLS context using AsyncLocalStorage for automatic propagation\n */\nclass RLSContextManager {\n /**\n * Run a synchronous function within an RLS context\n */\n run<T>(context: RLSContext, fn: () => T): T {\n return rlsStorage.run(context, fn);\n }\n\n /**\n * Run an async function within an RLS context\n */\n async runAsync<T>(context: RLSContext, fn: () => Promise<T>): Promise<T> {\n return rlsStorage.run(context, fn);\n }\n\n /**\n * Get current RLS context\n * @throws RLSContextError if no context is set\n */\n getContext(): RLSContext {\n const ctx = rlsStorage.getStore();\n if (!ctx) {\n throw new RLSContextError();\n }\n return ctx;\n }\n\n /**\n * Get current RLS context or null if not set\n */\n getContextOrNull(): RLSContext | null {\n return rlsStorage.getStore() ?? null;\n }\n\n /**\n * Check if running within RLS context\n */\n hasContext(): boolean {\n return rlsStorage.getStore() !== undefined;\n }\n\n /**\n * Get current auth context\n * @throws RLSContextError if no context is set\n */\n getAuth(): RLSAuthContext {\n return this.getContext().auth;\n }\n\n /**\n * Get current user ID\n * @throws RLSContextError if no context is set\n */\n getUserId(): string | number {\n return this.getAuth().userId;\n }\n\n /**\n * Get current tenant ID\n * @throws RLSContextError if no context is set\n */\n getTenantId(): string | number | undefined {\n return this.getAuth().tenantId;\n }\n\n /**\n * Check if current user has a specific role\n */\n hasRole(role: string): boolean {\n const ctx = this.getContextOrNull();\n return ctx?.auth.roles.includes(role) ?? false;\n }\n\n /**\n * Check if current user has a specific permission\n */\n hasPermission(permission: string): boolean {\n const ctx = this.getContextOrNull();\n return ctx?.auth.permissions?.includes(permission) ?? false;\n }\n\n /**\n * Check if current context is a system context (bypasses RLS)\n */\n isSystem(): boolean {\n const ctx = this.getContextOrNull();\n return ctx?.auth.isSystem ?? false;\n }\n\n /**\n * Create a system context for operations that should bypass RLS\n */\n asSystem<T>(fn: () => T): T {\n const currentCtx = this.getContextOrNull();\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context');\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true },\n };\n\n return this.run(systemCtx, fn);\n }\n\n /**\n * Create a system context for async operations\n */\n async asSystemAsync<T>(fn: () => Promise<T>): Promise<T> {\n const currentCtx = this.getContextOrNull();\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context');\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true },\n };\n\n return this.runAsync(systemCtx, fn);\n }\n}\n\n// Export singleton instance\nexport const rlsContext = new RLSContextManager();\n\n/**\n * Convenience function to run code within RLS context\n */\nexport function withRLSContext<T>(context: RLSContext, fn: () => T): T {\n return rlsContext.run(context, fn);\n}\n\n/**\n * Convenience function to run async code within RLS context\n */\nexport async function withRLSContextAsync<T>(\n context: RLSContext,\n fn: () => Promise<T>\n): Promise<T> {\n return rlsContext.runAsync(context, fn);\n}\n","/**\n * SELECT Query Transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\n\nimport type { SelectQueryBuilder } from 'kysely';\nimport type { PolicyRegistry } from '../policy/registry.js';\nimport type { PolicyEvaluationContext } from '../policy/types.js';\nimport type { RLSContext } from '../context/types.js';\nimport { rlsContext } from '../context/manager.js';\nimport { RLSError, RLSErrorCodes } from '../errors.js';\n\n/**\n * SELECT query transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\nexport class SelectTransformer<DB = unknown> {\n constructor(private registry: PolicyRegistry<DB>) {}\n\n /**\n * Transform a SELECT query by applying filter policies\n *\n * @param qb - The query builder to transform\n * @param table - Table name being queried\n * @returns Transformed query builder with RLS filters applied\n *\n * @example\n * ```typescript\n * const transformer = new SelectTransformer(registry);\n * let query = db.selectFrom('posts').selectAll();\n * query = transformer.transform(query, 'posts');\n * // Query now includes WHERE conditions from RLS policies\n * ```\n */\n transform<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n // Check for context\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) {\n // No context - return original query\n // In production, you might want to throw an error here\n return qb;\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n return qb;\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table);\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return qb;\n }\n\n // Get filter policies for this table\n const filters = this.registry.getFilters(table);\n if (filters.length === 0) {\n return qb;\n }\n\n // Apply each filter as WHERE condition\n let result = qb;\n for (const filter of filters) {\n const conditions = this.evaluateFilter(filter, ctx, table);\n result = this.applyConditions(result, conditions, table);\n }\n\n return result;\n }\n\n /**\n * Evaluate a filter policy to get WHERE conditions\n *\n * @param filter - The filter policy to evaluate\n * @param ctx - RLS context\n * @param table - Table name\n * @returns WHERE clause conditions as key-value pairs\n */\n private evaluateFilter(\n filter: { name: string; getConditions: (ctx: PolicyEvaluationContext) => Record<string, unknown> | Promise<Record<string, unknown>> },\n ctx: RLSContext,\n table: string\n ): Record<string, unknown> {\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> }),\n };\n\n const result = filter.getConditions(evalCtx);\n\n // Note: If async filters are needed, this method signature would need to change\n // For now, we assume synchronous filter evaluation\n if (result instanceof Promise) {\n throw new RLSError(\n `Async filter policies are not supported in SELECT transformers. ` +\n `Filter '${filter.name}' on table '${table}' returned a Promise. ` +\n `Use synchronous conditions for filter policies.`,\n RLSErrorCodes.RLS_POLICY_INVALID\n );\n }\n\n return result;\n }\n\n /**\n * Apply filter conditions to query builder\n *\n * @param qb - Query builder to modify\n * @param conditions - WHERE clause conditions\n * @param table - Table name (for qualified column names)\n * @returns Modified query builder\n */\n private applyConditions<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n conditions: Record<string, unknown>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n let result = qb;\n\n for (const [column, value] of Object.entries(conditions)) {\n // Use table-qualified column name to avoid ambiguity in joins\n const qualifiedColumn = `${table}.${column}` as any;\n\n if (value === null) {\n // NULL check\n result = result.where(qualifiedColumn, 'is', null);\n } else if (value === undefined) {\n // Skip undefined values\n continue;\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n // Empty array means no matches - add impossible condition\n // This ensures the query returns no rows\n result = result.where(qualifiedColumn, '=', '__RLS_NO_MATCH__' as any);\n } else {\n // IN clause for array values\n result = result.where(qualifiedColumn, 'in', value as any);\n }\n } else {\n // Equality check\n result = result.where(qualifiedColumn, '=', value as any);\n }\n }\n\n return result;\n }\n}\n","/**\n * Mutation Guard\n * Validates CREATE, UPDATE, DELETE operations against RLS policies\n */\n\nimport type { Kysely } from 'kysely';\nimport type { PolicyRegistry } from '../policy/registry.js';\nimport type { PolicyEvaluationContext, Operation } from '../policy/types.js';\nimport type { RLSContext } from '../context/types.js';\nimport { rlsContext } from '../context/manager.js';\nimport { RLSPolicyViolation } from '../errors.js';\n\n/**\n * Mutation guard\n * Validates mutations (CREATE, UPDATE, DELETE) against allow/deny/validate policies\n */\nexport class MutationGuard<DB = unknown> {\n // executor is kept for future use with database-dependent policies\n constructor(\n private registry: PolicyRegistry<DB>,\n _executor?: Kysely<DB>\n ) {}\n\n /**\n * Check if CREATE operation is allowed\n *\n * @param table - Table name\n * @param data - Data being inserted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * await guard.checkCreate('posts', { title: 'Hello', tenant_id: 1 });\n * ```\n */\n async checkCreate(\n table: string,\n data: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'create', undefined, data);\n }\n\n /**\n * Check if UPDATE operation is allowed\n *\n * @param table - Table name\n * @param existingRow - Current row data\n * @param data - Data being updated\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const existingPost = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * await guard.checkUpdate('posts', existingPost, { title: 'Updated' });\n * ```\n */\n async checkUpdate(\n table: string,\n existingRow: Record<string, unknown>,\n data: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'update', existingRow, data);\n }\n\n /**\n * Check if DELETE operation is allowed\n *\n * @param table - Table name\n * @param existingRow - Row to be deleted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const existingPost = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * await guard.checkDelete('posts', existingPost);\n * ```\n */\n async checkDelete(\n table: string,\n existingRow: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'delete', existingRow);\n }\n\n /**\n * Check if READ operation is allowed on a specific row\n *\n * @param table - Table name\n * @param row - Row to check access for\n * @returns true if access is allowed\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const post = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * const canRead = await guard.checkRead('posts', post);\n * ```\n */\n async checkRead(\n table: string,\n row: Record<string, unknown>\n ): Promise<boolean> {\n try {\n await this.checkMutation(table, 'read', row);\n return true;\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n return false;\n }\n throw error;\n }\n }\n\n /**\n * Generic check for any operation (helper for testing)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @returns true if access is allowed, false otherwise\n */\n async canMutate(\n operation: Operation,\n table: string,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<boolean> {\n try {\n await this.checkMutation(table, operation, row, data);\n return true;\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n return false;\n }\n throw error;\n }\n }\n\n /**\n * Validate mutation data (for validate policies)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param data - New data (for CREATE/UPDATE)\n * @param row - Existing row (for UPDATE)\n * @returns true if valid, false otherwise\n */\n async validateMutation(\n operation: Operation,\n table: string,\n data: Record<string, unknown>,\n row?: Record<string, unknown>\n ): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) {\n return false;\n }\n\n // System users bypass validation\n if (ctx.auth.isSystem) {\n return true;\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table);\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true;\n }\n\n // Get validate policies for this operation\n const validates = this.registry.getValidates(table, operation);\n if (validates.length === 0) {\n return true;\n }\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n row: row,\n data: data,\n table: table,\n operation: operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> }),\n };\n\n // All validate policies must pass\n for (const validate of validates) {\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx);\n if (!result) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Check mutation against RLS policies\n *\n * @param table - Table name\n * @param operation - Operation type\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @throws RLSPolicyViolation if access is denied\n */\n private async checkMutation(\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<void> {\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) {\n throw new RLSPolicyViolation(\n operation,\n table,\n 'No RLS context available'\n );\n }\n\n // System users bypass all checks\n if (ctx.auth.isSystem) {\n return;\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table);\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return;\n }\n\n // Evaluate deny policies first (they override allows)\n const denies = this.registry.getDenies(table, operation);\n for (const deny of denies) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data);\n const result = await this.evaluatePolicy(deny.evaluate, evalCtx);\n\n if (result) {\n throw new RLSPolicyViolation(\n operation,\n table,\n `Denied by policy: ${deny.name}`\n );\n }\n }\n\n // Evaluate validate policies (for CREATE/UPDATE)\n if ((operation === 'create' || operation === 'update') && data) {\n const validates = this.registry.getValidates(table, operation);\n for (const validate of validates) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data);\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx);\n\n if (!result) {\n throw new RLSPolicyViolation(\n operation,\n table,\n `Validation failed: ${validate.name}`\n );\n }\n }\n }\n\n // Evaluate allow policies\n const allows = this.registry.getAllows(table, operation);\n const defaultDeny = this.registry.hasDefaultDeny(table);\n\n if (defaultDeny && allows.length === 0) {\n throw new RLSPolicyViolation(\n operation,\n table,\n 'No allow policies defined (default deny)'\n );\n }\n\n if (allows.length > 0) {\n // At least one allow policy must pass\n let allowed = false;\n\n for (const allow of allows) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data);\n const result = await this.evaluatePolicy(allow.evaluate, evalCtx);\n\n if (result) {\n allowed = true;\n break;\n }\n }\n\n if (!allowed) {\n throw new RLSPolicyViolation(\n operation,\n table,\n 'No allow policies matched'\n );\n }\n }\n }\n\n /**\n * Create policy evaluation context\n */\n private createEvalContext(\n ctx: RLSContext,\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n row,\n data,\n table,\n operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> }),\n };\n }\n\n /**\n * Evaluate a policy condition\n */\n private async evaluatePolicy(\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n evalCtx: PolicyEvaluationContext\n ): Promise<boolean> {\n try {\n const result = condition(evalCtx);\n return result instanceof Promise ? await result : result;\n } catch (error) {\n // Policy evaluation errors are treated as denial\n throw new RLSPolicyViolation(\n evalCtx.operation ?? 'unknown',\n evalCtx.table ?? 'unknown',\n `Policy evaluation error: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Filter an array of rows, keeping only accessible ones\n * Useful for post-query filtering when query-level filtering is not possible\n *\n * @param table - Table name\n * @param rows - Array of rows to filter\n * @returns Filtered array containing only accessible rows\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry, db);\n * const allPosts = await db.selectFrom('posts').selectAll().execute();\n * const accessiblePosts = await guard.filterRows('posts', allPosts);\n * ```\n */\n async filterRows<T extends Record<string, unknown>>(\n table: string,\n rows: T[]\n ): Promise<T[]> {\n const results: T[] = [];\n\n for (const row of rows) {\n if (await this.checkRead(table, row)) {\n results.push(row);\n }\n }\n\n return results;\n }\n}\n","/**\n * RLS Plugin for Kysera Repository\n *\n * Implements Row-Level Security as a Kysera plugin, providing:\n * - Automatic query filtering for SELECT operations\n * - Policy enforcement for CREATE, UPDATE, DELETE operations\n * - Repository method extensions for RLS-aware operations\n * - System context bypass for privileged operations\n *\n * @module @kysera/rls\n */\n\nimport type { Plugin, QueryBuilderContext, AnyQueryBuilder } from '@kysera/repository';\nimport type { Kysely } from 'kysely';\nimport type { RLSSchema, Operation } from './policy/types.js';\nimport { PolicyRegistry } from './policy/registry.js';\nimport { SelectTransformer } from './transformer/select.js';\nimport { MutationGuard } from './transformer/mutation.js';\nimport { rlsContext } from './context/manager.js';\nimport { RLSContextError, RLSPolicyViolation, RLSError, RLSErrorCodes } from './errors.js';\nimport { silentLogger, type KyseraLogger } from '@kysera/core';\n\n/**\n * RLS Plugin configuration options\n */\nexport interface RLSPluginOptions<DB = unknown> {\n /** RLS policy schema */\n schema: RLSSchema<DB>;\n\n /** Tables to skip RLS for (always bypass policies) */\n skipTables?: string[];\n\n /** Roles that bypass RLS entirely (e.g., ['admin', 'superuser']) */\n bypassRoles?: string[];\n\n /** Logger instance for RLS operations */\n logger?: KyseraLogger;\n\n /** Require RLS context for all operations (throws if missing) */\n requireContext?: boolean;\n\n /** Enable audit logging of policy decisions */\n auditDecisions?: boolean;\n\n /** Custom error handler for policy violations */\n onViolation?: (violation: RLSPolicyViolation) => void;\n}\n\n/**\n * Base repository interface for type safety\n * @internal\n */\ninterface BaseRepository {\n tableName: string;\n executor: Kysely<Record<string, unknown>>;\n findById?: (id: unknown) => Promise<unknown>;\n create?: (data: unknown) => Promise<unknown>;\n update?: (id: unknown, data: unknown) => Promise<unknown>;\n delete?: (id: unknown) => Promise<unknown>;\n}\n\n/**\n * Create RLS plugin for Kysera\n *\n * The RLS plugin provides declarative row-level security for your database operations.\n * It automatically filters SELECT queries and validates mutations (CREATE, UPDATE, DELETE)\n * against your policy schema.\n *\n * @example\n * ```typescript\n * import { rlsPlugin, defineRLSSchema, allow, filter } from '@kysera/rls';\n * import { createORM } from '@kysera/repository';\n *\n * // Define your RLS schema\n * const schema = defineRLSSchema<Database>({\n * resources: {\n * policies: [\n * // Filter reads by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Allow updates for resource owners\n * allow('update', ctx => ctx.auth.userId === ctx.row.owner_id),\n * // Validate creates belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * },\n * });\n *\n * // Create ORM with RLS plugin\n * const orm = await createORM(db, [\n * rlsPlugin({ schema }),\n * ]);\n *\n * // Use within RLS context\n * await rlsContext.runAsync(\n * {\n * auth: { userId: 1, tenantId: 100, roles: ['user'], isSystem: false },\n * timestamp: new Date(),\n * },\n * async () => {\n * // All queries automatically filtered by tenant_id\n * const resources = await orm.resources.findAll();\n * }\n * );\n * ```\n *\n * @param options - Plugin configuration options\n * @returns Kysera plugin instance\n */\nexport function rlsPlugin<DB>(options: RLSPluginOptions<DB>): Plugin {\n const {\n schema,\n skipTables = [],\n bypassRoles = [],\n logger = silentLogger,\n requireContext = false,\n auditDecisions = false,\n onViolation,\n } = options;\n\n // Registry and transformers (initialized in onInit)\n let registry: PolicyRegistry<DB>;\n let selectTransformer: SelectTransformer<DB>;\n let mutationGuard: MutationGuard<DB>;\n\n return {\n name: '@kysera/rls',\n version: '0.5.1',\n\n // Run after soft-delete (priority 0), before audit\n priority: 50,\n\n // No dependencies by default\n dependencies: [],\n\n /**\n * Initialize plugin - compile policies\n */\n async onInit<TDB>(executor: Kysely<TDB>): Promise<void> {\n logger.info?.('[RLS] Initializing RLS plugin', {\n tables: Object.keys(schema).length,\n skipTables: skipTables.length,\n bypassRoles: bypassRoles.length,\n });\n\n // Create and compile registry\n registry = new PolicyRegistry<DB>(schema);\n registry.validate();\n\n // Create transformers\n selectTransformer = new SelectTransformer<DB>(registry);\n mutationGuard = new MutationGuard<DB>(registry, executor as unknown as Kysely<DB>);\n\n logger.info?.('[RLS] RLS plugin initialized successfully');\n },\n\n /**\n * Intercept queries to apply RLS filtering\n *\n * This hook is called for every query builder operation. For SELECT queries,\n * it applies filter policies as WHERE conditions. For mutations, it marks\n * that RLS validation is required (performed in extendRepository).\n */\n interceptQuery<QB extends AnyQueryBuilder>(\n qb: QB,\n context: QueryBuilderContext\n ): QB {\n const { operation, table, metadata } = context;\n\n // Skip if table is excluded\n if (skipTables.includes(table)) {\n logger.debug?.(`[RLS] Skipping RLS for excluded table: ${table}`);\n return qb;\n }\n\n // Skip if explicitly disabled via metadata\n if (metadata['skipRLS'] === true) {\n logger.debug?.(`[RLS] Skipping RLS (explicit skip): ${table}`);\n return qb;\n }\n\n // Check for context\n const ctx = rlsContext.getContextOrNull();\n\n if (!ctx) {\n if (requireContext) {\n throw new RLSContextError('RLS context required but not found');\n }\n logger.warn?.(`[RLS] No context for ${operation} on ${table}`);\n return qb;\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n logger.debug?.(`[RLS] Bypassing RLS (system user): ${table}`);\n return qb;\n }\n\n // Check bypass roles\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n logger.debug?.(`[RLS] Bypassing RLS (bypass role): ${table}`);\n return qb;\n }\n\n // Apply SELECT filtering\n if (operation === 'select') {\n try {\n const transformed = selectTransformer.transform(qb as any, table);\n\n if (auditDecisions) {\n logger.info?.('[RLS] Filter applied', {\n table,\n operation,\n userId: ctx.auth.userId,\n });\n }\n\n return transformed as QB;\n } catch (error) {\n logger.error?.('[RLS] Error applying filter', { table, error });\n throw error;\n }\n }\n\n // For mutations, mark that RLS check is needed (done in extendRepository)\n if (operation === 'insert' || operation === 'update' || operation === 'delete') {\n metadata['__rlsRequired'] = true;\n metadata['__rlsTable'] = table;\n }\n\n return qb;\n },\n\n /**\n * Extend repository with RLS-aware methods\n *\n * Wraps create, update, and delete methods to enforce RLS policies.\n * Also adds utility methods for bypassing RLS and checking access.\n */\n extendRepository<T extends object>(repo: T): T {\n const baseRepo = repo as unknown as BaseRepository;\n\n // Check if it's a valid repository\n if (!('tableName' in baseRepo) || !('executor' in baseRepo)) {\n return repo;\n }\n\n const table = baseRepo.tableName;\n\n // Skip excluded tables\n if (skipTables.includes(table)) {\n return repo;\n }\n\n // Skip if table not in schema\n if (!registry.hasTable(table)) {\n logger.debug?.(`[RLS] Table \"${table}\" not in RLS schema, skipping`);\n return repo;\n }\n\n logger.debug?.(`[RLS] Extending repository for table: ${table}`);\n\n // Store original methods\n const originalCreate = baseRepo.create?.bind(baseRepo);\n const originalUpdate = baseRepo.update?.bind(baseRepo);\n const originalDelete = baseRepo.delete?.bind(baseRepo);\n const originalFindById = baseRepo.findById?.bind(baseRepo);\n\n const extendedRepo = {\n ...baseRepo,\n\n /**\n * Wrapped create with RLS check\n */\n async create(data: unknown): Promise<unknown> {\n if (!originalCreate) {\n throw new RLSError('Repository does not support create operation', RLSErrorCodes.RLS_POLICY_INVALID);\n }\n\n const ctx = rlsContext.getContextOrNull();\n\n // Check RLS if context exists and not system/bypass\n if (ctx && !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n try {\n await mutationGuard.checkCreate(table, data as Record<string, unknown>);\n\n if (auditDecisions) {\n logger.info?.('[RLS] Create allowed', { table, userId: ctx.auth.userId });\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error);\n if (auditDecisions) {\n logger.warn?.('[RLS] Create denied', {\n table,\n userId: ctx.auth.userId,\n reason: error.reason\n });\n }\n }\n throw error;\n }\n }\n\n return originalCreate(data);\n },\n\n /**\n * Wrapped update with RLS check\n */\n async update(id: unknown, data: unknown): Promise<unknown> {\n if (!originalUpdate || !originalFindById) {\n throw new RLSError('Repository does not support update operation', RLSErrorCodes.RLS_POLICY_INVALID);\n }\n\n const ctx = rlsContext.getContextOrNull();\n\n if (ctx && !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n // Fetch existing row for policy evaluation\n const existingRow = await originalFindById(id);\n if (!existingRow) {\n // Let the original method handle not found\n return originalUpdate(id, data);\n }\n\n try {\n await mutationGuard.checkUpdate(\n table,\n existingRow as Record<string, unknown>,\n data as Record<string, unknown>\n );\n\n if (auditDecisions) {\n logger.info?.('[RLS] Update allowed', { table, id, userId: ctx.auth.userId });\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error);\n if (auditDecisions) {\n logger.warn?.('[RLS] Update denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n });\n }\n }\n throw error;\n }\n }\n\n return originalUpdate(id, data);\n },\n\n /**\n * Wrapped delete with RLS check\n */\n async delete(id: unknown): Promise<unknown> {\n if (!originalDelete || !originalFindById) {\n throw new RLSError('Repository does not support delete operation', RLSErrorCodes.RLS_POLICY_INVALID);\n }\n\n const ctx = rlsContext.getContextOrNull();\n\n if (ctx && !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n // Fetch existing row for policy evaluation\n const existingRow = await originalFindById(id);\n if (!existingRow) {\n // Let the original method handle not found\n return originalDelete(id);\n }\n\n try {\n await mutationGuard.checkDelete(table, existingRow as Record<string, unknown>);\n\n if (auditDecisions) {\n logger.info?.('[RLS] Delete allowed', { table, id, userId: ctx.auth.userId });\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error);\n if (auditDecisions) {\n logger.warn?.('[RLS] Delete denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n });\n }\n }\n throw error;\n }\n }\n\n return originalDelete(id);\n },\n\n /**\n * Bypass RLS for specific operation\n * Requires existing context\n *\n * @example\n * ```typescript\n * // Perform operation as system user\n * const result = await repo.withoutRLS(async () => {\n * return repo.findAll(); // No RLS filtering\n * });\n * ```\n */\n async withoutRLS<R>(fn: () => Promise<R>): Promise<R> {\n return rlsContext.asSystemAsync(fn);\n },\n\n /**\n * Check if current user can perform operation on a row\n *\n * @example\n * ```typescript\n * const post = await repo.findById(1);\n * const canUpdate = await repo.canAccess('update', post);\n * if (canUpdate) {\n * await repo.update(1, { title: 'New title' });\n * }\n * ```\n */\n async canAccess(operation: Operation, row: Record<string, unknown>): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull();\n if (!ctx) return false;\n if (ctx.auth.isSystem) return true;\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) return true;\n\n try {\n switch (operation) {\n case 'read':\n return await mutationGuard.checkRead(table, row);\n case 'create':\n await mutationGuard.checkCreate(table, row);\n return true;\n case 'update':\n await mutationGuard.checkUpdate(table, row, {});\n return true;\n case 'delete':\n await mutationGuard.checkDelete(table, row);\n return true;\n default:\n return false;\n }\n } catch (error) {\n logger.debug?.('[RLS] Access check failed', {\n table,\n operation,\n error: error instanceof Error ? error.message : String(error)\n });\n return false;\n }\n },\n };\n\n return extendedRepo as T;\n },\n };\n}\n","/**\n * Utility helper functions for RLS\n */\n\nimport type {\n RLSContext,\n PolicyEvaluationContext,\n Operation,\n} from '../policy/types.js';\n\n/**\n * Create a policy evaluation context from RLS context\n */\nexport function createEvaluationContext<\n TRow = unknown,\n TData = unknown\n>(\n rlsCtx: RLSContext,\n options?: {\n row?: TRow;\n data?: TData;\n }\n): PolicyEvaluationContext<unknown, TRow, TData> {\n const ctx: PolicyEvaluationContext<unknown, TRow, TData> = {\n auth: rlsCtx.auth,\n };\n\n if (options?.row !== undefined) {\n ctx.row = options.row;\n }\n\n if (options?.data !== undefined) {\n ctx.data = options.data;\n }\n\n if (rlsCtx.request !== undefined) {\n ctx.request = rlsCtx.request;\n }\n\n if (rlsCtx.meta !== undefined) {\n ctx.meta = rlsCtx.meta as Record<string, unknown>;\n }\n\n return ctx;\n}\n\n/**\n * Check if a condition function is async\n */\nexport function isAsyncFunction(fn: unknown): fn is (...args: unknown[]) => Promise<unknown> {\n return fn instanceof Function && fn.constructor.name === 'AsyncFunction';\n}\n\n/**\n * Safely evaluate a policy condition\n */\nexport async function safeEvaluate<T>(\n fn: () => T | Promise<T>,\n defaultValue: T\n): Promise<T> {\n try {\n const result = fn();\n if (result instanceof Promise) {\n return await result;\n }\n return result;\n } catch (error) {\n // Expected failure during policy evaluation - return default value\n // Logger not available in this utility function, error is handled gracefully\n return defaultValue;\n }\n}\n\n/**\n * Deep merge two objects\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceValue = source[key];\n const targetValue = result[key];\n\n if (\n sourceValue !== undefined &&\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[keyof T];\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as T[keyof T];\n }\n }\n\n return result;\n}\n\n/**\n * Create a simple hash for cache keys\n */\nexport function hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash.toString(36);\n}\n\n/**\n * Normalize operations to array format\n */\nexport function normalizeOperations(\n operation: Operation | Operation[]\n): Operation[] {\n if (Array.isArray(operation)) {\n if (operation.includes('all')) {\n return ['read', 'create', 'update', 'delete'];\n }\n return operation;\n }\n\n if (operation === 'all') {\n return ['read', 'create', 'update', 'delete'];\n }\n\n return [operation];\n}\n"]}
|
package/dist/native/index.d.ts
CHANGED
|
@@ -251,6 +251,16 @@ interface PolicyEvaluationContext<TAuth = unknown, TRow = unknown, TData = unkno
|
|
|
251
251
|
* Can contain any additional context needed for policy evaluation
|
|
252
252
|
*/
|
|
253
253
|
meta?: Record<string, unknown>;
|
|
254
|
+
/**
|
|
255
|
+
* Table name being accessed (optional)
|
|
256
|
+
* Available during mutation operations
|
|
257
|
+
*/
|
|
258
|
+
table?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Operation being performed (optional)
|
|
261
|
+
* E.g., 'create', 'update', 'delete'
|
|
262
|
+
*/
|
|
263
|
+
operation?: string;
|
|
254
264
|
}
|
|
255
265
|
/**
|
|
256
266
|
* Policy condition function or expression
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kysera/rls",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Row-Level Security plugin for Kysera ORM - declarative policies, query transformation, native RLS support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"zod": "^4.1.13",
|
|
27
|
-
"@kysera/core": "0.
|
|
28
|
-
"@kysera/repository": "0.
|
|
27
|
+
"@kysera/core": "0.6.0",
|
|
28
|
+
"@kysera/repository": "0.6.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/better-sqlite3": "^7.6.13",
|
package/src/policy/types.ts
CHANGED
|
@@ -299,6 +299,18 @@ export interface PolicyEvaluationContext<
|
|
|
299
299
|
* Can contain any additional context needed for policy evaluation
|
|
300
300
|
*/
|
|
301
301
|
meta?: Record<string, unknown>;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Table name being accessed (optional)
|
|
305
|
+
* Available during mutation operations
|
|
306
|
+
*/
|
|
307
|
+
table?: string;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Operation being performed (optional)
|
|
311
|
+
* E.g., 'create', 'update', 'delete'
|
|
312
|
+
*/
|
|
313
|
+
operation?: string;
|
|
302
314
|
}
|
|
303
315
|
|
|
304
316
|
// ============================================================================
|
|
@@ -15,9 +15,10 @@ import { RLSPolicyViolation } from '../errors.js';
|
|
|
15
15
|
* Validates mutations (CREATE, UPDATE, DELETE) against allow/deny/validate policies
|
|
16
16
|
*/
|
|
17
17
|
export class MutationGuard<DB = unknown> {
|
|
18
|
+
// executor is kept for future use with database-dependent policies
|
|
18
19
|
constructor(
|
|
19
20
|
private registry: PolicyRegistry<DB>,
|
|
20
|
-
|
|
21
|
+
_executor?: Kysely<DB>
|
|
21
22
|
) {}
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -316,7 +317,7 @@ export class MutationGuard<DB = unknown> {
|
|
|
316
317
|
data,
|
|
317
318
|
table,
|
|
318
319
|
operation,
|
|
319
|
-
|
|
320
|
+
...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> }),
|
|
320
321
|
};
|
|
321
322
|
}
|
|
322
323
|
|
|
@@ -333,8 +334,8 @@ export class MutationGuard<DB = unknown> {
|
|
|
333
334
|
} catch (error) {
|
|
334
335
|
// Policy evaluation errors are treated as denial
|
|
335
336
|
throw new RLSPolicyViolation(
|
|
336
|
-
evalCtx.operation,
|
|
337
|
-
evalCtx.table,
|
|
337
|
+
evalCtx.operation ?? 'unknown',
|
|
338
|
+
evalCtx.table ?? 'unknown',
|
|
338
339
|
`Policy evaluation error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
339
340
|
);
|
|
340
341
|
}
|