@highflame/policy 2.1.3 → 2.1.5
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 +41 -0
- package/_schemas/guardrails/context.json +466 -76
- package/_schemas/guardrails/schema.cedarschema +39 -3
- package/_schemas/guardrails/templates/defaults/injection.cedar +6 -6
- package/_schemas/guardrails/templates/profiles/chat_assistant/security.cedar +2 -2
- package/_schemas/guardrails/templates/profiles/data_pipeline/security.cedar +1 -1
- package/_schemas/overwatch/context.json +443 -5
- package/_schemas/overwatch/schema.cedarschema +42 -4
- package/_schemas/palisade/context.json +1 -1
- package/_schemas/sentry/context.json +1165 -0
- package/_schemas/sentry/schema.cedarschema +388 -0
- package/_schemas/sentry/templates/defaults/baseline.cedar +24 -0
- package/_schemas/sentry/templates/defaults/content_safety.cedar +232 -0
- package/_schemas/sentry/templates/defaults/file_safety.cedar +174 -0
- package/_schemas/sentry/templates/defaults/organization.cedar +207 -0
- package/_schemas/sentry/templates/defaults/pii.cedar +229 -0
- package/_schemas/sentry/templates/defaults/semantic.cedar +167 -0
- package/_schemas/sentry/templates/templates.json +93 -0
- package/dist/builder.d.ts +32 -0
- package/dist/builder.js +6 -6
- package/dist/condition-groups.d.ts +69 -0
- package/dist/condition-groups.js +305 -0
- package/dist/guardrails-context.gen.d.ts +19 -2
- package/dist/guardrails-context.gen.js +19 -2
- package/dist/guardrails-defaults.gen.js +9 -9
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/overwatch-context.gen.d.ts +17 -0
- package/dist/overwatch-context.gen.js +17 -0
- package/dist/sentry-context.gen.d.ts +76 -0
- package/dist/sentry-context.gen.js +77 -0
- package/dist/sentry-defaults.gen.d.ts +61 -0
- package/dist/sentry-defaults.gen.js +1235 -0
- package/dist/sentry-entities.gen.d.ts +11 -0
- package/dist/sentry-entities.gen.js +33 -0
- package/dist/service-schemas.gen.d.ts +12 -2
- package/dist/service-schemas.gen.js +861 -25
- package/dist/types.d.ts +6 -1
- package/dist/types.js +6 -1
- package/package.json +1 -1
- package/_schemas/guardrails/templates/profiles/chat_assistant.cedar +0 -85
- package/_schemas/guardrails/templates/profiles/code_agent.cedar +0 -125
- package/_schemas/guardrails/templates/profiles/data_pipeline.cedar +0 -111
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Condition Groups — flat UI-friendly representation of ConditionExpression trees.
|
|
3
|
+
*
|
|
4
|
+
* Provides bidirectional conversion between recursive ConditionExpression ASTs
|
|
5
|
+
* and flat ConditionGroup arrays suitable for visual condition builder UIs.
|
|
6
|
+
*
|
|
7
|
+
* Also provides:
|
|
8
|
+
* - expressionToCedar(): render any AST node to valid Cedar condition text
|
|
9
|
+
* - extractContextFields(): collect all context field names from an AST
|
|
10
|
+
*/
|
|
11
|
+
import { conditionToCedar, sanitizeIdentifier, isValidRawCondition, } from './builder.js';
|
|
12
|
+
/** Sentinel field name used for raw (unparseable) conditions. */
|
|
13
|
+
export const RAW_CONDITION_FIELD = '__raw';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// ID generation
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
let _groupCounter = 0;
|
|
18
|
+
/** Generate a unique group ID. Uses a simple counter for deterministic output. */
|
|
19
|
+
function nextGroupId() {
|
|
20
|
+
return `group-${++_groupCounter}`;
|
|
21
|
+
}
|
|
22
|
+
/** Reset the group counter (for testing). */
|
|
23
|
+
export function resetGroupCounter() {
|
|
24
|
+
_groupCounter = 0;
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// expressionToGroups
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Convert a ConditionExpression AST into a flat array of ConditionGroups.
|
|
31
|
+
*
|
|
32
|
+
* The top-level AND is split into separate groups. Each OR subtree becomes
|
|
33
|
+
* a single group with `logic: 'or'`. NOT wrappers set `negated: true`.
|
|
34
|
+
* Raw nodes produce a sentinel condition with `field: "__raw"`.
|
|
35
|
+
*/
|
|
36
|
+
export function expressionToGroups(expr) {
|
|
37
|
+
// Top-level AND → split children into groups
|
|
38
|
+
if (expr.kind === 'and') {
|
|
39
|
+
const groups = [];
|
|
40
|
+
for (const child of expr.children) {
|
|
41
|
+
groups.push(...nodeToGroups(child));
|
|
42
|
+
}
|
|
43
|
+
return groups;
|
|
44
|
+
}
|
|
45
|
+
// Anything else → delegate
|
|
46
|
+
return nodeToGroups(expr);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Convert a single AST node (not a top-level AND) into one or more groups.
|
|
50
|
+
*/
|
|
51
|
+
function nodeToGroups(expr) {
|
|
52
|
+
switch (expr.kind) {
|
|
53
|
+
case 'and': {
|
|
54
|
+
// Nested AND within a top-level AND child → single AND group
|
|
55
|
+
const conditions = collectLeafConditions(expr.children);
|
|
56
|
+
return [{ id: nextGroupId(), logic: 'and', conditions, negated: false }];
|
|
57
|
+
}
|
|
58
|
+
case 'or': {
|
|
59
|
+
const conditions = collectLeafConditions(expr.children);
|
|
60
|
+
return [{ id: nextGroupId(), logic: 'or', conditions, negated: false }];
|
|
61
|
+
}
|
|
62
|
+
case 'not': {
|
|
63
|
+
return notToGroups(expr.child);
|
|
64
|
+
}
|
|
65
|
+
case 'raw': {
|
|
66
|
+
return [{
|
|
67
|
+
id: nextGroupId(),
|
|
68
|
+
logic: 'and',
|
|
69
|
+
conditions: [{ field: RAW_CONDITION_FIELD, operator: 'eq', value: expr.text }],
|
|
70
|
+
negated: false,
|
|
71
|
+
}];
|
|
72
|
+
}
|
|
73
|
+
default: {
|
|
74
|
+
// Leaf node → single AND group with one condition
|
|
75
|
+
const cond = leafToCondition(expr);
|
|
76
|
+
return [{ id: nextGroupId(), logic: 'and', conditions: [cond], negated: false }];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Convert a NOT node's inner expression into negated group(s). */
|
|
81
|
+
function notToGroups(inner) {
|
|
82
|
+
switch (inner.kind) {
|
|
83
|
+
case 'or': {
|
|
84
|
+
const conditions = collectLeafConditions(inner.children);
|
|
85
|
+
return [{ id: nextGroupId(), logic: 'or', conditions, negated: true }];
|
|
86
|
+
}
|
|
87
|
+
case 'and': {
|
|
88
|
+
const conditions = collectLeafConditions(inner.children);
|
|
89
|
+
return [{ id: nextGroupId(), logic: 'and', conditions, negated: true }];
|
|
90
|
+
}
|
|
91
|
+
case 'not': {
|
|
92
|
+
// Double negation: NOT(NOT(x)) → just x
|
|
93
|
+
return nodeToGroups(inner.child);
|
|
94
|
+
}
|
|
95
|
+
case 'raw': {
|
|
96
|
+
return [{
|
|
97
|
+
id: nextGroupId(),
|
|
98
|
+
logic: 'and',
|
|
99
|
+
conditions: [{ field: RAW_CONDITION_FIELD, operator: 'eq', value: inner.text }],
|
|
100
|
+
negated: true,
|
|
101
|
+
}];
|
|
102
|
+
}
|
|
103
|
+
default: {
|
|
104
|
+
// NOT wrapping a leaf
|
|
105
|
+
const cond = leafToCondition(inner);
|
|
106
|
+
return [{ id: nextGroupId(), logic: 'and', conditions: [cond], negated: true }];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Collect leaf conditions from an array of children. Non-leaf children become raw fallbacks. */
|
|
111
|
+
function collectLeafConditions(children) {
|
|
112
|
+
return children.map(child => {
|
|
113
|
+
if (isLeaf(child)) {
|
|
114
|
+
return leafToCondition(child);
|
|
115
|
+
}
|
|
116
|
+
// Non-leaf in OR/AND children → raw fallback with Cedar text
|
|
117
|
+
return { field: RAW_CONDITION_FIELD, operator: 'eq', value: expressionToCedar(child) };
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** Check if an expression is a leaf (comparison, contains, like, has). */
|
|
121
|
+
function isLeaf(expr) {
|
|
122
|
+
return expr.kind === 'comparison' || expr.kind === 'contains'
|
|
123
|
+
|| expr.kind === 'like' || expr.kind === 'has';
|
|
124
|
+
}
|
|
125
|
+
/** Convert a leaf expression to a PolicyCondition. */
|
|
126
|
+
function leafToCondition(expr) {
|
|
127
|
+
switch (expr.kind) {
|
|
128
|
+
case 'comparison':
|
|
129
|
+
return { field: expr.field, operator: expr.operator, value: expr.value };
|
|
130
|
+
case 'contains':
|
|
131
|
+
return { field: expr.field, operator: 'contains', value: expr.value };
|
|
132
|
+
case 'like':
|
|
133
|
+
return { field: expr.field, operator: 'like', value: expr.pattern };
|
|
134
|
+
case 'has':
|
|
135
|
+
return { field: expr.field, operator: 'eq', value: true };
|
|
136
|
+
default:
|
|
137
|
+
// Fallback — shouldn't reach here for true leaves
|
|
138
|
+
return { field: RAW_CONDITION_FIELD, operator: 'eq', value: expressionToCedar(expr) };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// groupsToExpression
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
/**
|
|
145
|
+
* Convert a flat array of ConditionGroups back into a ConditionExpression AST.
|
|
146
|
+
*
|
|
147
|
+
* Each group becomes an AND/OR node (or single leaf if only one condition).
|
|
148
|
+
* If `negated`, the group is wrapped in NOT. Multiple groups are combined
|
|
149
|
+
* with a top-level AND.
|
|
150
|
+
*/
|
|
151
|
+
export function groupsToExpression(groups) {
|
|
152
|
+
if (groups.length === 0) {
|
|
153
|
+
return { kind: 'and', children: [] };
|
|
154
|
+
}
|
|
155
|
+
const expressions = groups.map(groupToExpression);
|
|
156
|
+
if (expressions.length === 1) {
|
|
157
|
+
return expressions[0];
|
|
158
|
+
}
|
|
159
|
+
return { kind: 'and', children: expressions };
|
|
160
|
+
}
|
|
161
|
+
/** Convert a single ConditionGroup to a ConditionExpression. */
|
|
162
|
+
function groupToExpression(group) {
|
|
163
|
+
const children = group.conditions.map(conditionToExpression);
|
|
164
|
+
let inner;
|
|
165
|
+
if (children.length === 1) {
|
|
166
|
+
inner = children[0];
|
|
167
|
+
}
|
|
168
|
+
else if (group.logic === 'or') {
|
|
169
|
+
inner = { kind: 'or', children };
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
inner = { kind: 'and', children };
|
|
173
|
+
}
|
|
174
|
+
if (group.negated) {
|
|
175
|
+
return { kind: 'not', child: inner };
|
|
176
|
+
}
|
|
177
|
+
return inner;
|
|
178
|
+
}
|
|
179
|
+
/** Convert a PolicyCondition back to a leaf ConditionExpression. */
|
|
180
|
+
function conditionToExpression(cond) {
|
|
181
|
+
// Raw sentinel → raw expression
|
|
182
|
+
if (cond.field === RAW_CONDITION_FIELD) {
|
|
183
|
+
return { kind: 'raw', text: String(cond.value) };
|
|
184
|
+
}
|
|
185
|
+
switch (cond.operator) {
|
|
186
|
+
case 'contains': {
|
|
187
|
+
// contains() checks a single value against a set — value is never string[]
|
|
188
|
+
const containsVal = Array.isArray(cond.value) ? cond.value[0] ?? '' : cond.value;
|
|
189
|
+
return { kind: 'contains', field: cond.field, value: containsVal };
|
|
190
|
+
}
|
|
191
|
+
case 'like':
|
|
192
|
+
return { kind: 'like', field: cond.field, pattern: String(cond.value) };
|
|
193
|
+
default:
|
|
194
|
+
return {
|
|
195
|
+
kind: 'comparison',
|
|
196
|
+
field: cond.field,
|
|
197
|
+
operator: cond.operator,
|
|
198
|
+
value: cond.value,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// expressionToCedar
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
/**
|
|
206
|
+
* Render any ConditionExpression node to valid Cedar condition text.
|
|
207
|
+
*
|
|
208
|
+
* This handles the full AST including AND, OR, NOT, and raw nodes —
|
|
209
|
+
* unlike `conditionToCedar()` which only handles leaf PolicyConditions.
|
|
210
|
+
*
|
|
211
|
+
* @param expr - The expression tree to render
|
|
212
|
+
* @param optionalFields - Optional set of field names that need `context has` guards
|
|
213
|
+
* @returns Cedar condition text (without the `when { ... }` wrapper)
|
|
214
|
+
*/
|
|
215
|
+
export function expressionToCedar(expr, optionalFields) {
|
|
216
|
+
switch (expr.kind) {
|
|
217
|
+
case 'comparison':
|
|
218
|
+
case 'contains':
|
|
219
|
+
case 'like':
|
|
220
|
+
return conditionToCedar(leafToCondition(expr), optionalFields);
|
|
221
|
+
case 'has': {
|
|
222
|
+
const field = sanitizeIdentifier(expr.field, 'field');
|
|
223
|
+
return `context has ${field}`;
|
|
224
|
+
}
|
|
225
|
+
case 'and': {
|
|
226
|
+
if (expr.children.length === 0)
|
|
227
|
+
return 'true';
|
|
228
|
+
if (expr.children.length === 1)
|
|
229
|
+
return expressionToCedar(expr.children[0], optionalFields);
|
|
230
|
+
return expr.children
|
|
231
|
+
.map(c => {
|
|
232
|
+
// Parenthesize OR children to preserve precedence
|
|
233
|
+
if (c.kind === 'or')
|
|
234
|
+
return `(${expressionToCedar(c, optionalFields)})`;
|
|
235
|
+
return expressionToCedar(c, optionalFields);
|
|
236
|
+
})
|
|
237
|
+
.join(' && ');
|
|
238
|
+
}
|
|
239
|
+
case 'or': {
|
|
240
|
+
if (expr.children.length === 0)
|
|
241
|
+
return 'false';
|
|
242
|
+
if (expr.children.length === 1)
|
|
243
|
+
return expressionToCedar(expr.children[0], optionalFields);
|
|
244
|
+
return expr.children
|
|
245
|
+
.map(c => {
|
|
246
|
+
// Parenthesize AND children to preserve precedence
|
|
247
|
+
if (c.kind === 'and')
|
|
248
|
+
return `(${expressionToCedar(c, optionalFields)})`;
|
|
249
|
+
return expressionToCedar(c, optionalFields);
|
|
250
|
+
})
|
|
251
|
+
.join(' || ');
|
|
252
|
+
}
|
|
253
|
+
case 'not': {
|
|
254
|
+
const inner = expressionToCedar(expr.child, optionalFields);
|
|
255
|
+
// If inner is a simple leaf, no parens needed after !
|
|
256
|
+
if (isLeaf(expr.child))
|
|
257
|
+
return `!${inner}`;
|
|
258
|
+
return `!(${inner})`;
|
|
259
|
+
}
|
|
260
|
+
case 'raw': {
|
|
261
|
+
if (isValidRawCondition(expr.text)) {
|
|
262
|
+
return expr.text;
|
|
263
|
+
}
|
|
264
|
+
return '/* invalid raw condition */';
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
// extractContextFields
|
|
270
|
+
// ---------------------------------------------------------------------------
|
|
271
|
+
/**
|
|
272
|
+
* Extract all unique context field names referenced in a ConditionExpression tree.
|
|
273
|
+
*
|
|
274
|
+
* Used by Shield to determine which detectors to run — only detectors that
|
|
275
|
+
* produce fields referenced in active policies need to execute.
|
|
276
|
+
*
|
|
277
|
+
* @returns Sorted array of unique field names
|
|
278
|
+
*/
|
|
279
|
+
export function extractContextFields(expr) {
|
|
280
|
+
const fields = new Set();
|
|
281
|
+
collectFields(expr, fields);
|
|
282
|
+
return Array.from(fields).sort();
|
|
283
|
+
}
|
|
284
|
+
function collectFields(expr, fields) {
|
|
285
|
+
switch (expr.kind) {
|
|
286
|
+
case 'comparison':
|
|
287
|
+
case 'contains':
|
|
288
|
+
case 'like':
|
|
289
|
+
case 'has':
|
|
290
|
+
fields.add(expr.field);
|
|
291
|
+
break;
|
|
292
|
+
case 'and':
|
|
293
|
+
case 'or':
|
|
294
|
+
for (const child of expr.children) {
|
|
295
|
+
collectFields(child, fields);
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
case 'not':
|
|
299
|
+
collectFields(expr.child, fields);
|
|
300
|
+
break;
|
|
301
|
+
case 'raw':
|
|
302
|
+
// Can't reliably extract fields from raw text
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -36,12 +36,16 @@ export declare const GuardrailsContextKey: {
|
|
|
36
36
|
readonly FactualityScore: "factuality_score";
|
|
37
37
|
readonly HallucinationScore: "hallucination_score";
|
|
38
38
|
readonly HateSpeechScore: "hate_speech_score";
|
|
39
|
-
readonly
|
|
39
|
+
readonly InjectionConfidence: "injection_confidence";
|
|
40
|
+
readonly InjectionDeepContextScore: "injection_deep_context_score";
|
|
41
|
+
readonly InjectionPulseScore: "injection_pulse_score";
|
|
40
42
|
readonly InjectionType: "injection_type";
|
|
41
43
|
readonly InvisibleCharsScore: "invisible_chars_score";
|
|
42
44
|
readonly IsEnglish: "is_english";
|
|
43
45
|
readonly IsLatinScript: "is_latin_script";
|
|
44
|
-
readonly
|
|
46
|
+
readonly JailbreakConfidence: "jailbreak_confidence";
|
|
47
|
+
readonly JailbreakDeepContextScore: "jailbreak_deep_context_score";
|
|
48
|
+
readonly JailbreakPulseScore: "jailbreak_pulse_score";
|
|
45
49
|
readonly KeywordCategories: "keyword_categories";
|
|
46
50
|
readonly KeywordCount: "keyword_count";
|
|
47
51
|
readonly KeywordMatched: "keyword_matched";
|
|
@@ -74,6 +78,19 @@ export declare const GuardrailsContextKey: {
|
|
|
74
78
|
readonly SecretTypes: "secret_types";
|
|
75
79
|
readonly SentimentScore: "sentiment_score";
|
|
76
80
|
readonly SequenceRisk: "sequence_risk";
|
|
81
|
+
readonly SessionCommandInjection: "session_command_injection";
|
|
82
|
+
readonly SessionCumulativeRiskScore: "session_cumulative_risk_score";
|
|
83
|
+
readonly SessionInjectionDetected: "session_injection_detected";
|
|
84
|
+
readonly SessionMaxCommandInjectionScore: "session_max_command_injection_score";
|
|
85
|
+
readonly SessionMaxInjectionScore: "session_max_injection_score";
|
|
86
|
+
readonly SessionMaxJailbreakScore: "session_max_jailbreak_score";
|
|
87
|
+
readonly SessionMaxPiiScore: "session_max_pii_score";
|
|
88
|
+
readonly SessionMaxSecretScore: "session_max_secret_score";
|
|
89
|
+
readonly SessionPiiDetected: "session_pii_detected";
|
|
90
|
+
readonly SessionPiiTypes: "session_pii_types";
|
|
91
|
+
readonly SessionSecretTypes: "session_secret_types";
|
|
92
|
+
readonly SessionSecretsDetected: "session_secrets_detected";
|
|
93
|
+
readonly SessionThreatTurns: "session_threat_turns";
|
|
77
94
|
readonly SexualScore: "sexual_score";
|
|
78
95
|
readonly SqlInjectionDetected: "sql_injection_detected";
|
|
79
96
|
readonly SqlInjectionScore: "sql_injection_score";
|
|
@@ -38,12 +38,16 @@ export const GuardrailsContextKey = {
|
|
|
38
38
|
FactualityScore: 'factuality_score',
|
|
39
39
|
HallucinationScore: 'hallucination_score',
|
|
40
40
|
HateSpeechScore: 'hate_speech_score',
|
|
41
|
-
|
|
41
|
+
InjectionConfidence: 'injection_confidence',
|
|
42
|
+
InjectionDeepContextScore: 'injection_deep_context_score',
|
|
43
|
+
InjectionPulseScore: 'injection_pulse_score',
|
|
42
44
|
InjectionType: 'injection_type',
|
|
43
45
|
InvisibleCharsScore: 'invisible_chars_score',
|
|
44
46
|
IsEnglish: 'is_english',
|
|
45
47
|
IsLatinScript: 'is_latin_script',
|
|
46
|
-
|
|
48
|
+
JailbreakConfidence: 'jailbreak_confidence',
|
|
49
|
+
JailbreakDeepContextScore: 'jailbreak_deep_context_score',
|
|
50
|
+
JailbreakPulseScore: 'jailbreak_pulse_score',
|
|
47
51
|
KeywordCategories: 'keyword_categories',
|
|
48
52
|
KeywordCount: 'keyword_count',
|
|
49
53
|
KeywordMatched: 'keyword_matched',
|
|
@@ -76,6 +80,19 @@ export const GuardrailsContextKey = {
|
|
|
76
80
|
SecretTypes: 'secret_types',
|
|
77
81
|
SentimentScore: 'sentiment_score',
|
|
78
82
|
SequenceRisk: 'sequence_risk',
|
|
83
|
+
SessionCommandInjection: 'session_command_injection',
|
|
84
|
+
SessionCumulativeRiskScore: 'session_cumulative_risk_score',
|
|
85
|
+
SessionInjectionDetected: 'session_injection_detected',
|
|
86
|
+
SessionMaxCommandInjectionScore: 'session_max_command_injection_score',
|
|
87
|
+
SessionMaxInjectionScore: 'session_max_injection_score',
|
|
88
|
+
SessionMaxJailbreakScore: 'session_max_jailbreak_score',
|
|
89
|
+
SessionMaxPiiScore: 'session_max_pii_score',
|
|
90
|
+
SessionMaxSecretScore: 'session_max_secret_score',
|
|
91
|
+
SessionPiiDetected: 'session_pii_detected',
|
|
92
|
+
SessionPiiTypes: 'session_pii_types',
|
|
93
|
+
SessionSecretTypes: 'session_secret_types',
|
|
94
|
+
SessionSecretsDetected: 'session_secrets_detected',
|
|
95
|
+
SessionThreatTurns: 'session_threat_turns',
|
|
79
96
|
SexualScore: 'sexual_score',
|
|
80
97
|
SqlInjectionDetected: 'sql_injection_detected',
|
|
81
98
|
SqlInjectionScore: 'sql_injection_score',
|
|
@@ -80,8 +80,8 @@ const GUARDRAILS_INJECTION_DEFAULT_CEDAR = `// =================================
|
|
|
80
80
|
// Uses ML-based confidence scores from normalized context.
|
|
81
81
|
//
|
|
82
82
|
// Context keys used (normalized by projection layer):
|
|
83
|
-
// -
|
|
84
|
-
// -
|
|
83
|
+
// - injection_confidence: Long (0-100) - Overall injection confidence
|
|
84
|
+
// - jailbreak_confidence: Long (0-100) - Jailbreak attempt confidence
|
|
85
85
|
// - injection_type: String - Type of injection detected
|
|
86
86
|
// - contains_invisible_chars: Bool - Invisible Unicode characters detected
|
|
87
87
|
// - invisible_chars_score: Long (0-100) - Invisible character density
|
|
@@ -100,7 +100,7 @@ forbid (
|
|
|
100
100
|
action,
|
|
101
101
|
resource
|
|
102
102
|
) when {
|
|
103
|
-
context has
|
|
103
|
+
context has injection_confidence && context.injection_confidence > 85
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
@id("jailbreak-block-high-confidence")
|
|
@@ -113,7 +113,7 @@ forbid (
|
|
|
113
113
|
action,
|
|
114
114
|
resource
|
|
115
115
|
) when {
|
|
116
|
-
context has
|
|
116
|
+
context has jailbreak_confidence && context.jailbreak_confidence > 80
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
@id("injection-combined-threshold")
|
|
@@ -126,8 +126,8 @@ forbid (
|
|
|
126
126
|
action,
|
|
127
127
|
resource
|
|
128
128
|
) when {
|
|
129
|
-
context has
|
|
130
|
-
context.
|
|
129
|
+
context has injection_confidence && context has jailbreak_confidence &&
|
|
130
|
+
context.injection_confidence > 60 && context.jailbreak_confidence > 60
|
|
131
131
|
};
|
|
132
132
|
|
|
133
133
|
@id("injection-invisible-chars")
|
|
@@ -634,7 +634,7 @@ forbid (
|
|
|
634
634
|
action,
|
|
635
635
|
resource
|
|
636
636
|
) when {
|
|
637
|
-
context has
|
|
637
|
+
context has injection_confidence && context.injection_confidence > 70
|
|
638
638
|
};
|
|
639
639
|
|
|
640
640
|
@id("chat-jailbreak-lower-threshold")
|
|
@@ -647,7 +647,7 @@ forbid (
|
|
|
647
647
|
action,
|
|
648
648
|
resource
|
|
649
649
|
) when {
|
|
650
|
-
context has
|
|
650
|
+
context has jailbreak_confidence && context.jailbreak_confidence > 65
|
|
651
651
|
};
|
|
652
652
|
`;
|
|
653
653
|
const GUARDRAILS_CHAT_ASSISTANT_PRIVACY_CEDAR = `// =============================================================================
|
|
@@ -938,7 +938,7 @@ forbid (
|
|
|
938
938
|
action,
|
|
939
939
|
resource
|
|
940
940
|
) when {
|
|
941
|
-
context has
|
|
941
|
+
context has injection_confidence && context.injection_confidence > 65
|
|
942
942
|
};
|
|
943
943
|
`;
|
|
944
944
|
const GUARDRAILS_DATA_PIPELINE_AGENTIC_SECURITY_CEDAR = `// =============================================================================
|
package/dist/index.d.ts
CHANGED
|
@@ -8,16 +8,21 @@ export * from './parser.js';
|
|
|
8
8
|
export * from './errors.js';
|
|
9
9
|
export * from './annotations.js';
|
|
10
10
|
export * from './explain.js';
|
|
11
|
-
export
|
|
11
|
+
export * from './condition-groups.js';
|
|
12
|
+
export { GUARDRAILS_SCHEMA, GUARDRAILS_CONTEXT, OVERWATCH_SCHEMA, OVERWATCH_CONTEXT, PALISADE_SCHEMA, PALISADE_CONTEXT, SENTRY_SCHEMA, SENTRY_CONTEXT, } from './service-schemas.gen.js';
|
|
12
13
|
export type { ContextAttribute, ActionContext, ServiceContext, } from './service-schemas.gen.js';
|
|
13
14
|
export { GuardrailsContextKey } from './guardrails-context.gen.js';
|
|
14
15
|
export { OverwatchContextKey } from './overwatch-context.gen.js';
|
|
15
16
|
export { PalisadeContextKey } from './palisade-context.gen.js';
|
|
17
|
+
export { SentryContextKey } from './sentry-context.gen.js';
|
|
16
18
|
export { GUARDRAILS_ENTITIES, GUARDRAILS_ACTION_ENTITIES, } from './guardrails-entities.gen.js';
|
|
17
19
|
export { OVERWATCH_ENTITIES, OVERWATCH_ACTION_ENTITIES, } from './overwatch-entities.gen.js';
|
|
18
20
|
export { PALISADE_ENTITIES, PALISADE_ACTION_ENTITIES, } from './palisade-entities.gen.js';
|
|
21
|
+
export { SENTRY_ENTITIES, SENTRY_ACTION_ENTITIES, } from './sentry-entities.gen.js';
|
|
19
22
|
export type { ServiceEntityMetadata, ActionEntityMetadata } from './entity-metadata-types.gen.js';
|
|
20
23
|
export { GUARDRAILS_DEFAULTS, GUARDRAILS_TEMPLATES, GUARDRAILS_CATEGORIES, GUARDRAILS_TEMPLATES_JSON, getGuardrailsDefaultsByCategory, getGuardrailsTemplatesByCategory, getGuardrailsTemplateById, } from './guardrails-defaults.gen.js';
|
|
21
24
|
export type { GuardrailsCategory, GuardrailsCategoryInfo, GuardrailsDefaultPolicy, GuardrailsTemplate, } from './guardrails-defaults.gen.js';
|
|
22
25
|
export { OVERWATCH_DEFAULTS, OVERWATCH_TEMPLATES, OVERWATCH_CATEGORIES, OVERWATCH_TEMPLATES_JSON, getOverwatchDefaultsByCategory, getOverwatchTemplatesByCategory, getOverwatchTemplateById, } from './overwatch-defaults.gen.js';
|
|
23
26
|
export type { OverwatchCategory, OverwatchCategoryInfo, OverwatchDefaultPolicy, OverwatchTemplate, } from './overwatch-defaults.gen.js';
|
|
27
|
+
export { SENTRY_DEFAULTS, SENTRY_TEMPLATES, SENTRY_CATEGORIES, SENTRY_TEMPLATES_JSON, getSentryDefaultsByCategory, getSentryTemplatesByCategory, getSentryTemplateById, } from './sentry-defaults.gen.js';
|
|
28
|
+
export type { SentryCategory, SentryCategoryInfo, SentryDefaultPolicy, SentryTemplate, } from './sentry-defaults.gen.js';
|
package/dist/index.js
CHANGED
|
@@ -15,16 +15,21 @@ export * from './errors.js';
|
|
|
15
15
|
export * from './annotations.js';
|
|
16
16
|
// Decision explanation
|
|
17
17
|
export * from './explain.js';
|
|
18
|
+
// Condition groups (AST ↔ flat UI groups)
|
|
19
|
+
export * from './condition-groups.js';
|
|
18
20
|
// Service-specific schemas and context (inlined)
|
|
19
|
-
export { GUARDRAILS_SCHEMA, GUARDRAILS_CONTEXT, OVERWATCH_SCHEMA, OVERWATCH_CONTEXT, PALISADE_SCHEMA, PALISADE_CONTEXT, } from './service-schemas.gen.js';
|
|
21
|
+
export { GUARDRAILS_SCHEMA, GUARDRAILS_CONTEXT, OVERWATCH_SCHEMA, OVERWATCH_CONTEXT, PALISADE_SCHEMA, PALISADE_CONTEXT, SENTRY_SCHEMA, SENTRY_CONTEXT, } from './service-schemas.gen.js';
|
|
20
22
|
// Service-specific context key enums
|
|
21
23
|
export { GuardrailsContextKey } from './guardrails-context.gen.js';
|
|
22
24
|
export { OverwatchContextKey } from './overwatch-context.gen.js';
|
|
23
25
|
export { PalisadeContextKey } from './palisade-context.gen.js';
|
|
26
|
+
export { SentryContextKey } from './sentry-context.gen.js';
|
|
24
27
|
// Service-specific entity metadata (for UI - principals, resources, actions)
|
|
25
28
|
export { GUARDRAILS_ENTITIES, GUARDRAILS_ACTION_ENTITIES, } from './guardrails-entities.gen.js';
|
|
26
29
|
export { OVERWATCH_ENTITIES, OVERWATCH_ACTION_ENTITIES, } from './overwatch-entities.gen.js';
|
|
27
30
|
export { PALISADE_ENTITIES, PALISADE_ACTION_ENTITIES, } from './palisade-entities.gen.js';
|
|
31
|
+
export { SENTRY_ENTITIES, SENTRY_ACTION_ENTITIES, } from './sentry-entities.gen.js';
|
|
28
32
|
// Service-specific default policies, templates, and categories
|
|
29
33
|
export { GUARDRAILS_DEFAULTS, GUARDRAILS_TEMPLATES, GUARDRAILS_CATEGORIES, GUARDRAILS_TEMPLATES_JSON, getGuardrailsDefaultsByCategory, getGuardrailsTemplatesByCategory, getGuardrailsTemplateById, } from './guardrails-defaults.gen.js';
|
|
30
34
|
export { OVERWATCH_DEFAULTS, OVERWATCH_TEMPLATES, OVERWATCH_CATEGORIES, OVERWATCH_TEMPLATES_JSON, getOverwatchDefaultsByCategory, getOverwatchTemplatesByCategory, getOverwatchTemplateById, } from './overwatch-defaults.gen.js';
|
|
35
|
+
export { SENTRY_DEFAULTS, SENTRY_TEMPLATES, SENTRY_CATEGORIES, SENTRY_TEMPLATES_JSON, getSentryDefaultsByCategory, getSentryTemplatesByCategory, getSentryTemplateById, } from './sentry-defaults.gen.js';
|
|
@@ -16,8 +16,12 @@ export declare const OverwatchContextKey: {
|
|
|
16
16
|
readonly HighestSeverity: "highest_severity";
|
|
17
17
|
readonly IndirectInjectionScore: "indirect_injection_score";
|
|
18
18
|
readonly InjectionConfidence: "injection_confidence";
|
|
19
|
+
readonly InjectionDeepContextScore: "injection_deep_context_score";
|
|
20
|
+
readonly InjectionPulseScore: "injection_pulse_score";
|
|
19
21
|
readonly InvisibleCharsScore: "invisible_chars_score";
|
|
20
22
|
readonly JailbreakConfidence: "jailbreak_confidence";
|
|
23
|
+
readonly JailbreakDeepContextScore: "jailbreak_deep_context_score";
|
|
24
|
+
readonly JailbreakPulseScore: "jailbreak_pulse_score";
|
|
21
25
|
readonly LoopCount: "loop_count";
|
|
22
26
|
readonly LoopDetected: "loop_detected";
|
|
23
27
|
readonly LoopTool: "loop_tool";
|
|
@@ -41,6 +45,19 @@ export declare const OverwatchContextKey: {
|
|
|
41
45
|
readonly SecretCount: "secret_count";
|
|
42
46
|
readonly SecretTypes: "secret_types";
|
|
43
47
|
readonly SequenceRisk: "sequence_risk";
|
|
48
|
+
readonly SessionCommandInjection: "session_command_injection";
|
|
49
|
+
readonly SessionCumulativeRiskScore: "session_cumulative_risk_score";
|
|
50
|
+
readonly SessionInjectionDetected: "session_injection_detected";
|
|
51
|
+
readonly SessionMaxCommandInjectionScore: "session_max_command_injection_score";
|
|
52
|
+
readonly SessionMaxInjectionScore: "session_max_injection_score";
|
|
53
|
+
readonly SessionMaxJailbreakScore: "session_max_jailbreak_score";
|
|
54
|
+
readonly SessionMaxPiiScore: "session_max_pii_score";
|
|
55
|
+
readonly SessionMaxSecretScore: "session_max_secret_score";
|
|
56
|
+
readonly SessionPiiDetected: "session_pii_detected";
|
|
57
|
+
readonly SessionPiiTypes: "session_pii_types";
|
|
58
|
+
readonly SessionSecretTypes: "session_secret_types";
|
|
59
|
+
readonly SessionSecretsDetected: "session_secrets_detected";
|
|
60
|
+
readonly SessionThreatTurns: "session_threat_turns";
|
|
44
61
|
readonly SexualScore: "sexual_score";
|
|
45
62
|
readonly Source: "source";
|
|
46
63
|
readonly SuspiciousPattern: "suspicious_pattern";
|
|
@@ -18,8 +18,12 @@ export const OverwatchContextKey = {
|
|
|
18
18
|
HighestSeverity: 'highest_severity',
|
|
19
19
|
IndirectInjectionScore: 'indirect_injection_score',
|
|
20
20
|
InjectionConfidence: 'injection_confidence',
|
|
21
|
+
InjectionDeepContextScore: 'injection_deep_context_score',
|
|
22
|
+
InjectionPulseScore: 'injection_pulse_score',
|
|
21
23
|
InvisibleCharsScore: 'invisible_chars_score',
|
|
22
24
|
JailbreakConfidence: 'jailbreak_confidence',
|
|
25
|
+
JailbreakDeepContextScore: 'jailbreak_deep_context_score',
|
|
26
|
+
JailbreakPulseScore: 'jailbreak_pulse_score',
|
|
23
27
|
LoopCount: 'loop_count',
|
|
24
28
|
LoopDetected: 'loop_detected',
|
|
25
29
|
LoopTool: 'loop_tool',
|
|
@@ -43,6 +47,19 @@ export const OverwatchContextKey = {
|
|
|
43
47
|
SecretCount: 'secret_count',
|
|
44
48
|
SecretTypes: 'secret_types',
|
|
45
49
|
SequenceRisk: 'sequence_risk',
|
|
50
|
+
SessionCommandInjection: 'session_command_injection',
|
|
51
|
+
SessionCumulativeRiskScore: 'session_cumulative_risk_score',
|
|
52
|
+
SessionInjectionDetected: 'session_injection_detected',
|
|
53
|
+
SessionMaxCommandInjectionScore: 'session_max_command_injection_score',
|
|
54
|
+
SessionMaxInjectionScore: 'session_max_injection_score',
|
|
55
|
+
SessionMaxJailbreakScore: 'session_max_jailbreak_score',
|
|
56
|
+
SessionMaxPiiScore: 'session_max_pii_score',
|
|
57
|
+
SessionMaxSecretScore: 'session_max_secret_score',
|
|
58
|
+
SessionPiiDetected: 'session_pii_detected',
|
|
59
|
+
SessionPiiTypes: 'session_pii_types',
|
|
60
|
+
SessionSecretTypes: 'session_secret_types',
|
|
61
|
+
SessionSecretsDetected: 'session_secrets_detected',
|
|
62
|
+
SessionThreatTurns: 'session_threat_turns',
|
|
46
63
|
SexualScore: 'sexual_score',
|
|
47
64
|
Source: 'source',
|
|
48
65
|
SuspiciousPattern: 'suspicious_pattern',
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context attribute keys for Sentry Sentry browser security — monitors AI chat interactions and enforces data-protection, content-safety, and compliance policies.
|
|
3
|
+
*
|
|
4
|
+
* These constants correspond to the context attributes defined in the
|
|
5
|
+
* Sentry Cedar schema and are used at policy evaluation time.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SentryContextKey: {
|
|
8
|
+
readonly CodeLanguages: "code_languages";
|
|
9
|
+
readonly CodeRatio: "code_ratio";
|
|
10
|
+
readonly ContainsCode: "contains_code";
|
|
11
|
+
readonly ContainsInvisibleChars: "contains_invisible_chars";
|
|
12
|
+
readonly ContainsSecrets: "contains_secrets";
|
|
13
|
+
readonly Content: "content";
|
|
14
|
+
readonly ContentTopics: "content_topics";
|
|
15
|
+
readonly CrimeScore: "crime_score";
|
|
16
|
+
readonly DetectedLanguage: "detected_language";
|
|
17
|
+
readonly DetectedScript: "detected_script";
|
|
18
|
+
readonly DetectedThreats: "detected_threats";
|
|
19
|
+
readonly EncodedContentDetected: "encoded_content_detected";
|
|
20
|
+
readonly EncodedCount: "encoded_count";
|
|
21
|
+
readonly EncodedScore: "encoded_score";
|
|
22
|
+
readonly EncodedTypes: "encoded_types";
|
|
23
|
+
readonly Event: "event";
|
|
24
|
+
readonly FactualityScore: "factuality_score";
|
|
25
|
+
readonly FileExtension: "file_extension";
|
|
26
|
+
readonly FileName: "file_name";
|
|
27
|
+
readonly FileSizeBytes: "file_size_bytes";
|
|
28
|
+
readonly FileType: "file_type";
|
|
29
|
+
readonly HallucinationScore: "hallucination_score";
|
|
30
|
+
readonly HateSpeechScore: "hate_speech_score";
|
|
31
|
+
readonly HighestSeverity: "highest_severity";
|
|
32
|
+
readonly InjectionScore: "injection_score";
|
|
33
|
+
readonly InvisibleCharsScore: "invisible_chars_score";
|
|
34
|
+
readonly IsEncrypted: "is_encrypted";
|
|
35
|
+
readonly IsEnglish: "is_english";
|
|
36
|
+
readonly IsLatinScript: "is_latin_script";
|
|
37
|
+
readonly IsRightsManaged: "is_rights_managed";
|
|
38
|
+
readonly JailbreakScore: "jailbreak_score";
|
|
39
|
+
readonly KeywordCategories: "keyword_categories";
|
|
40
|
+
readonly KeywordCount: "keyword_count";
|
|
41
|
+
readonly KeywordMatched: "keyword_matched";
|
|
42
|
+
readonly LanguageConfidence: "language_confidence";
|
|
43
|
+
readonly MaxThreatSeverity: "max_threat_severity";
|
|
44
|
+
readonly MipLabelId: "mip_label_id";
|
|
45
|
+
readonly MipLabelName: "mip_label_name";
|
|
46
|
+
readonly PasteLength: "paste_length";
|
|
47
|
+
readonly PasteSourceApp: "paste_source_app";
|
|
48
|
+
readonly PasteSourceUrl: "paste_source_url";
|
|
49
|
+
readonly PhishingDetected: "phishing_detected";
|
|
50
|
+
readonly PiiConfidence: "pii_confidence";
|
|
51
|
+
readonly PiiCount: "pii_count";
|
|
52
|
+
readonly PiiDetected: "pii_detected";
|
|
53
|
+
readonly PiiTypes: "pii_types";
|
|
54
|
+
readonly ProfanityScore: "profanity_score";
|
|
55
|
+
readonly ScriptConfidence: "script_confidence";
|
|
56
|
+
readonly SecretCount: "secret_count";
|
|
57
|
+
readonly SecretTypes: "secret_types";
|
|
58
|
+
readonly SensitivityLevel: "sensitivity_level";
|
|
59
|
+
readonly SessionInjectionDetected: "session_injection_detected";
|
|
60
|
+
readonly SessionPiiDetected: "session_pii_detected";
|
|
61
|
+
readonly SessionPiiTypes: "session_pii_types";
|
|
62
|
+
readonly SessionSecretTypes: "session_secret_types";
|
|
63
|
+
readonly SessionSecretsDetected: "session_secrets_detected";
|
|
64
|
+
readonly SessionThreatTurns: "session_threat_turns";
|
|
65
|
+
readonly SexualScore: "sexual_score";
|
|
66
|
+
readonly Source: "source";
|
|
67
|
+
readonly TargetApp: "target_app";
|
|
68
|
+
readonly TargetUrl: "target_url";
|
|
69
|
+
readonly ThreatCategories: "threat_categories";
|
|
70
|
+
readonly ThreatCount: "threat_count";
|
|
71
|
+
readonly TopicConfidence: "topic_confidence";
|
|
72
|
+
readonly UserEmail: "user_email";
|
|
73
|
+
readonly ViolenceScore: "violence_score";
|
|
74
|
+
readonly WeaponsScore: "weapons_score";
|
|
75
|
+
};
|
|
76
|
+
export type SentryContextKey = (typeof SentryContextKey)[keyof typeof SentryContextKey];
|