@allternit/ix 0.1.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 +320 -0
- package/dist/adapters/json-render.d.ts +211 -0
- package/dist/adapters/json-render.d.ts.bak +211 -0
- package/dist/adapters/json-render.d.ts.map +1 -0
- package/dist/adapters/json-render.js +576 -0
- package/dist/adapters/json-render.js.bak +576 -0
- package/dist/adapters/json-render.js.map +1 -0
- package/dist/catalog/registry.d.ts +65 -0
- package/dist/catalog/registry.d.ts.bak +65 -0
- package/dist/catalog/registry.d.ts.map +1 -0
- package/dist/catalog/registry.js +388 -0
- package/dist/catalog/registry.js.bak +388 -0
- package/dist/catalog/registry.js.map +1 -0
- package/dist/collab/capsule-registry.d.ts +114 -0
- package/dist/collab/capsule-registry.d.ts.bak +114 -0
- package/dist/collab/capsule-registry.d.ts.map +1 -0
- package/dist/collab/capsule-registry.js +271 -0
- package/dist/collab/capsule-registry.js.bak +271 -0
- package/dist/collab/capsule-registry.js.map +1 -0
- package/dist/collab/index.d.ts +21 -0
- package/dist/collab/index.d.ts.bak +21 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +32 -0
- package/dist/collab/index.js.bak +32 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/collab/visual-editor.d.ts +199 -0
- package/dist/collab/visual-editor.d.ts.bak +199 -0
- package/dist/collab/visual-editor.d.ts.map +1 -0
- package/dist/collab/visual-editor.js +259 -0
- package/dist/collab/visual-editor.js.bak +259 -0
- package/dist/collab/visual-editor.js.map +1 -0
- package/dist/collab/yjs-adapter.d.ts +95 -0
- package/dist/collab/yjs-adapter.d.ts.bak +95 -0
- package/dist/collab/yjs-adapter.d.ts.map +1 -0
- package/dist/collab/yjs-adapter.js +282 -0
- package/dist/collab/yjs-adapter.js.bak +282 -0
- package/dist/collab/yjs-adapter.js.map +1 -0
- package/dist/collab/yjs-client.d.ts +101 -0
- package/dist/collab/yjs-client.d.ts.bak +101 -0
- package/dist/collab/yjs-client.d.ts.map +1 -0
- package/dist/collab/yjs-client.js +193 -0
- package/dist/collab/yjs-client.js.bak +193 -0
- package/dist/collab/yjs-client.js.map +1 -0
- package/dist/collab/yjs-protocols.d.ts +128 -0
- package/dist/collab/yjs-protocols.d.ts.bak +128 -0
- package/dist/collab/yjs-protocols.d.ts.map +1 -0
- package/dist/collab/yjs-protocols.js +245 -0
- package/dist/collab/yjs-protocols.js.bak +245 -0
- package/dist/collab/yjs-protocols.js.map +1 -0
- package/dist/collab/yjs-types.d.ts +201 -0
- package/dist/collab/yjs-types.d.ts.bak +201 -0
- package/dist/collab/yjs-types.d.ts.map +1 -0
- package/dist/collab/yjs-types.js +45 -0
- package/dist/collab/yjs-types.js.bak +45 -0
- package/dist/collab/yjs-types.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.bak +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.bak +48 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/llm-to-ix.d.ts +249 -0
- package/dist/pipeline/llm-to-ix.d.ts.bak +249 -0
- package/dist/pipeline/llm-to-ix.d.ts.map +1 -0
- package/dist/pipeline/llm-to-ix.js +992 -0
- package/dist/pipeline/llm-to-ix.js.bak +992 -0
- package/dist/pipeline/llm-to-ix.js.map +1 -0
- package/dist/react/index.d.ts +18 -0
- package/dist/react/index.d.ts.bak +18 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +18 -0
- package/dist/react/index.js.bak +18 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/renderer.d.ts +47 -0
- package/dist/react/renderer.d.ts.bak +47 -0
- package/dist/react/renderer.d.ts.map +1 -0
- package/dist/react/renderer.js +420 -0
- package/dist/react/renderer.js.bak +420 -0
- package/dist/react/renderer.js.map +1 -0
- package/dist/renderer/renderer.d.ts +55 -0
- package/dist/renderer/renderer.d.ts.bak +55 -0
- package/dist/renderer/renderer.d.ts.map +1 -0
- package/dist/renderer/renderer.js +232 -0
- package/dist/renderer/renderer.js.bak +232 -0
- package/dist/renderer/renderer.js.map +1 -0
- package/dist/runtime/capsule-runtime.d.ts +227 -0
- package/dist/runtime/capsule-runtime.d.ts.bak +227 -0
- package/dist/runtime/capsule-runtime.d.ts.map +1 -0
- package/dist/runtime/capsule-runtime.js +563 -0
- package/dist/runtime/capsule-runtime.js.bak +563 -0
- package/dist/runtime/capsule-runtime.js.map +1 -0
- package/dist/runtime/policy-gates.d.ts +116 -0
- package/dist/runtime/policy-gates.d.ts.bak +116 -0
- package/dist/runtime/policy-gates.d.ts.map +1 -0
- package/dist/runtime/policy-gates.js +317 -0
- package/dist/runtime/policy-gates.js.bak +317 -0
- package/dist/runtime/policy-gates.js.map +1 -0
- package/dist/schema/ui-ir.d.ts +26 -0
- package/dist/schema/ui-ir.d.ts.bak +26 -0
- package/dist/schema/ui-ir.d.ts.map +1 -0
- package/dist/schema/ui-ir.js +51 -0
- package/dist/schema/ui-ir.js.bak +51 -0
- package/dist/schema/ui-ir.js.map +1 -0
- package/dist/sdk/api.d.ts +101 -0
- package/dist/sdk/api.d.ts.bak +101 -0
- package/dist/sdk/api.d.ts.map +1 -0
- package/dist/sdk/api.js +177 -0
- package/dist/sdk/api.js.bak +177 -0
- package/dist/sdk/api.js.map +1 -0
- package/dist/sdk/index.d.ts +9 -0
- package/dist/sdk/index.d.ts.bak +9 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +10 -0
- package/dist/sdk/index.js.bak +10 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/react.d.ts +63 -0
- package/dist/sdk/react.d.ts.bak +63 -0
- package/dist/sdk/react.d.ts.map +1 -0
- package/dist/sdk/react.js +161 -0
- package/dist/sdk/react.js.bak +161 -0
- package/dist/sdk/react.js.map +1 -0
- package/dist/state/index.d.ts +8 -0
- package/dist/state/index.d.ts.bak +8 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +8 -0
- package/dist/state/index.js.bak +8 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/patch.d.ts +73 -0
- package/dist/state/patch.d.ts.bak +73 -0
- package/dist/state/patch.d.ts.map +1 -0
- package/dist/state/patch.js +437 -0
- package/dist/state/patch.js.bak +437 -0
- package/dist/state/patch.js.map +1 -0
- package/dist/state/store.d.ts +50 -0
- package/dist/state/store.d.ts.bak +50 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +246 -0
- package/dist/state/store.js.bak +246 -0
- package/dist/state/store.js.map +1 -0
- package/dist/svelte/index.d.ts +15 -0
- package/dist/svelte/index.d.ts.bak +15 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +15 -0
- package/dist/svelte/index.js.bak +15 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/svelte/renderer.d.ts +35 -0
- package/dist/svelte/renderer.d.ts.bak +35 -0
- package/dist/svelte/renderer.d.ts.map +1 -0
- package/dist/svelte/renderer.js +317 -0
- package/dist/svelte/renderer.js.bak +317 -0
- package/dist/svelte/renderer.js.map +1 -0
- package/dist/types/index.d.ts +349 -0
- package/dist/types/index.d.ts.bak +349 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +152 -0
- package/dist/types/index.js.bak +152 -0
- package/dist/types/index.js.map +1 -0
- package/dist/vue/index.d.ts +18 -0
- package/dist/vue/index.d.ts.bak +18 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +18 -0
- package/dist/vue/index.js.bak +18 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/vue/renderer.d.ts +46 -0
- package/dist/vue/renderer.d.ts.bak +46 -0
- package/dist/vue/renderer.d.ts.map +1 -0
- package/dist/vue/renderer.js +302 -0
- package/dist/vue/renderer.js.bak +302 -0
- package/dist/vue/renderer.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Gates
|
|
3
|
+
*
|
|
4
|
+
* Security controls for IX capsule execution.
|
|
5
|
+
*
|
|
6
|
+
* Policy gates enforce security boundaries for:
|
|
7
|
+
* - Action execution (rate limiting, allowlists)
|
|
8
|
+
* - State changes (validation, sanitization)
|
|
9
|
+
* - Rendering (component restrictions, prop filtering)
|
|
10
|
+
*/
|
|
11
|
+
export interface PolicyContext {
|
|
12
|
+
/** Capsule ID */
|
|
13
|
+
capsuleId: string;
|
|
14
|
+
/** Action being performed */
|
|
15
|
+
actionId?: string;
|
|
16
|
+
/** Action parameters */
|
|
17
|
+
params?: Record<string, unknown>;
|
|
18
|
+
/** State snapshot */
|
|
19
|
+
state?: Record<string, unknown>;
|
|
20
|
+
/** Component being rendered */
|
|
21
|
+
component?: string;
|
|
22
|
+
/** Props being passed */
|
|
23
|
+
props?: Record<string, unknown>;
|
|
24
|
+
/** Timestamp */
|
|
25
|
+
timestamp: number;
|
|
26
|
+
/** User/agent identifier */
|
|
27
|
+
agentId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface PolicyResult {
|
|
30
|
+
allowed: boolean;
|
|
31
|
+
reason?: string;
|
|
32
|
+
/** Modified context (for sanitization) */
|
|
33
|
+
context?: PolicyContext;
|
|
34
|
+
/** Audit log entry */
|
|
35
|
+
audit?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface PolicyGate {
|
|
38
|
+
name: string;
|
|
39
|
+
check: (type: 'action' | 'state-change' | 'render', context: PolicyContext) => Promise<PolicyResult> | PolicyResult;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Rate Limiting Policy Gate
|
|
43
|
+
*
|
|
44
|
+
* Limits action execution rate per capsule.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createRateLimitGate(options: {
|
|
47
|
+
maxActionsPerMinute: number;
|
|
48
|
+
burstSize?: number;
|
|
49
|
+
windowMs?: number;
|
|
50
|
+
}): PolicyGate;
|
|
51
|
+
/**
|
|
52
|
+
* Action Allowlist Policy Gate
|
|
53
|
+
*
|
|
54
|
+
* Only allows specific actions to execute.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createActionAllowlistGate(allowedActions: string[]): PolicyGate;
|
|
57
|
+
/**
|
|
58
|
+
* Component Restrictions Policy Gate
|
|
59
|
+
*
|
|
60
|
+
* Restricts which components can be rendered.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createComponentRestrictionsGate(options: {
|
|
63
|
+
allowedComponents?: string[];
|
|
64
|
+
blockedComponents?: string[];
|
|
65
|
+
maxDepth?: number;
|
|
66
|
+
}): PolicyGate;
|
|
67
|
+
/**
|
|
68
|
+
* State Validation Policy Gate
|
|
69
|
+
*
|
|
70
|
+
* Validates state changes against schema.
|
|
71
|
+
*/
|
|
72
|
+
export declare function createStateValidationGate(schema: {
|
|
73
|
+
[path: string]: {
|
|
74
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
75
|
+
required?: boolean;
|
|
76
|
+
validate?: (value: unknown) => boolean | string;
|
|
77
|
+
};
|
|
78
|
+
}): PolicyGate;
|
|
79
|
+
/**
|
|
80
|
+
* Prop Sanitization Policy Gate
|
|
81
|
+
*
|
|
82
|
+
* Sanitizes component props to prevent XSS and injection attacks.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createPropSanitizationGate(options: {
|
|
85
|
+
allowHTML?: boolean;
|
|
86
|
+
allowedTags?: string[];
|
|
87
|
+
allowedAttributes?: string[];
|
|
88
|
+
}): PolicyGate;
|
|
89
|
+
/**
|
|
90
|
+
* Resource Limiting Policy Gate
|
|
91
|
+
*
|
|
92
|
+
* Enforces resource limits on capsules.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createResourceLimitGate(options: {
|
|
95
|
+
maxStateSize?: number;
|
|
96
|
+
maxComponents?: number;
|
|
97
|
+
maxActions?: number;
|
|
98
|
+
}): PolicyGate;
|
|
99
|
+
/**
|
|
100
|
+
* Audit Logging Policy Gate
|
|
101
|
+
*
|
|
102
|
+
* Logs all policy decisions for audit purposes.
|
|
103
|
+
*/
|
|
104
|
+
export declare function createAuditLogGate(options: {
|
|
105
|
+
logFn: (entry: Record<string, unknown>) => void;
|
|
106
|
+
logAllowed?: boolean;
|
|
107
|
+
}): PolicyGate;
|
|
108
|
+
/**
|
|
109
|
+
* Compose multiple policy gates
|
|
110
|
+
*/
|
|
111
|
+
export declare function composePolicyGates(...gates: PolicyGate[]): PolicyGate;
|
|
112
|
+
/**
|
|
113
|
+
* Create default security policy gates
|
|
114
|
+
*/
|
|
115
|
+
export declare function createDefaultPolicyGates(): PolicyGate[];
|
|
116
|
+
//# sourceMappingURL=policy-gates.d.ts.map
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Gates
|
|
3
|
+
*
|
|
4
|
+
* Security controls for IX capsule execution.
|
|
5
|
+
*
|
|
6
|
+
* Policy gates enforce security boundaries for:
|
|
7
|
+
* - Action execution (rate limiting, allowlists)
|
|
8
|
+
* - State changes (validation, sanitization)
|
|
9
|
+
* - Rendering (component restrictions, prop filtering)
|
|
10
|
+
*/
|
|
11
|
+
export interface PolicyContext {
|
|
12
|
+
/** Capsule ID */
|
|
13
|
+
capsuleId: string;
|
|
14
|
+
/** Action being performed */
|
|
15
|
+
actionId?: string;
|
|
16
|
+
/** Action parameters */
|
|
17
|
+
params?: Record<string, unknown>;
|
|
18
|
+
/** State snapshot */
|
|
19
|
+
state?: Record<string, unknown>;
|
|
20
|
+
/** Component being rendered */
|
|
21
|
+
component?: string;
|
|
22
|
+
/** Props being passed */
|
|
23
|
+
props?: Record<string, unknown>;
|
|
24
|
+
/** Timestamp */
|
|
25
|
+
timestamp: number;
|
|
26
|
+
/** User/agent identifier */
|
|
27
|
+
agentId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface PolicyResult {
|
|
30
|
+
allowed: boolean;
|
|
31
|
+
reason?: string;
|
|
32
|
+
/** Modified context (for sanitization) */
|
|
33
|
+
context?: PolicyContext;
|
|
34
|
+
/** Audit log entry */
|
|
35
|
+
audit?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface PolicyGate {
|
|
38
|
+
name: string;
|
|
39
|
+
check: (type: 'action' | 'state-change' | 'render', context: PolicyContext) => Promise<PolicyResult> | PolicyResult;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Rate Limiting Policy Gate
|
|
43
|
+
*
|
|
44
|
+
* Limits action execution rate per capsule.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createRateLimitGate(options: {
|
|
47
|
+
maxActionsPerMinute: number;
|
|
48
|
+
burstSize?: number;
|
|
49
|
+
windowMs?: number;
|
|
50
|
+
}): PolicyGate;
|
|
51
|
+
/**
|
|
52
|
+
* Action Allowlist Policy Gate
|
|
53
|
+
*
|
|
54
|
+
* Only allows specific actions to execute.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createActionAllowlistGate(allowedActions: string[]): PolicyGate;
|
|
57
|
+
/**
|
|
58
|
+
* Component Restrictions Policy Gate
|
|
59
|
+
*
|
|
60
|
+
* Restricts which components can be rendered.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createComponentRestrictionsGate(options: {
|
|
63
|
+
allowedComponents?: string[];
|
|
64
|
+
blockedComponents?: string[];
|
|
65
|
+
maxDepth?: number;
|
|
66
|
+
}): PolicyGate;
|
|
67
|
+
/**
|
|
68
|
+
* State Validation Policy Gate
|
|
69
|
+
*
|
|
70
|
+
* Validates state changes against schema.
|
|
71
|
+
*/
|
|
72
|
+
export declare function createStateValidationGate(schema: {
|
|
73
|
+
[path: string]: {
|
|
74
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
75
|
+
required?: boolean;
|
|
76
|
+
validate?: (value: unknown) => boolean | string;
|
|
77
|
+
};
|
|
78
|
+
}): PolicyGate;
|
|
79
|
+
/**
|
|
80
|
+
* Prop Sanitization Policy Gate
|
|
81
|
+
*
|
|
82
|
+
* Sanitizes component props to prevent XSS and injection attacks.
|
|
83
|
+
*/
|
|
84
|
+
export declare function createPropSanitizationGate(options: {
|
|
85
|
+
allowHTML?: boolean;
|
|
86
|
+
allowedTags?: string[];
|
|
87
|
+
allowedAttributes?: string[];
|
|
88
|
+
}): PolicyGate;
|
|
89
|
+
/**
|
|
90
|
+
* Resource Limiting Policy Gate
|
|
91
|
+
*
|
|
92
|
+
* Enforces resource limits on capsules.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createResourceLimitGate(options: {
|
|
95
|
+
maxStateSize?: number;
|
|
96
|
+
maxComponents?: number;
|
|
97
|
+
maxActions?: number;
|
|
98
|
+
}): PolicyGate;
|
|
99
|
+
/**
|
|
100
|
+
* Audit Logging Policy Gate
|
|
101
|
+
*
|
|
102
|
+
* Logs all policy decisions for audit purposes.
|
|
103
|
+
*/
|
|
104
|
+
export declare function createAuditLogGate(options: {
|
|
105
|
+
logFn: (entry: Record<string, unknown>) => void;
|
|
106
|
+
logAllowed?: boolean;
|
|
107
|
+
}): PolicyGate;
|
|
108
|
+
/**
|
|
109
|
+
* Compose multiple policy gates
|
|
110
|
+
*/
|
|
111
|
+
export declare function composePolicyGates(...gates: PolicyGate[]): PolicyGate;
|
|
112
|
+
/**
|
|
113
|
+
* Create default security policy gates
|
|
114
|
+
*/
|
|
115
|
+
export declare function createDefaultPolicyGates(): PolicyGate[];
|
|
116
|
+
//# sourceMappingURL=policy-gates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-gates.d.ts","sourceRoot":"","sources":["../../src/runtime/policy-gates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Gates
|
|
3
|
+
*
|
|
4
|
+
* Security controls for IX capsule execution.
|
|
5
|
+
*
|
|
6
|
+
* Policy gates enforce security boundaries for:
|
|
7
|
+
* - Action execution (rate limiting, allowlists)
|
|
8
|
+
* - State changes (validation, sanitization)
|
|
9
|
+
* - Rendering (component restrictions, prop filtering)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Rate Limiting Policy Gate
|
|
13
|
+
*
|
|
14
|
+
* Limits action execution rate per capsule.
|
|
15
|
+
*/
|
|
16
|
+
export function createRateLimitGate(options) {
|
|
17
|
+
const { maxActionsPerMinute, burstSize = maxActionsPerMinute, windowMs = 60000 } = options;
|
|
18
|
+
const actionLog = new Map();
|
|
19
|
+
return {
|
|
20
|
+
name: 'rate-limit',
|
|
21
|
+
check: (_type, context) => {
|
|
22
|
+
if (_type !== 'action')
|
|
23
|
+
return { allowed: true };
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
const log = actionLog.get(context.capsuleId) || [];
|
|
26
|
+
// Remove old entries outside window
|
|
27
|
+
const validLog = log.filter((ts) => now - ts < windowMs);
|
|
28
|
+
// Check burst limit
|
|
29
|
+
if (validLog.length >= burstSize) {
|
|
30
|
+
return {
|
|
31
|
+
allowed: false,
|
|
32
|
+
reason: `Rate limit exceeded: ${maxActionsPerMinute} actions per minute`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Record action
|
|
36
|
+
validLog.push(now);
|
|
37
|
+
actionLog.set(context.capsuleId, validLog);
|
|
38
|
+
return { allowed: true };
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Action Allowlist Policy Gate
|
|
44
|
+
*
|
|
45
|
+
* Only allows specific actions to execute.
|
|
46
|
+
*/
|
|
47
|
+
export function createActionAllowlistGate(allowedActions) {
|
|
48
|
+
const allowedSet = new Set(allowedActions);
|
|
49
|
+
return {
|
|
50
|
+
name: 'action-allowlist',
|
|
51
|
+
check: (type, context) => {
|
|
52
|
+
if (type !== 'action')
|
|
53
|
+
return { allowed: true };
|
|
54
|
+
if (!context.actionId || !allowedSet.has(context.actionId)) {
|
|
55
|
+
return {
|
|
56
|
+
allowed: false,
|
|
57
|
+
reason: `Action '${context.actionId}' is not in allowlist`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return { allowed: true };
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Component Restrictions Policy Gate
|
|
66
|
+
*
|
|
67
|
+
* Restricts which components can be rendered.
|
|
68
|
+
*/
|
|
69
|
+
export function createComponentRestrictionsGate(options) {
|
|
70
|
+
const { allowedComponents, blockedComponents = [], maxDepth = 10 } = options;
|
|
71
|
+
const allowedSet = allowedComponents ? new Set(allowedComponents) : null;
|
|
72
|
+
const blockedSet = new Set(blockedComponents);
|
|
73
|
+
return {
|
|
74
|
+
name: 'component-restrictions',
|
|
75
|
+
check: (type, context) => {
|
|
76
|
+
if (type !== 'render')
|
|
77
|
+
return { allowed: true };
|
|
78
|
+
if (!context.component)
|
|
79
|
+
return { allowed: true };
|
|
80
|
+
// Check blocked
|
|
81
|
+
if (blockedSet.has(context.component)) {
|
|
82
|
+
return {
|
|
83
|
+
allowed: false,
|
|
84
|
+
reason: `Component '${context.component}' is blocked`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Check allowed
|
|
88
|
+
if (allowedSet && !allowedSet.has(context.component)) {
|
|
89
|
+
return {
|
|
90
|
+
allowed: false,
|
|
91
|
+
reason: `Component '${context.component}' is not in allowlist`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return { allowed: true };
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* State Validation Policy Gate
|
|
100
|
+
*
|
|
101
|
+
* Validates state changes against schema.
|
|
102
|
+
*/
|
|
103
|
+
export function createStateValidationGate(schema) {
|
|
104
|
+
return {
|
|
105
|
+
name: 'state-validation',
|
|
106
|
+
check: (type, context) => {
|
|
107
|
+
if (type !== 'state-change')
|
|
108
|
+
return { allowed: true };
|
|
109
|
+
// This would need the actual path and value being changed
|
|
110
|
+
// For now, validate entire state snapshot
|
|
111
|
+
if (!context.state)
|
|
112
|
+
return { allowed: true };
|
|
113
|
+
for (const [path, rules] of Object.entries(schema)) {
|
|
114
|
+
const value = getPathValue(context.state, path);
|
|
115
|
+
// Check required
|
|
116
|
+
if (rules.required && (value === undefined || value === null)) {
|
|
117
|
+
return {
|
|
118
|
+
allowed: false,
|
|
119
|
+
reason: `State path '${path}' is required`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// Skip if not required and undefined
|
|
123
|
+
if (!rules.required && (value === undefined || value === null)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
// Check type
|
|
127
|
+
if (rules.type) {
|
|
128
|
+
const actualType = getValueType(value);
|
|
129
|
+
if (actualType !== rules.type) {
|
|
130
|
+
return {
|
|
131
|
+
allowed: false,
|
|
132
|
+
reason: `State path '${path}' must be ${rules.type}, got ${actualType}`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Run custom validation
|
|
137
|
+
if (rules.validate) {
|
|
138
|
+
const result = rules.validate(value);
|
|
139
|
+
if (result !== true) {
|
|
140
|
+
return {
|
|
141
|
+
allowed: false,
|
|
142
|
+
reason: typeof result === 'string' ? result : `Validation failed for '${path}'`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { allowed: true };
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Prop Sanitization Policy Gate
|
|
153
|
+
*
|
|
154
|
+
* Sanitizes component props to prevent XSS and injection attacks.
|
|
155
|
+
*/
|
|
156
|
+
export function createPropSanitizationGate(options) {
|
|
157
|
+
const { allowHTML = false, allowedTags = [], allowedAttributes = [] } = options;
|
|
158
|
+
return {
|
|
159
|
+
name: 'prop-sanitization',
|
|
160
|
+
check: (type, context) => {
|
|
161
|
+
if (type !== 'render' || !context.props)
|
|
162
|
+
return { allowed: true };
|
|
163
|
+
const sanitizedProps = { ...context.props };
|
|
164
|
+
let modified = false;
|
|
165
|
+
for (const [key, value] of Object.entries(context.props)) {
|
|
166
|
+
// Sanitize string values
|
|
167
|
+
if (typeof value === 'string') {
|
|
168
|
+
// Remove script tags and event handlers
|
|
169
|
+
let sanitized = value;
|
|
170
|
+
if (!allowHTML) {
|
|
171
|
+
// Strip all HTML
|
|
172
|
+
sanitized = sanitized.replace(/<[^>]*>/g, '');
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Remove script tags and their content completely
|
|
176
|
+
sanitized = sanitized.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
|
|
177
|
+
// Allow only specific tags
|
|
178
|
+
const tagRegex = /<\/?([a-z][a-z0-9]*)[^>]*>/gi;
|
|
179
|
+
sanitized = sanitized.replace(tagRegex, (match, tag) => {
|
|
180
|
+
return allowedTags.includes(tag.toLowerCase()) ? match : '';
|
|
181
|
+
});
|
|
182
|
+
// Remove event handlers
|
|
183
|
+
sanitized = sanitized.replace(/on\w+\s*=/gi, '');
|
|
184
|
+
// Remove javascript: URLs
|
|
185
|
+
sanitized = sanitized.replace(/javascript:/gi, '');
|
|
186
|
+
}
|
|
187
|
+
if (sanitized !== value) {
|
|
188
|
+
sanitizedProps[key] = sanitized;
|
|
189
|
+
modified = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Block dangerous props
|
|
193
|
+
if (key.startsWith('on') && typeof value === 'string') {
|
|
194
|
+
// Block string-based event handlers
|
|
195
|
+
delete sanitizedProps[key];
|
|
196
|
+
modified = true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
allowed: true,
|
|
201
|
+
context: modified ? { ...context, props: sanitizedProps } : context,
|
|
202
|
+
};
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Resource Limiting Policy Gate
|
|
208
|
+
*
|
|
209
|
+
* Enforces resource limits on capsules.
|
|
210
|
+
*/
|
|
211
|
+
export function createResourceLimitGate(options) {
|
|
212
|
+
const { maxStateSize = 1024 * 1024, maxComponents = 100, maxActions = 1000 } = options;
|
|
213
|
+
const actionCounts = new Map();
|
|
214
|
+
return {
|
|
215
|
+
name: 'resource-limit',
|
|
216
|
+
check: (type, context) => {
|
|
217
|
+
// Check state size
|
|
218
|
+
if (type === 'state-change' && context.state) {
|
|
219
|
+
const stateSize = JSON.stringify(context.state).length;
|
|
220
|
+
if (stateSize > maxStateSize) {
|
|
221
|
+
return {
|
|
222
|
+
allowed: false,
|
|
223
|
+
reason: `State size (${stateSize} bytes) exceeds limit (${maxStateSize} bytes)`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Check action count
|
|
228
|
+
if (type === 'action') {
|
|
229
|
+
const count = (actionCounts.get(context.capsuleId) || 0) + 1;
|
|
230
|
+
if (count > maxActions) {
|
|
231
|
+
return {
|
|
232
|
+
allowed: false,
|
|
233
|
+
reason: `Maximum action count (${maxActions}) exceeded`,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
actionCounts.set(context.capsuleId, count);
|
|
237
|
+
}
|
|
238
|
+
return { allowed: true };
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Audit Logging Policy Gate
|
|
244
|
+
*
|
|
245
|
+
* Logs all policy decisions for audit purposes.
|
|
246
|
+
*/
|
|
247
|
+
export function createAuditLogGate(options) {
|
|
248
|
+
const { logFn, logAllowed = false } = options;
|
|
249
|
+
return {
|
|
250
|
+
name: 'audit-log',
|
|
251
|
+
check: (type, context) => {
|
|
252
|
+
const shouldLog = logAllowed || type === 'action';
|
|
253
|
+
if (shouldLog) {
|
|
254
|
+
logFn({
|
|
255
|
+
timestamp: Date.now(),
|
|
256
|
+
capsuleId: context.capsuleId,
|
|
257
|
+
actionId: context.actionId,
|
|
258
|
+
type,
|
|
259
|
+
agentId: context.agentId,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return { allowed: true };
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Compose multiple policy gates
|
|
268
|
+
*/
|
|
269
|
+
export function composePolicyGates(...gates) {
|
|
270
|
+
return {
|
|
271
|
+
name: `composed(${gates.map((g) => g.name).join(', ')})`,
|
|
272
|
+
check: async (type, context) => {
|
|
273
|
+
let currentContext = context;
|
|
274
|
+
for (const gate of gates) {
|
|
275
|
+
const result = await gate.check(type, currentContext);
|
|
276
|
+
if (!result.allowed) {
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
if (result.context) {
|
|
280
|
+
currentContext = result.context;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return { allowed: true, context: currentContext };
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Create default security policy gates
|
|
289
|
+
*/
|
|
290
|
+
export function createDefaultPolicyGates() {
|
|
291
|
+
return [
|
|
292
|
+
createRateLimitGate({ maxActionsPerMinute: 60 }),
|
|
293
|
+
createPropSanitizationGate({ allowHTML: false }),
|
|
294
|
+
createResourceLimitGate({
|
|
295
|
+
maxStateSize: 1024 * 1024, // 1MB
|
|
296
|
+
maxComponents: 100,
|
|
297
|
+
maxActions: 1000,
|
|
298
|
+
}),
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
// Helper functions
|
|
302
|
+
function getPathValue(obj, path) {
|
|
303
|
+
return path.split('.').reduce((acc, key) => {
|
|
304
|
+
if (acc && typeof acc === 'object') {
|
|
305
|
+
return acc[key];
|
|
306
|
+
}
|
|
307
|
+
return undefined;
|
|
308
|
+
}, obj);
|
|
309
|
+
}
|
|
310
|
+
function getValueType(value) {
|
|
311
|
+
if (value === null)
|
|
312
|
+
return 'null';
|
|
313
|
+
if (Array.isArray(value))
|
|
314
|
+
return 'array';
|
|
315
|
+
return typeof value;
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=policy-gates.js.map
|