@highflame/policy 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_schemas/overwatch/context.json +0 -30
- package/_schemas/overwatch/schema.cedarschema +0 -5
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +16 -3
- package/dist/builder.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/overwatch-context.gen.d.ts +0 -2
- package/dist/overwatch-context.gen.d.ts.map +1 -1
- package/dist/overwatch-context.gen.js +0 -2
- package/dist/overwatch-context.gen.js.map +1 -1
- package/dist/schemas.test.js +0 -4
- package/dist/schemas.test.js.map +1 -1
- package/dist/service-schemas.gen.d.ts +48 -0
- package/dist/service-schemas.gen.d.ts.map +1 -0
- package/dist/service-schemas.gen.js +581 -0
- package/dist/service-schemas.gen.js.map +1 -0
- package/dist/studio-ui.test.d.ts +8 -0
- package/dist/studio-ui.test.d.ts.map +1 -0
- package/dist/studio-ui.test.js +165 -0
- package/dist/studio-ui.test.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/builder.ts +17 -3
- package/src/index.ts +17 -0
- package/src/overwatch-context.gen.ts +0 -2
- package/src/schemas.test.ts +0 -4
- package/src/service-schemas.gen.ts +608 -0
- package/src/studio-ui.test.ts +207 -0
- package/src/types.ts +17 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio UI Integration Tests
|
|
3
|
+
*
|
|
4
|
+
* These tests simulate exactly how the Studio UI (Overwatch admin dashboard)
|
|
5
|
+
* will use the @highflame/policy npm package.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
// Browser-safe imports (simulating '@highflame/policy/types')
|
|
9
|
+
import { PolicyBuilder, OVERWATCH_SCHEMA, PALISADE_SCHEMA, OVERWATCH_CONTEXT, OverwatchContextKey, PalisadeContextKey, } from './types.js';
|
|
10
|
+
// Node.js only imports (for API routes)
|
|
11
|
+
import { PolicyEngine, PolicyValidator, newEntityUID, newEntity, } from './index.js';
|
|
12
|
+
describe('Studio UI Integration Tests', () => {
|
|
13
|
+
/**
|
|
14
|
+
* Test: PolicyBuilder action formatting
|
|
15
|
+
*
|
|
16
|
+
* Tests that simple action names are properly formatted to Cedar syntax.
|
|
17
|
+
* This is the "normal approach" for non-namespaced schemas.
|
|
18
|
+
*/
|
|
19
|
+
it('should format simple action names to Cedar syntax', () => {
|
|
20
|
+
// Using simple action name (normal approach)
|
|
21
|
+
const policy = PolicyBuilder.permit()
|
|
22
|
+
.principalType('User')
|
|
23
|
+
.action('call_tool')
|
|
24
|
+
.resourceType('Tool')
|
|
25
|
+
.build();
|
|
26
|
+
const cedarText = policy.toCedar();
|
|
27
|
+
// Simple actions should be wrapped as Action::"..."
|
|
28
|
+
expect(cedarText).toContain('action == Action::"call_tool"');
|
|
29
|
+
expect(cedarText).not.toContain('Action::"Action::'); // No double-wrapping
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Test 1: Schema and Context Loading
|
|
33
|
+
*
|
|
34
|
+
* Studio UI needs to load schemas for validation and context metadata
|
|
35
|
+
* for populating form dropdowns.
|
|
36
|
+
*/
|
|
37
|
+
it('should load schemas and context metadata for form builders', () => {
|
|
38
|
+
// Schemas should be strings
|
|
39
|
+
expect(typeof OVERWATCH_SCHEMA).toBe('string');
|
|
40
|
+
expect(OVERWATCH_SCHEMA).toContain('namespace Overwatch');
|
|
41
|
+
expect(typeof PALISADE_SCHEMA).toBe('string');
|
|
42
|
+
expect(PALISADE_SCHEMA).toContain('namespace Palisade');
|
|
43
|
+
// Context metadata should have action definitions
|
|
44
|
+
expect(OVERWATCH_CONTEXT.service).toBe('overwatch');
|
|
45
|
+
expect(OVERWATCH_CONTEXT.actions.length).toBeGreaterThan(0);
|
|
46
|
+
// Find call_tool action and verify context attributes
|
|
47
|
+
const callToolAction = OVERWATCH_CONTEXT.actions.find((a) => a.name === 'call_tool');
|
|
48
|
+
expect(callToolAction).toBeDefined();
|
|
49
|
+
expect(callToolAction.context_attributes.length).toBeGreaterThan(0);
|
|
50
|
+
// Context keys should be available for type-safe form building
|
|
51
|
+
expect(OverwatchContextKey.ToolName).toBe('tool_name');
|
|
52
|
+
expect(OverwatchContextKey.ThreatCount).toBe('threat_count');
|
|
53
|
+
expect(PalisadeContextKey.Severity).toBe('severity');
|
|
54
|
+
expect(PalisadeContextKey.Environment).toBe('environment');
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Test 2: Full Round-Trip - Create Policy → Validate → Evaluate
|
|
58
|
+
*
|
|
59
|
+
* This simulates the complete flow:
|
|
60
|
+
* 1. User creates a policy using PolicyBuilder in the UI
|
|
61
|
+
* 2. API validates the policy against the schema
|
|
62
|
+
* 3. Runtime evaluates the policy
|
|
63
|
+
*/
|
|
64
|
+
it('should complete full policy lifecycle for Overwatch', () => {
|
|
65
|
+
// Step 1: User creates policy in form UI
|
|
66
|
+
const policy = PolicyBuilder.permit()
|
|
67
|
+
.principalType('Overwatch::User')
|
|
68
|
+
.action('Overwatch::Action::"call_tool"')
|
|
69
|
+
.resourceType('Overwatch::Tool')
|
|
70
|
+
.whenRaw('context.threat_count < 5')
|
|
71
|
+
.build();
|
|
72
|
+
const cedarText = policy.toCedar();
|
|
73
|
+
expect(cedarText).toContain('permit');
|
|
74
|
+
expect(cedarText).toContain('Overwatch::User');
|
|
75
|
+
// Step 2: API validates policy against schema
|
|
76
|
+
const validator = new PolicyValidator(OVERWATCH_SCHEMA);
|
|
77
|
+
const validationResult = validator.validate(cedarText);
|
|
78
|
+
expect(validationResult.valid).toBe(true);
|
|
79
|
+
// Step 3: Runtime loads and evaluates policy
|
|
80
|
+
const engine = new PolicyEngine({ schema: OVERWATCH_SCHEMA });
|
|
81
|
+
engine.loadPolicies(cedarText);
|
|
82
|
+
const entities = [
|
|
83
|
+
newEntity('Overwatch::User', 'mcp_client', { user_type: 'external', email: 'test@example.com' }),
|
|
84
|
+
newEntity('Overwatch::Tool', 'shell', { tool_name: 'shell', risk_level: 'high' }),
|
|
85
|
+
];
|
|
86
|
+
// Full context as Guardian will provide at runtime
|
|
87
|
+
const baseContext = {
|
|
88
|
+
content: 'ls -la',
|
|
89
|
+
source: 'claudecode',
|
|
90
|
+
event: 'PreToolUse',
|
|
91
|
+
user_email: 'test@example.com',
|
|
92
|
+
tool_name: 'shell',
|
|
93
|
+
mcp_server: 'filesystem',
|
|
94
|
+
mcp_tool: 'shell',
|
|
95
|
+
path: '/workspace',
|
|
96
|
+
cwd: '/workspace',
|
|
97
|
+
workspace_root: '/workspace',
|
|
98
|
+
highest_severity: 'low',
|
|
99
|
+
threat_categories: [],
|
|
100
|
+
threat_types: [],
|
|
101
|
+
yara_threats: [],
|
|
102
|
+
max_threat_severity: 1,
|
|
103
|
+
contains_secrets: false,
|
|
104
|
+
response_content: '',
|
|
105
|
+
};
|
|
106
|
+
// Should allow when threat_count < 5
|
|
107
|
+
const allowDecision = engine.evaluate({
|
|
108
|
+
principal: newEntityUID('Overwatch::User', 'mcp_client'),
|
|
109
|
+
action: 'Overwatch::Action::"call_tool"',
|
|
110
|
+
resource: newEntityUID('Overwatch::Tool', 'shell'),
|
|
111
|
+
context: { ...baseContext, threat_count: 3 },
|
|
112
|
+
entities,
|
|
113
|
+
});
|
|
114
|
+
expect(allowDecision.effect).toBe('Allow');
|
|
115
|
+
// Should deny when threat_count >= 5 (no matching permit)
|
|
116
|
+
const denyDecision = engine.evaluate({
|
|
117
|
+
principal: newEntityUID('Overwatch::User', 'mcp_client'),
|
|
118
|
+
action: 'Overwatch::Action::"call_tool"',
|
|
119
|
+
resource: newEntityUID('Overwatch::Tool', 'shell'),
|
|
120
|
+
context: { ...baseContext, threat_count: 10 },
|
|
121
|
+
entities,
|
|
122
|
+
});
|
|
123
|
+
expect(denyDecision.effect).toBe('Deny');
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Test 3: Full Round-Trip for Palisade
|
|
127
|
+
*
|
|
128
|
+
* Same flow but for Palisade ML security policies.
|
|
129
|
+
*/
|
|
130
|
+
it('should complete full policy lifecycle for Palisade', () => {
|
|
131
|
+
// Step 1: Create a forbid policy for CRITICAL findings
|
|
132
|
+
const policy = PolicyBuilder.forbid()
|
|
133
|
+
.principalType('Palisade::Scanner')
|
|
134
|
+
.action('Palisade::Action::"load_model"')
|
|
135
|
+
.resourceType('Palisade::Artifact')
|
|
136
|
+
.whenRaw('context.severity == "CRITICAL"')
|
|
137
|
+
.build();
|
|
138
|
+
const cedarText = policy.toCedar();
|
|
139
|
+
// Step 2: Validate
|
|
140
|
+
const validator = new PolicyValidator(PALISADE_SCHEMA);
|
|
141
|
+
expect(validator.validate(cedarText).valid).toBe(true);
|
|
142
|
+
// Step 3: Evaluate
|
|
143
|
+
const engine = new PolicyEngine({ schema: PALISADE_SCHEMA });
|
|
144
|
+
engine.loadPolicies(cedarText);
|
|
145
|
+
const entities = [
|
|
146
|
+
newEntity('Palisade::Scanner', 'palisade', { scanner_type: 'ml' }),
|
|
147
|
+
newEntity('Palisade::Artifact', 'model.pkl', {
|
|
148
|
+
artifact_format: 'pickle',
|
|
149
|
+
path: '/model.pkl',
|
|
150
|
+
signed: false,
|
|
151
|
+
signer: 'unsigned',
|
|
152
|
+
}),
|
|
153
|
+
];
|
|
154
|
+
// Should deny CRITICAL findings
|
|
155
|
+
const decision = engine.evaluate({
|
|
156
|
+
principal: newEntityUID('Palisade::Scanner', 'palisade'),
|
|
157
|
+
action: 'Palisade::Action::"load_model"',
|
|
158
|
+
resource: newEntityUID('Palisade::Artifact', 'model.pkl'),
|
|
159
|
+
context: { severity: 'CRITICAL' },
|
|
160
|
+
entities,
|
|
161
|
+
});
|
|
162
|
+
expect(decision.effect).toBe('Deny');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=studio-ui.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studio-ui.test.js","sourceRoot":"","sources":["../src/studio-ui.test.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,4 +4,8 @@ export * from './context.gen.js';
|
|
|
4
4
|
export * from './schema.gen.js';
|
|
5
5
|
export * from './builder.js';
|
|
6
6
|
export * from './errors.js';
|
|
7
|
+
export { OVERWATCH_SCHEMA, PALISADE_SCHEMA, OVERWATCH_CONTEXT, PALISADE_CONTEXT, } from './service-schemas.gen.js';
|
|
8
|
+
export type { ContextAttribute, ActionContext, ServiceContext, } from './service-schemas.gen.js';
|
|
9
|
+
export { OverwatchContextKey } from './overwatch-context.gen.js';
|
|
10
|
+
export { PalisadeContextKey } from './palisade-context.gen.js';
|
|
7
11
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,cAAc,CAAC;AAG7B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,cAAc,CAAC;AAG7B,cAAc,aAAa,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,GACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/types.js
CHANGED
|
@@ -13,4 +13,9 @@ export * from './schema.gen.js';
|
|
|
13
13
|
export * from './builder.js';
|
|
14
14
|
// Error types - works in browser (no WASM dependency)
|
|
15
15
|
export * from './errors.js';
|
|
16
|
+
// Service-specific schemas and context (inlined, browser-safe)
|
|
17
|
+
export { OVERWATCH_SCHEMA, PALISADE_SCHEMA, OVERWATCH_CONTEXT, PALISADE_CONTEXT, } from './service-schemas.gen.js';
|
|
18
|
+
// Service-specific context key enums
|
|
19
|
+
export { OverwatchContextKey } from './overwatch-context.gen.js';
|
|
20
|
+
export { PalisadeContextKey } from './palisade-context.gen.js';
|
|
16
21
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,uCAAuC;AACvC,EAAE;AACF,6CAA6C;AAC7C,gDAAgD;AAChD,yEAAyE;AAEzE,gDAAgD;AAChD,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,wDAAwD;AACxD,cAAc,cAAc,CAAC;AAE7B,sDAAsD;AACtD,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,uCAAuC;AACvC,EAAE;AACF,6CAA6C;AAC7C,gDAAgD;AAChD,yEAAyE;AAEzE,gDAAgD;AAChD,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,wDAAwD;AACxD,cAAc,cAAc,CAAC;AAE7B,sDAAsD;AACtD,cAAc,aAAa,CAAC;AAE5B,+DAA+D;AAC/D,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAOlC,qCAAqC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/package.json
CHANGED
package/src/builder.ts
CHANGED
|
@@ -25,6 +25,20 @@
|
|
|
25
25
|
import { EntityType, EntityUID } from './entities.gen.js';
|
|
26
26
|
import { ActionType } from './actions.gen.js';
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Format an action string for Cedar policy text.
|
|
30
|
+
* Detects if action is already namespaced (contains 'Action::"') and preserves it,
|
|
31
|
+
* otherwise wraps with Action::"...".
|
|
32
|
+
*/
|
|
33
|
+
function formatAction(action: string): string {
|
|
34
|
+
if (action.includes('Action::"')) {
|
|
35
|
+
// Already namespaced (e.g., 'Overwatch::Action::"call_tool"')
|
|
36
|
+
return action;
|
|
37
|
+
}
|
|
38
|
+
// Non-namespaced, wrap with Action::"..."
|
|
39
|
+
return `Action::"${action}"`;
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
/**
|
|
29
43
|
* Policy effect - permit or forbid
|
|
30
44
|
*/
|
|
@@ -163,13 +177,13 @@ export class Policy {
|
|
|
163
177
|
// Action
|
|
164
178
|
if (Array.isArray(this.data.action)) {
|
|
165
179
|
if (this.data.action.length === 1) {
|
|
166
|
-
policyLine += `,\n action ==
|
|
180
|
+
policyLine += `,\n action == ${formatAction(this.data.action[0])}`;
|
|
167
181
|
} else {
|
|
168
|
-
const actions = this.data.action.map(a =>
|
|
182
|
+
const actions = this.data.action.map(a => formatAction(a)).join(', ');
|
|
169
183
|
policyLine += `,\n action in [${actions}]`;
|
|
170
184
|
}
|
|
171
185
|
} else {
|
|
172
|
-
policyLine += `,\n action ==
|
|
186
|
+
policyLine += `,\n action == ${formatAction(this.data.action)}`;
|
|
173
187
|
}
|
|
174
188
|
|
|
175
189
|
// Resource
|
package/src/index.ts
CHANGED
|
@@ -14,3 +14,20 @@ export * from './engine.js';
|
|
|
14
14
|
export * from './builder.js';
|
|
15
15
|
export * from './parser.js';
|
|
16
16
|
export * from './errors.js';
|
|
17
|
+
|
|
18
|
+
// Service-specific schemas and context (inlined)
|
|
19
|
+
export {
|
|
20
|
+
OVERWATCH_SCHEMA,
|
|
21
|
+
PALISADE_SCHEMA,
|
|
22
|
+
OVERWATCH_CONTEXT,
|
|
23
|
+
PALISADE_CONTEXT,
|
|
24
|
+
} from './service-schemas.gen.js';
|
|
25
|
+
export type {
|
|
26
|
+
ContextAttribute,
|
|
27
|
+
ActionContext,
|
|
28
|
+
ServiceContext,
|
|
29
|
+
} from './service-schemas.gen.js';
|
|
30
|
+
|
|
31
|
+
// Service-specific context key enums
|
|
32
|
+
export { OverwatchContextKey } from './overwatch-context.gen.js';
|
|
33
|
+
export { PalisadeContextKey } from './palisade-context.gen.js';
|
|
@@ -12,7 +12,6 @@ export const OverwatchContextKey = {
|
|
|
12
12
|
Content: 'content',
|
|
13
13
|
Cwd: 'cwd',
|
|
14
14
|
Event: 'event',
|
|
15
|
-
FilePath: 'file_path',
|
|
16
15
|
HighestSeverity: 'highest_severity',
|
|
17
16
|
MaxThreatSeverity: 'max_threat_severity',
|
|
18
17
|
McpServer: 'mcp_server',
|
|
@@ -20,7 +19,6 @@ export const OverwatchContextKey = {
|
|
|
20
19
|
Path: 'path',
|
|
21
20
|
PromptText: 'prompt_text',
|
|
22
21
|
ResponseContent: 'response_content',
|
|
23
|
-
ServerName: 'server_name',
|
|
24
22
|
Source: 'source',
|
|
25
23
|
ThreatCategories: 'threat_categories',
|
|
26
24
|
ThreatCount: 'threat_count',
|
package/src/schemas.test.ts
CHANGED
|
@@ -205,9 +205,7 @@ describe('Service-Specific Schemas', () => {
|
|
|
205
205
|
tool_name: 'shell',
|
|
206
206
|
mcp_server: 'filesystem',
|
|
207
207
|
mcp_tool: 'shell',
|
|
208
|
-
server_name: 'filesystem',
|
|
209
208
|
path: '/workspace',
|
|
210
|
-
file_path: '/workspace',
|
|
211
209
|
cwd: '/workspace',
|
|
212
210
|
workspace_root: '/workspace',
|
|
213
211
|
threat_count: 3,
|
|
@@ -388,9 +386,7 @@ describe('Service-Specific Schemas', () => {
|
|
|
388
386
|
tool_name: 'shell',
|
|
389
387
|
mcp_server: 'filesystem',
|
|
390
388
|
mcp_tool: 'shell',
|
|
391
|
-
server_name: 'filesystem',
|
|
392
389
|
path: '/etc/passwd',
|
|
393
|
-
file_path: '/etc/passwd',
|
|
394
390
|
cwd: '/workspace',
|
|
395
391
|
workspace_root: '/workspace',
|
|
396
392
|
threat_count: 5,
|