@kysera/rls 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Policy Composition Types
3
+ *
4
+ * Provides types for creating reusable, composable RLS policies.
5
+ *
6
+ * @module @kysera/rls/composition/types
7
+ */
8
+
9
+ import type {
10
+ PolicyDefinition,
11
+ PolicyCondition,
12
+ FilterCondition,
13
+ PolicyEvaluationContext,
14
+ Operation,
15
+ PolicyHints
16
+ } from '../policy/types.js'
17
+
18
+ // ============================================================================
19
+ // Reusable Policy Types
20
+ // ============================================================================
21
+
22
+ /**
23
+ * A named, reusable policy template
24
+ *
25
+ * Can be composed with other policies and applied to multiple tables.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const tenantIsolation = definePolicy({
30
+ * name: 'tenantIsolation',
31
+ * type: 'filter',
32
+ * operation: 'read',
33
+ * filter: ctx => ({ tenant_id: ctx.auth.tenantId }),
34
+ * priority: 1000
35
+ * });
36
+ * ```
37
+ */
38
+ export interface ReusablePolicy {
39
+ /**
40
+ * Unique name for this policy
41
+ */
42
+ name: string
43
+
44
+ /**
45
+ * Description for documentation
46
+ */
47
+ description?: string
48
+
49
+ /**
50
+ * Policy definitions (can include multiple policies)
51
+ */
52
+ policies: PolicyDefinition[]
53
+
54
+ /**
55
+ * Tags for categorization
56
+ */
57
+ tags?: string[]
58
+ }
59
+
60
+ /**
61
+ * Configuration for a reusable policy template
62
+ */
63
+ export interface ReusablePolicyConfig {
64
+ /**
65
+ * Policy name
66
+ */
67
+ name: string
68
+
69
+ /**
70
+ * Description
71
+ */
72
+ description?: string
73
+
74
+ /**
75
+ * Tags for categorization
76
+ */
77
+ tags?: string[]
78
+ }
79
+
80
+ // ============================================================================
81
+ // Policy Builder Configuration
82
+ // ============================================================================
83
+
84
+ /**
85
+ * Configuration for creating a filter policy
86
+ */
87
+ export interface FilterPolicyConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {
88
+ /**
89
+ * Filter condition (returns WHERE clause conditions)
90
+ */
91
+ filter: FilterCondition<TCtx>
92
+
93
+ /**
94
+ * Priority for policy evaluation
95
+ * @default 0
96
+ */
97
+ priority?: number
98
+
99
+ /**
100
+ * Performance hints
101
+ */
102
+ hints?: PolicyHints
103
+ }
104
+
105
+ /**
106
+ * Configuration for creating an allow policy
107
+ */
108
+ export interface AllowPolicyConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {
109
+ /**
110
+ * Operations this policy applies to
111
+ */
112
+ operation: Operation | Operation[]
113
+
114
+ /**
115
+ * Allow condition
116
+ */
117
+ allow: PolicyCondition<TCtx>
118
+
119
+ /**
120
+ * Priority for policy evaluation
121
+ * @default 0
122
+ */
123
+ priority?: number
124
+
125
+ /**
126
+ * Performance hints
127
+ */
128
+ hints?: PolicyHints
129
+ }
130
+
131
+ /**
132
+ * Configuration for creating a deny policy
133
+ */
134
+ export interface DenyPolicyConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {
135
+ /**
136
+ * Operations this policy applies to
137
+ */
138
+ operation: Operation | Operation[]
139
+
140
+ /**
141
+ * Deny condition (optional - if not provided, always denies)
142
+ */
143
+ deny?: PolicyCondition<TCtx>
144
+
145
+ /**
146
+ * Priority for policy evaluation
147
+ * @default 100
148
+ */
149
+ priority?: number
150
+
151
+ /**
152
+ * Performance hints
153
+ */
154
+ hints?: PolicyHints
155
+ }
156
+
157
+ /**
158
+ * Configuration for creating a validate policy
159
+ */
160
+ export interface ValidatePolicyConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {
161
+ /**
162
+ * Operations this policy applies to
163
+ */
164
+ operation: 'create' | 'update' | 'all'
165
+
166
+ /**
167
+ * Validation condition
168
+ */
169
+ validate: PolicyCondition<TCtx>
170
+
171
+ /**
172
+ * Priority for policy evaluation
173
+ * @default 0
174
+ */
175
+ priority?: number
176
+
177
+ /**
178
+ * Performance hints
179
+ */
180
+ hints?: PolicyHints
181
+ }
182
+
183
+ /**
184
+ * Combined policy configuration
185
+ */
186
+ export interface CombinedPolicyConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {
187
+ /**
188
+ * Filter policy (for read operations)
189
+ */
190
+ filter?: FilterCondition<TCtx>
191
+
192
+ /**
193
+ * Allow policies by operation
194
+ */
195
+ allow?: {
196
+ [K in Operation]?: PolicyCondition<TCtx>
197
+ }
198
+
199
+ /**
200
+ * Deny policies by operation
201
+ */
202
+ deny?: {
203
+ [K in Operation]?: PolicyCondition<TCtx>
204
+ }
205
+
206
+ /**
207
+ * Validate policies by operation
208
+ */
209
+ validate?: {
210
+ create?: PolicyCondition<TCtx>
211
+ update?: PolicyCondition<TCtx>
212
+ }
213
+ }
214
+
215
+ // ============================================================================
216
+ // Table Configuration with Composition
217
+ // ============================================================================
218
+
219
+ /**
220
+ * Extended table RLS configuration with policy composition support
221
+ */
222
+ export interface ComposableTableConfig {
223
+ /**
224
+ * Reusable policies to extend from
225
+ * Policies are applied in order (first = lowest priority)
226
+ */
227
+ extends?: ReusablePolicy[]
228
+
229
+ /**
230
+ * Additional table-specific policies
231
+ */
232
+ policies?: PolicyDefinition[]
233
+
234
+ /**
235
+ * Whether to allow access by default when no policies match
236
+ * @default true
237
+ */
238
+ defaultDeny?: boolean
239
+
240
+ /**
241
+ * Roles that bypass RLS
242
+ */
243
+ skipFor?: string[]
244
+ }
245
+
246
+ /**
247
+ * Complete schema with composition support
248
+ *
249
+ * @typeParam DB - Database schema type
250
+ */
251
+ export type ComposableRLSSchema<DB> = {
252
+ [K in keyof DB]?: ComposableTableConfig
253
+ }
254
+
255
+ // ============================================================================
256
+ // Policy Inheritance Types
257
+ // ============================================================================
258
+
259
+ /**
260
+ * Base policy that can be extended
261
+ */
262
+ export interface BasePolicyDefinition {
263
+ /**
264
+ * Unique identifier for this base policy
265
+ */
266
+ id: string
267
+
268
+ /**
269
+ * Human-readable name
270
+ */
271
+ name: string
272
+
273
+ /**
274
+ * Description
275
+ */
276
+ description?: string
277
+
278
+ /**
279
+ * Policies included in this base
280
+ */
281
+ policies: PolicyDefinition[]
282
+
283
+ /**
284
+ * Other base policies this extends
285
+ */
286
+ extends?: string[]
287
+
288
+ /**
289
+ * Priority offset applied to all policies
290
+ * @default 0
291
+ */
292
+ priorityOffset?: number
293
+ }
294
+
295
+ /**
296
+ * Policy inheritance chain resolution
297
+ */
298
+ export interface ResolvedInheritance {
299
+ /**
300
+ * Final merged policies
301
+ */
302
+ policies: PolicyDefinition[]
303
+
304
+ /**
305
+ * Chain of base policies used
306
+ */
307
+ inheritanceChain: string[]
308
+
309
+ /**
310
+ * Any conflicts detected
311
+ */
312
+ conflicts: {
313
+ policy: string
314
+ reason: string
315
+ }[]
316
+ }
317
+
318
+ // ============================================================================
319
+ // Common Policy Patterns
320
+ // ============================================================================
321
+
322
+ /**
323
+ * Multi-tenancy policy configuration
324
+ */
325
+ export interface TenantIsolationConfig {
326
+ /**
327
+ * Column name for tenant ID
328
+ * @default 'tenant_id'
329
+ */
330
+ tenantColumn?: string
331
+
332
+ /**
333
+ * Operations to apply tenant isolation to
334
+ * @default ['read', 'create', 'update', 'delete']
335
+ */
336
+ operations?: Operation[]
337
+
338
+ /**
339
+ * Whether to validate tenant on create/update
340
+ * @default true
341
+ */
342
+ validateOnMutation?: boolean
343
+ }
344
+
345
+ /**
346
+ * Ownership policy configuration
347
+ */
348
+ export interface OwnershipConfig {
349
+ /**
350
+ * Column name for owner ID
351
+ * @default 'owner_id' or 'user_id'
352
+ */
353
+ ownerColumn?: string
354
+
355
+ /**
356
+ * Operations owners can perform
357
+ * @default ['read', 'update', 'delete']
358
+ */
359
+ ownerOperations?: Operation[]
360
+
361
+ /**
362
+ * Whether owners can delete
363
+ * @default true
364
+ */
365
+ canDelete?: boolean
366
+ }
367
+
368
+ /**
369
+ * Soft delete policy configuration
370
+ */
371
+ export interface SoftDeleteConfig {
372
+ /**
373
+ * Column name for soft delete flag
374
+ * @default 'deleted_at'
375
+ */
376
+ deletedColumn?: string
377
+
378
+ /**
379
+ * Whether to filter soft-deleted rows on read
380
+ * @default true
381
+ */
382
+ filterOnRead?: boolean
383
+
384
+ /**
385
+ * Whether to prevent hard deletes
386
+ * @default true
387
+ */
388
+ preventHardDelete?: boolean
389
+ }
390
+
391
+ /**
392
+ * Status-based access configuration
393
+ */
394
+ export interface StatusAccessConfig {
395
+ /**
396
+ * Column name for status
397
+ * @default 'status'
398
+ */
399
+ statusColumn?: string
400
+
401
+ /**
402
+ * Statuses that are publicly readable
403
+ */
404
+ publicStatuses?: string[]
405
+
406
+ /**
407
+ * Statuses that can be updated
408
+ */
409
+ editableStatuses?: string[]
410
+
411
+ /**
412
+ * Statuses that can be deleted
413
+ */
414
+ deletableStatuses?: string[]
415
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Field-Level Access Control Module
3
+ *
4
+ * Provides field-level security for controlling access to individual columns.
5
+ *
6
+ * @module @kysera/rls/field-access
7
+ */
8
+
9
+ // Types
10
+ export type {
11
+ FieldOperation,
12
+ FieldAccessCondition,
13
+ FieldAccessConfig,
14
+ TableFieldAccessConfig,
15
+ FieldAccessSchema,
16
+ CompiledFieldAccess,
17
+ CompiledTableFieldAccess,
18
+ FieldAccessResult,
19
+ MaskedRow,
20
+ FieldAccessOptions
21
+ } from './types.js'
22
+
23
+ // Predefined patterns
24
+ export {
25
+ neverAccessible,
26
+ ownerOnly,
27
+ ownerOrRoles,
28
+ rolesOnly,
29
+ readOnly,
30
+ publicReadRestrictedWrite,
31
+ maskedField
32
+ } from './types.js'
33
+
34
+ // Registry
35
+ export { FieldAccessRegistry, createFieldAccessRegistry } from './registry.js'
36
+
37
+ // Processor
38
+ export { FieldAccessProcessor, createFieldAccessProcessor } from './processor.js'