troxy-cli 1.21.1 → 1.22.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/bin/troxy.js +92 -12
- package/package.json +7 -4
- package/src/api.js +18 -0
- package/src/data/policy-spec.json +496 -0
- package/src/data/templates.json +1429 -0
- package/src/init.js +11 -0
- package/src/mcp-server.js +81 -0
- package/src/policies.js +341 -46
- package/src/policy-fields.js +107 -0
- package/src/simulate.js +251 -0
- package/src/tests/mcp-checkpoints.test.js +79 -0
- package/src/tests/model-checkpoint.test.js +5 -1
- package/src/tests/policies-create.test.js +218 -0
- package/src/tests/policies-org.test.js +60 -0
- package/src/tests/simulate.test.js +127 -0
- package/src/tests/templates.test.js +46 -0
- package/src/tool_detect.js +179 -0
|
@@ -0,0 +1,1429 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_generated_by": "troxy-cli/scripts/export-templates.mjs, reading troxy-dashboard/index.html",
|
|
3
|
+
"_why": "Vendored copy of the dashboard's shipped policy templates. Regenerate whenever the dashboard's templates change: node scripts/export-templates.mjs ../troxy-dashboard/index.html > src/data/templates.json",
|
|
4
|
+
"templates": [
|
|
5
|
+
{
|
|
6
|
+
"label": "Block over $100",
|
|
7
|
+
"category": "Spending & transactions",
|
|
8
|
+
"domain": "payment",
|
|
9
|
+
"action": "BLOCK",
|
|
10
|
+
"conditions": [
|
|
11
|
+
{
|
|
12
|
+
"field": "amount",
|
|
13
|
+
"operator": "gt",
|
|
14
|
+
"value": "100"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"or_conditions": [],
|
|
18
|
+
"desc": "Blocks any single transaction above $100. Edit the amount after adding it."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"label": "Notify over $50",
|
|
22
|
+
"category": "Spending & transactions",
|
|
23
|
+
"domain": "payment",
|
|
24
|
+
"action": "NOTIFY",
|
|
25
|
+
"conditions": [
|
|
26
|
+
{
|
|
27
|
+
"field": "amount",
|
|
28
|
+
"operator": "gt",
|
|
29
|
+
"value": "50"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"or_conditions": [],
|
|
33
|
+
"desc": "Allows transactions over $50, but notifies you each time one happens."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"label": "Escalate over $200",
|
|
37
|
+
"category": "Spending & transactions",
|
|
38
|
+
"domain": "payment",
|
|
39
|
+
"action": "ESCALATE",
|
|
40
|
+
"conditions": [
|
|
41
|
+
{
|
|
42
|
+
"field": "amount",
|
|
43
|
+
"operator": "gt",
|
|
44
|
+
"value": "200"
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"or_conditions": [],
|
|
48
|
+
"desc": "Holds any transaction above $200 until you approve it. The agent waits."
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"label": "Block $200/day spend",
|
|
52
|
+
"category": "Spending & transactions",
|
|
53
|
+
"domain": "payment",
|
|
54
|
+
"action": "BLOCK",
|
|
55
|
+
"conditions": [
|
|
56
|
+
{
|
|
57
|
+
"field": "spend_per_day",
|
|
58
|
+
"operator": "gt",
|
|
59
|
+
"value": "200"
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"or_conditions": [],
|
|
63
|
+
"desc": "Caps total daily activity. Blocks the action that would cross $200 in a rolling 24 hours."
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"label": "Cap all agents at $1,000/month",
|
|
67
|
+
"category": "Spending & transactions",
|
|
68
|
+
"domain": "payment",
|
|
69
|
+
"action": "BLOCK",
|
|
70
|
+
"conditions": [
|
|
71
|
+
{
|
|
72
|
+
"field": "spend_per_month",
|
|
73
|
+
"operator": "gt",
|
|
74
|
+
"value": "1000"
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"or_conditions": [],
|
|
78
|
+
"desc": "One cap across every agent on the account, not per agent. Blocks the action that would cross $1,000 in a rolling 30 days."
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"label": "Escalate every transaction",
|
|
82
|
+
"category": "Spending & transactions",
|
|
83
|
+
"domain": "payment",
|
|
84
|
+
"action": "ESCALATE",
|
|
85
|
+
"conditions": [],
|
|
86
|
+
"or_conditions": [],
|
|
87
|
+
"desc": "Nothing happens without you approving it first. The strictest setting, good for a new agent you do not trust yet."
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"label": "Block a specific target domain",
|
|
91
|
+
"category": "Spending & transactions",
|
|
92
|
+
"domain": "payment",
|
|
93
|
+
"action": "BLOCK",
|
|
94
|
+
"conditions": [
|
|
95
|
+
{
|
|
96
|
+
"field": "merchant_name",
|
|
97
|
+
"operator": "contains",
|
|
98
|
+
"value": "example"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"or_conditions": [],
|
|
102
|
+
"desc": "Blocks actions targeting one domain. Replace \"example\" with the domain after adding it, otherwise it matches nothing."
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"label": "Notify on every message an agent sends",
|
|
106
|
+
"category": "Messages",
|
|
107
|
+
"domain": "comms",
|
|
108
|
+
"action": "NOTIFY",
|
|
109
|
+
"conditions": [],
|
|
110
|
+
"or_conditions": [],
|
|
111
|
+
"desc": "Emails you a copy of every send decision, on every channel. Nothing is blocked, pure visibility."
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"label": "Escalate every message an agent sends",
|
|
115
|
+
"category": "Messages",
|
|
116
|
+
"domain": "comms",
|
|
117
|
+
"action": "ESCALATE",
|
|
118
|
+
"conditions": [],
|
|
119
|
+
"or_conditions": [],
|
|
120
|
+
"desc": "Every outgoing message waits for your approval before it is sent, whichever channel it is going out on."
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"label": "Block an agent from sending messages",
|
|
124
|
+
"category": "Messages",
|
|
125
|
+
"domain": "comms",
|
|
126
|
+
"action": "BLOCK",
|
|
127
|
+
"conditions": [],
|
|
128
|
+
"or_conditions": [],
|
|
129
|
+
"desc": "Turns sending off entirely for the agents you pick. Nothing goes out, on any channel."
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"label": "Escalate messages going outside your company",
|
|
133
|
+
"category": "Messages",
|
|
134
|
+
"domain": "comms",
|
|
135
|
+
"action": "ESCALATE",
|
|
136
|
+
"conditions": [
|
|
137
|
+
{
|
|
138
|
+
"field": "recipient_domain",
|
|
139
|
+
"operator": "not_contains",
|
|
140
|
+
"value": "yourcompany.com"
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
"or_conditions": [],
|
|
144
|
+
"desc": "Internal email flows freely; anything addressed outside your domain waits for approval. Because a phone number or a chat handle has no company domain, WhatsApp, Telegram and SMS messages count as outside and will wait too. We assume the address you signed in with is your work address, so the domain is pre-filled from it. If you signed up with a personal address, change it to your real company domain before adding this, otherwise it will treat every address at your personal provider as internal."
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"label": "Escalate anything sent on WhatsApp or Telegram",
|
|
148
|
+
"category": "Messages",
|
|
149
|
+
"domain": "comms",
|
|
150
|
+
"action": "ESCALATE",
|
|
151
|
+
"conditions": [],
|
|
152
|
+
"or_conditions": [
|
|
153
|
+
{
|
|
154
|
+
"action": "ESCALATE",
|
|
155
|
+
"conditions": [
|
|
156
|
+
{
|
|
157
|
+
"field": "channel",
|
|
158
|
+
"operator": "eq",
|
|
159
|
+
"value": "whatsapp"
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"action": "ESCALATE",
|
|
165
|
+
"conditions": [
|
|
166
|
+
{
|
|
167
|
+
"field": "channel",
|
|
168
|
+
"operator": "eq",
|
|
169
|
+
"value": "telegram"
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
"desc": "Email goes out as normal; anything the agent tries to send on WhatsApp or Telegram waits for you. A good first rule if you have just connected an agent to a personal messaging account, where there is no sent folder to check afterwards."
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"label": "Block the agent from messaging apps",
|
|
178
|
+
"category": "Messages",
|
|
179
|
+
"domain": "comms",
|
|
180
|
+
"action": "BLOCK",
|
|
181
|
+
"conditions": [],
|
|
182
|
+
"or_conditions": [
|
|
183
|
+
{
|
|
184
|
+
"action": "BLOCK",
|
|
185
|
+
"conditions": [
|
|
186
|
+
{
|
|
187
|
+
"field": "channel",
|
|
188
|
+
"operator": "eq",
|
|
189
|
+
"value": "whatsapp"
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"action": "BLOCK",
|
|
195
|
+
"conditions": [
|
|
196
|
+
{
|
|
197
|
+
"field": "channel",
|
|
198
|
+
"operator": "eq",
|
|
199
|
+
"value": "telegram"
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"action": "BLOCK",
|
|
205
|
+
"conditions": [
|
|
206
|
+
{
|
|
207
|
+
"field": "channel",
|
|
208
|
+
"operator": "eq",
|
|
209
|
+
"value": "sms"
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"action": "BLOCK",
|
|
215
|
+
"conditions": [
|
|
216
|
+
{
|
|
217
|
+
"field": "channel",
|
|
218
|
+
"operator": "eq",
|
|
219
|
+
"value": "discord"
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
"desc": "The agent can still send email, but never a WhatsApp, Telegram, SMS or Discord message. For when an agent has a job that email covers completely and there is no reason for it to reach your personal contacts."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"label": "Block outgoing messages mentioning a password",
|
|
228
|
+
"category": "Messages",
|
|
229
|
+
"domain": "comms",
|
|
230
|
+
"action": "BLOCK",
|
|
231
|
+
"conditions": [
|
|
232
|
+
{
|
|
233
|
+
"field": "body",
|
|
234
|
+
"operator": "contains",
|
|
235
|
+
"value": "password"
|
|
236
|
+
}
|
|
237
|
+
],
|
|
238
|
+
"or_conditions": [],
|
|
239
|
+
"desc": "Reads the message body and blocks it if the word \"password\" appears anywhere in the text, on any channel."
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"label": "Block a credential in any outgoing message",
|
|
243
|
+
"category": "Messages",
|
|
244
|
+
"domain": "comms",
|
|
245
|
+
"action": "BLOCK",
|
|
246
|
+
"conditions": [],
|
|
247
|
+
"or_conditions": [
|
|
248
|
+
{
|
|
249
|
+
"action": "BLOCK",
|
|
250
|
+
"conditions": [
|
|
251
|
+
{
|
|
252
|
+
"field": "body",
|
|
253
|
+
"operator": "contains",
|
|
254
|
+
"value": "api key"
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"action": "BLOCK",
|
|
260
|
+
"conditions": [
|
|
261
|
+
{
|
|
262
|
+
"field": "body",
|
|
263
|
+
"operator": "contains",
|
|
264
|
+
"value": "txy-"
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"action": "BLOCK",
|
|
270
|
+
"conditions": [
|
|
271
|
+
{
|
|
272
|
+
"field": "body",
|
|
273
|
+
"operator": "contains",
|
|
274
|
+
"value": "sk-ant-"
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"action": "BLOCK",
|
|
280
|
+
"conditions": [
|
|
281
|
+
{
|
|
282
|
+
"field": "body",
|
|
283
|
+
"operator": "contains",
|
|
284
|
+
"value": "ghp_"
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"action": "BLOCK",
|
|
290
|
+
"conditions": [
|
|
291
|
+
{
|
|
292
|
+
"field": "body",
|
|
293
|
+
"operator": "contains",
|
|
294
|
+
"value": "AKIA"
|
|
295
|
+
}
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"action": "BLOCK",
|
|
300
|
+
"conditions": [
|
|
301
|
+
{
|
|
302
|
+
"field": "body",
|
|
303
|
+
"operator": "contains",
|
|
304
|
+
"value": "xoxb-"
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"action": "BLOCK",
|
|
310
|
+
"conditions": [
|
|
311
|
+
{
|
|
312
|
+
"field": "body",
|
|
313
|
+
"operator": "contains",
|
|
314
|
+
"value": "-----BEGIN"
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
}
|
|
318
|
+
],
|
|
319
|
+
"desc": "Reads the message body and blocks it if it contains a credential: the words \"api key\", or a key that starts like a Troxy, Anthropic, GitHub, AWS or Slack one, or a PEM private key or certificate. Works the same whether the agent is sending an email or pasting into a WhatsApp thread. Add your own prefixes after creating it."
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"label": "Escalate a message marked confidential",
|
|
323
|
+
"category": "Messages",
|
|
324
|
+
"domain": "comms",
|
|
325
|
+
"action": "ESCALATE",
|
|
326
|
+
"conditions": [
|
|
327
|
+
{
|
|
328
|
+
"field": "body",
|
|
329
|
+
"operator": "contains",
|
|
330
|
+
"value": "confidential"
|
|
331
|
+
}
|
|
332
|
+
],
|
|
333
|
+
"or_conditions": [],
|
|
334
|
+
"desc": "Holds any message whose body contains the word \"confidential\" until you approve it. Sending confidential material to a colleague is ordinary work, so this asks rather than refuses."
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"label": "Escalate mass sends (reply-all or bulk)",
|
|
338
|
+
"category": "Messages",
|
|
339
|
+
"domain": "comms",
|
|
340
|
+
"action": "ESCALATE",
|
|
341
|
+
"conditions": [
|
|
342
|
+
{
|
|
343
|
+
"field": "recipient_count",
|
|
344
|
+
"operator": "gt",
|
|
345
|
+
"value": "5"
|
|
346
|
+
}
|
|
347
|
+
],
|
|
348
|
+
"or_conditions": [],
|
|
349
|
+
"desc": "Counts every To, Cc and Bcc address, or every member of a group thread. More than 5 people and the send waits for your approval."
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"label": "Block messages to personal email domains",
|
|
353
|
+
"category": "Messages",
|
|
354
|
+
"domain": "comms",
|
|
355
|
+
"action": "BLOCK",
|
|
356
|
+
"conditions": [],
|
|
357
|
+
"or_conditions": [
|
|
358
|
+
{
|
|
359
|
+
"action": "BLOCK",
|
|
360
|
+
"conditions": [
|
|
361
|
+
{
|
|
362
|
+
"field": "recipient_domain",
|
|
363
|
+
"operator": "contains",
|
|
364
|
+
"value": "gmail.com"
|
|
365
|
+
}
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"action": "BLOCK",
|
|
370
|
+
"conditions": [
|
|
371
|
+
{
|
|
372
|
+
"field": "recipient_domain",
|
|
373
|
+
"operator": "contains",
|
|
374
|
+
"value": "yahoo.com"
|
|
375
|
+
}
|
|
376
|
+
]
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"action": "BLOCK",
|
|
380
|
+
"conditions": [
|
|
381
|
+
{
|
|
382
|
+
"field": "recipient_domain",
|
|
383
|
+
"operator": "contains",
|
|
384
|
+
"value": "outlook.com"
|
|
385
|
+
}
|
|
386
|
+
]
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"action": "BLOCK",
|
|
390
|
+
"conditions": [
|
|
391
|
+
{
|
|
392
|
+
"field": "recipient_domain",
|
|
393
|
+
"operator": "contains",
|
|
394
|
+
"value": "hotmail.com"
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
],
|
|
399
|
+
"desc": "Stops an agent from sending emails to personal email providers. Prevents data exfiltration to a personal account - the agent can still email colleagues at your company domain. Add other personal providers as branches after adding it."
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"label": "Escalate making a file public",
|
|
403
|
+
"category": "Files & documents",
|
|
404
|
+
"domain": "destructive",
|
|
405
|
+
"action": "ESCALATE",
|
|
406
|
+
"conditions": [
|
|
407
|
+
{
|
|
408
|
+
"field": "action_verb",
|
|
409
|
+
"operator": "eq",
|
|
410
|
+
"value": "share"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"field": "destination",
|
|
414
|
+
"operator": "eq",
|
|
415
|
+
"value": "public"
|
|
416
|
+
}
|
|
417
|
+
],
|
|
418
|
+
"or_conditions": [],
|
|
419
|
+
"desc": "Sharing a doc with a named person goes through. Turning on \"anyone with the link\", or making it public, waits for you. Publishing something deliberately is a real thing people do, so this asks rather than refuses."
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"label": "Escalate sharing a file outside your company",
|
|
423
|
+
"category": "Files & documents",
|
|
424
|
+
"domain": "destructive",
|
|
425
|
+
"action": "ESCALATE",
|
|
426
|
+
"conditions": [],
|
|
427
|
+
"or_conditions": [
|
|
428
|
+
{
|
|
429
|
+
"action": "ESCALATE",
|
|
430
|
+
"conditions": [
|
|
431
|
+
{
|
|
432
|
+
"field": "action_verb",
|
|
433
|
+
"operator": "eq",
|
|
434
|
+
"value": "share"
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"field": "destination",
|
|
438
|
+
"operator": "eq",
|
|
439
|
+
"value": "public"
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"action": "ESCALATE",
|
|
445
|
+
"conditions": [
|
|
446
|
+
{
|
|
447
|
+
"field": "action_verb",
|
|
448
|
+
"operator": "eq",
|
|
449
|
+
"value": "share"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"field": "destination",
|
|
453
|
+
"operator": "contains",
|
|
454
|
+
"value": "@"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
"field": "destination",
|
|
458
|
+
"operator": "not_contains",
|
|
459
|
+
"value": "yourcompany.com"
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
}
|
|
463
|
+
],
|
|
464
|
+
"desc": "Sharing with a colleague is unrestricted. Making a file public, or sharing it with an address outside your company, waits for your approval. Uploading a file to your own storage is not a share and will not trigger this. Pre-filled with the domain you signed in with, editable after adding."
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
"label": "Escalate a delete that cannot be undone",
|
|
468
|
+
"category": "Files & documents",
|
|
469
|
+
"domain": "destructive",
|
|
470
|
+
"action": "ESCALATE",
|
|
471
|
+
"conditions": [
|
|
472
|
+
{
|
|
473
|
+
"field": "action_verb",
|
|
474
|
+
"operator": "eq",
|
|
475
|
+
"value": "delete"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"field": "reversible",
|
|
479
|
+
"operator": "eq",
|
|
480
|
+
"value": "false"
|
|
481
|
+
}
|
|
482
|
+
],
|
|
483
|
+
"or_conditions": [],
|
|
484
|
+
"desc": "Moving a file to the trash is recoverable and goes through. Emptying the trash, or a permanent delete that skips it, waits for you. Covers the case where the agent itself has told us the action is irreversible."
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"label": "Notify when files are exported or downloaded",
|
|
488
|
+
"category": "Files & documents",
|
|
489
|
+
"domain": "destructive",
|
|
490
|
+
"action": "NOTIFY",
|
|
491
|
+
"conditions": [
|
|
492
|
+
{
|
|
493
|
+
"field": "action_verb",
|
|
494
|
+
"operator": "eq",
|
|
495
|
+
"value": "export"
|
|
496
|
+
}
|
|
497
|
+
],
|
|
498
|
+
"or_conditions": [],
|
|
499
|
+
"desc": "Nothing is blocked. You get an email whenever the agent pulls files or records out of a system, including a bulk download of a folder. Pair it with the bulk-export rule under Data & privacy if you want large ones to actually wait."
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
"label": "Escalate every signup",
|
|
503
|
+
"category": "Data & privacy",
|
|
504
|
+
"domain": "access",
|
|
505
|
+
"action": "ESCALATE",
|
|
506
|
+
"conditions": [
|
|
507
|
+
{
|
|
508
|
+
"field": "login_action",
|
|
509
|
+
"operator": "eq",
|
|
510
|
+
"value": "signup"
|
|
511
|
+
}
|
|
512
|
+
],
|
|
513
|
+
"or_conditions": [],
|
|
514
|
+
"desc": "The agent must get your approval before creating an account anywhere."
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
"label": "Notify on every login",
|
|
518
|
+
"category": "Data & privacy",
|
|
519
|
+
"domain": "access",
|
|
520
|
+
"action": "NOTIFY",
|
|
521
|
+
"conditions": [
|
|
522
|
+
{
|
|
523
|
+
"field": "login_action",
|
|
524
|
+
"operator": "eq",
|
|
525
|
+
"value": "login"
|
|
526
|
+
}
|
|
527
|
+
],
|
|
528
|
+
"or_conditions": [],
|
|
529
|
+
"desc": "Logging in is allowed, but you get an email showing which site each time."
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"label": "Never let the agent create accounts",
|
|
533
|
+
"category": "Data & privacy",
|
|
534
|
+
"domain": "access",
|
|
535
|
+
"action": "BLOCK",
|
|
536
|
+
"conditions": [
|
|
537
|
+
{
|
|
538
|
+
"field": "login_action",
|
|
539
|
+
"operator": "eq",
|
|
540
|
+
"value": "signup"
|
|
541
|
+
}
|
|
542
|
+
],
|
|
543
|
+
"or_conditions": [],
|
|
544
|
+
"desc": "A hard stop on signups. The agent can log into accounts you already have, but can never create a new one."
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"label": "Escalate access to a specific site",
|
|
548
|
+
"category": "Data & privacy",
|
|
549
|
+
"domain": "access",
|
|
550
|
+
"action": "ESCALATE",
|
|
551
|
+
"conditions": [
|
|
552
|
+
{
|
|
553
|
+
"field": "site",
|
|
554
|
+
"operator": "contains",
|
|
555
|
+
"value": "example.com"
|
|
556
|
+
}
|
|
557
|
+
],
|
|
558
|
+
"or_conditions": [],
|
|
559
|
+
"desc": "Gates one site by name. Replace \"example.com\" after adding it, otherwise it matches nothing."
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"label": "Escalate bank or card details in a message",
|
|
563
|
+
"category": "Data & privacy",
|
|
564
|
+
"domain": "comms",
|
|
565
|
+
"action": "ESCALATE",
|
|
566
|
+
"conditions": [],
|
|
567
|
+
"or_conditions": [
|
|
568
|
+
{
|
|
569
|
+
"action": "ESCALATE",
|
|
570
|
+
"conditions": [
|
|
571
|
+
{
|
|
572
|
+
"field": "body",
|
|
573
|
+
"operator": "contains",
|
|
574
|
+
"value": "card number"
|
|
575
|
+
}
|
|
576
|
+
]
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"action": "ESCALATE",
|
|
580
|
+
"conditions": [
|
|
581
|
+
{
|
|
582
|
+
"field": "body",
|
|
583
|
+
"operator": "contains",
|
|
584
|
+
"value": "cvv"
|
|
585
|
+
}
|
|
586
|
+
]
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"action": "ESCALATE",
|
|
590
|
+
"conditions": [
|
|
591
|
+
{
|
|
592
|
+
"field": "body",
|
|
593
|
+
"operator": "contains",
|
|
594
|
+
"value": "iban"
|
|
595
|
+
}
|
|
596
|
+
]
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"action": "ESCALATE",
|
|
600
|
+
"conditions": [
|
|
601
|
+
{
|
|
602
|
+
"field": "body",
|
|
603
|
+
"operator": "contains",
|
|
604
|
+
"value": "routing number"
|
|
605
|
+
}
|
|
606
|
+
]
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
"action": "ESCALATE",
|
|
610
|
+
"conditions": [
|
|
611
|
+
{
|
|
612
|
+
"field": "body",
|
|
613
|
+
"operator": "contains",
|
|
614
|
+
"value": "sort code"
|
|
615
|
+
}
|
|
616
|
+
]
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
"action": "ESCALATE",
|
|
620
|
+
"conditions": [
|
|
621
|
+
{
|
|
622
|
+
"field": "body",
|
|
623
|
+
"operator": "contains",
|
|
624
|
+
"value": "account number"
|
|
625
|
+
}
|
|
626
|
+
]
|
|
627
|
+
}
|
|
628
|
+
],
|
|
629
|
+
"desc": "Holds any message whose body mentions bank or card details until you approve it, on email or a messaging app. Matches the words around the number rather than the number itself, so an agent that pastes a bare 16 digits with no label will not be caught. Add your own phrases after adding it."
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
"label": "Escalate an ID or passport number in a message",
|
|
633
|
+
"category": "Data & privacy",
|
|
634
|
+
"domain": "comms",
|
|
635
|
+
"action": "ESCALATE",
|
|
636
|
+
"conditions": [],
|
|
637
|
+
"or_conditions": [
|
|
638
|
+
{
|
|
639
|
+
"action": "ESCALATE",
|
|
640
|
+
"conditions": [
|
|
641
|
+
{
|
|
642
|
+
"field": "body",
|
|
643
|
+
"operator": "contains",
|
|
644
|
+
"value": "passport number"
|
|
645
|
+
}
|
|
646
|
+
]
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"action": "ESCALATE",
|
|
650
|
+
"conditions": [
|
|
651
|
+
{
|
|
652
|
+
"field": "body",
|
|
653
|
+
"operator": "contains",
|
|
654
|
+
"value": "social security"
|
|
655
|
+
}
|
|
656
|
+
]
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
"action": "ESCALATE",
|
|
660
|
+
"conditions": [
|
|
661
|
+
{
|
|
662
|
+
"field": "body",
|
|
663
|
+
"operator": "contains",
|
|
664
|
+
"value": "national id"
|
|
665
|
+
}
|
|
666
|
+
]
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"action": "ESCALATE",
|
|
670
|
+
"conditions": [
|
|
671
|
+
{
|
|
672
|
+
"field": "body",
|
|
673
|
+
"operator": "contains",
|
|
674
|
+
"value": "date of birth"
|
|
675
|
+
}
|
|
676
|
+
]
|
|
677
|
+
}
|
|
678
|
+
],
|
|
679
|
+
"desc": "Government ID and date of birth are the details that make everything else easier to steal, so this asks you before any of them go out. Same substring caveat as the bank rule: it matches the label, not the number."
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
"label": "Escalate sharing anywhere you have not approved",
|
|
683
|
+
"category": "Data & privacy",
|
|
684
|
+
"domain": "destructive",
|
|
685
|
+
"action": "ESCALATE",
|
|
686
|
+
"conditions": [],
|
|
687
|
+
"or_conditions": [
|
|
688
|
+
{
|
|
689
|
+
"action": "ESCALATE",
|
|
690
|
+
"conditions": [
|
|
691
|
+
{
|
|
692
|
+
"field": "action_verb",
|
|
693
|
+
"operator": "eq",
|
|
694
|
+
"value": "share"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"field": "destination",
|
|
698
|
+
"operator": "eq",
|
|
699
|
+
"value": "public"
|
|
700
|
+
}
|
|
701
|
+
]
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"action": "ESCALATE",
|
|
705
|
+
"conditions": [
|
|
706
|
+
{
|
|
707
|
+
"field": "action_verb",
|
|
708
|
+
"operator": "eq",
|
|
709
|
+
"value": "share"
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
"field": "destination",
|
|
713
|
+
"operator": "contains",
|
|
714
|
+
"value": "@"
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"field": "destination",
|
|
718
|
+
"operator": "not_contains",
|
|
719
|
+
"value": "yourcompany.com"
|
|
720
|
+
}
|
|
721
|
+
]
|
|
722
|
+
}
|
|
723
|
+
],
|
|
724
|
+
"desc": "An allowlist. Anything made public, or shared with a person outside the domain named here, waits for your approval. Starts with your own company domain; add a branch per service or domain you want to treat as approved. Storing a file in your own Drive is not a share and will not trigger this."
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
"label": "Escalate a bulk data export",
|
|
728
|
+
"category": "Data & privacy",
|
|
729
|
+
"domain": "destructive",
|
|
730
|
+
"action": "ESCALATE",
|
|
731
|
+
"conditions": [
|
|
732
|
+
{
|
|
733
|
+
"field": "action_verb",
|
|
734
|
+
"operator": "eq",
|
|
735
|
+
"value": "export"
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
"field": "item_count",
|
|
739
|
+
"operator": "gt",
|
|
740
|
+
"value": "100"
|
|
741
|
+
}
|
|
742
|
+
],
|
|
743
|
+
"or_conditions": [],
|
|
744
|
+
"desc": "A small export goes through; anything over 100 records waits for you. Edit the threshold after adding it."
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
"label": "Block exporting customer data",
|
|
748
|
+
"category": "Data & privacy",
|
|
749
|
+
"domain": "destructive",
|
|
750
|
+
"action": "BLOCK",
|
|
751
|
+
"conditions": [
|
|
752
|
+
{
|
|
753
|
+
"field": "action_verb",
|
|
754
|
+
"operator": "eq",
|
|
755
|
+
"value": "export"
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
"field": "resource",
|
|
759
|
+
"operator": "contains",
|
|
760
|
+
"value": "customer"
|
|
761
|
+
}
|
|
762
|
+
],
|
|
763
|
+
"or_conditions": [],
|
|
764
|
+
"desc": "A hard stop on exporting any data from a customer, user, or PII store. The agent can export other datasets freely, but customer data does not leave without this rule being removed."
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"label": "Escalate access to social media",
|
|
768
|
+
"category": "Data & privacy",
|
|
769
|
+
"domain": "access",
|
|
770
|
+
"action": "ESCALATE",
|
|
771
|
+
"conditions": [],
|
|
772
|
+
"or_conditions": [
|
|
773
|
+
{
|
|
774
|
+
"action": "ESCALATE",
|
|
775
|
+
"conditions": [
|
|
776
|
+
{
|
|
777
|
+
"field": "site",
|
|
778
|
+
"operator": "contains",
|
|
779
|
+
"value": "twitter.com"
|
|
780
|
+
}
|
|
781
|
+
]
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
"action": "ESCALATE",
|
|
785
|
+
"conditions": [
|
|
786
|
+
{
|
|
787
|
+
"field": "site",
|
|
788
|
+
"operator": "contains",
|
|
789
|
+
"value": "facebook.com"
|
|
790
|
+
}
|
|
791
|
+
]
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
"action": "ESCALATE",
|
|
795
|
+
"conditions": [
|
|
796
|
+
{
|
|
797
|
+
"field": "site",
|
|
798
|
+
"operator": "contains",
|
|
799
|
+
"value": "instagram.com"
|
|
800
|
+
}
|
|
801
|
+
]
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
"action": "ESCALATE",
|
|
805
|
+
"conditions": [
|
|
806
|
+
{
|
|
807
|
+
"field": "site",
|
|
808
|
+
"operator": "contains",
|
|
809
|
+
"value": "linkedin.com"
|
|
810
|
+
}
|
|
811
|
+
]
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"action": "ESCALATE",
|
|
815
|
+
"conditions": [
|
|
816
|
+
{
|
|
817
|
+
"field": "site",
|
|
818
|
+
"operator": "contains",
|
|
819
|
+
"value": "tiktok.com"
|
|
820
|
+
}
|
|
821
|
+
]
|
|
822
|
+
}
|
|
823
|
+
],
|
|
824
|
+
"desc": "Any login or signup on a social media platform waits for your approval. Stops an agent from quietly connecting to social accounts on your behalf. Add more domains as branches after adding it."
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
"label": "Block API keys in agent output",
|
|
828
|
+
"category": "Secrets & credentials",
|
|
829
|
+
"domain": "secrets",
|
|
830
|
+
"action": "BLOCK",
|
|
831
|
+
"conditions": [
|
|
832
|
+
{
|
|
833
|
+
"field": "has_api_key",
|
|
834
|
+
"operator": "eq",
|
|
835
|
+
"value": "true"
|
|
836
|
+
}
|
|
837
|
+
],
|
|
838
|
+
"or_conditions": [],
|
|
839
|
+
"desc": "Stops an agent from sending, writing, or publishing content that contains an API key (AWS, Stripe, GitHub, Google, Slack, OpenAI and more). The most important guardrail - credentials in the wild are how breaches happen."
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
"label": "Block credit cards and private keys",
|
|
843
|
+
"category": "Secrets & credentials",
|
|
844
|
+
"domain": "secrets",
|
|
845
|
+
"action": "BLOCK",
|
|
846
|
+
"conditions": [],
|
|
847
|
+
"or_conditions": [
|
|
848
|
+
{
|
|
849
|
+
"action": "BLOCK",
|
|
850
|
+
"conditions": [
|
|
851
|
+
{
|
|
852
|
+
"field": "has_credit_card",
|
|
853
|
+
"operator": "eq",
|
|
854
|
+
"value": "true"
|
|
855
|
+
}
|
|
856
|
+
]
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
"action": "BLOCK",
|
|
860
|
+
"conditions": [
|
|
861
|
+
{
|
|
862
|
+
"field": "has_private_key",
|
|
863
|
+
"operator": "eq",
|
|
864
|
+
"value": "true"
|
|
865
|
+
}
|
|
866
|
+
]
|
|
867
|
+
}
|
|
868
|
+
],
|
|
869
|
+
"desc": "Catches credit card numbers and RSA/EC/DSA/SSH/PGP private keys before they leave the agent."
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
"label": "Escalate when any sensitive data is detected",
|
|
873
|
+
"category": "Secrets & credentials",
|
|
874
|
+
"domain": "secrets",
|
|
875
|
+
"action": "ESCALATE",
|
|
876
|
+
"conditions": [
|
|
877
|
+
{
|
|
878
|
+
"field": "has_sensitive_data",
|
|
879
|
+
"operator": "eq",
|
|
880
|
+
"value": "true"
|
|
881
|
+
}
|
|
882
|
+
],
|
|
883
|
+
"or_conditions": [],
|
|
884
|
+
"desc": "Pauses and asks you before any content containing sensitive data (API keys, tokens, credit cards, SSNs, database connection strings, JWTs) is sent. The broadest safety net."
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
"label": "Notify on secrets in agent output",
|
|
888
|
+
"category": "Secrets & credentials",
|
|
889
|
+
"domain": "secrets",
|
|
890
|
+
"action": "NOTIFY",
|
|
891
|
+
"conditions": [
|
|
892
|
+
{
|
|
893
|
+
"field": "has_sensitive_data",
|
|
894
|
+
"operator": "eq",
|
|
895
|
+
"value": "true"
|
|
896
|
+
}
|
|
897
|
+
],
|
|
898
|
+
"or_conditions": [],
|
|
899
|
+
"desc": "Lets everything through but emails you whenever a secret is detected in agent output. Use this when you want visibility without blocking."
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
"label": "Block a secret going somewhere public",
|
|
903
|
+
"category": "Secrets & credentials",
|
|
904
|
+
"domain": "secrets",
|
|
905
|
+
"action": "BLOCK",
|
|
906
|
+
"conditions": [
|
|
907
|
+
{
|
|
908
|
+
"field": "has_sensitive_data",
|
|
909
|
+
"operator": "eq",
|
|
910
|
+
"value": "true"
|
|
911
|
+
},
|
|
912
|
+
{
|
|
913
|
+
"field": "is_public",
|
|
914
|
+
"operator": "eq",
|
|
915
|
+
"value": "true"
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
"or_conditions": [],
|
|
919
|
+
"desc": "A secret shared with one named colleague is ordinary work; the same secret made public, or pushed to a public repo, is an incident with no acceptable version. BLOCK is right here in a way it is not for the broader escalate-on-any-secret rule above."
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
"label": "Escalate credential rotation",
|
|
923
|
+
"category": "Secrets & credentials",
|
|
924
|
+
"domain": "destructive",
|
|
925
|
+
"action": "ESCALATE",
|
|
926
|
+
"conditions": [
|
|
927
|
+
{
|
|
928
|
+
"field": "action_verb",
|
|
929
|
+
"operator": "eq",
|
|
930
|
+
"value": "rotate"
|
|
931
|
+
}
|
|
932
|
+
],
|
|
933
|
+
"or_conditions": [],
|
|
934
|
+
"desc": "Rotating a key is sometimes exactly the right move and sometimes breaks every system still holding the old one, so this asks you first rather than deciding for you."
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
"label": "Escalate personal data in agent output",
|
|
938
|
+
"category": "Secrets & credentials",
|
|
939
|
+
"domain": "secrets",
|
|
940
|
+
"action": "ESCALATE",
|
|
941
|
+
"conditions": [
|
|
942
|
+
{
|
|
943
|
+
"field": "has_pii",
|
|
944
|
+
"operator": "eq",
|
|
945
|
+
"value": "true"
|
|
946
|
+
}
|
|
947
|
+
],
|
|
948
|
+
"or_conditions": [],
|
|
949
|
+
"desc": "Social security numbers and similar personal identifiers are scored high severity, so with no rule at all they are blocked outright. That is often too blunt: a support agent quoting a customer's details back to them is doing its job. This softens PII specifically to a hold-and-ask, without loosening anything else. Use it if you handle customer data and want a person to look rather than a wall."
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
"label": "Block a password in agent output",
|
|
953
|
+
"category": "Secrets & credentials",
|
|
954
|
+
"domain": "secrets",
|
|
955
|
+
"action": "BLOCK",
|
|
956
|
+
"conditions": [
|
|
957
|
+
{
|
|
958
|
+
"field": "has_password",
|
|
959
|
+
"operator": "eq",
|
|
960
|
+
"value": "true"
|
|
961
|
+
}
|
|
962
|
+
],
|
|
963
|
+
"or_conditions": [],
|
|
964
|
+
"desc": "A password in a config line scores medium, which by default only escalates and waits. This makes it a hard stop instead. Worth having if your agents touch config files or deployment scripts, where a password reaching a log or a message is not something you want to be asked about at 2am."
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
"label": "Block database URLs and auth tokens",
|
|
968
|
+
"category": "Secrets & credentials",
|
|
969
|
+
"domain": "secrets",
|
|
970
|
+
"action": "BLOCK",
|
|
971
|
+
"conditions": [],
|
|
972
|
+
"or_conditions": [
|
|
973
|
+
{
|
|
974
|
+
"action": "BLOCK",
|
|
975
|
+
"conditions": [
|
|
976
|
+
{
|
|
977
|
+
"field": "has_connection_string",
|
|
978
|
+
"operator": "eq",
|
|
979
|
+
"value": "true"
|
|
980
|
+
}
|
|
981
|
+
]
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
"action": "BLOCK",
|
|
985
|
+
"conditions": [
|
|
986
|
+
{
|
|
987
|
+
"field": "has_jwt",
|
|
988
|
+
"operator": "eq",
|
|
989
|
+
"value": "true"
|
|
990
|
+
}
|
|
991
|
+
]
|
|
992
|
+
}
|
|
993
|
+
],
|
|
994
|
+
"desc": "A postgres:// or mongodb:// URL carries its own username and password, and a JWT is a working session until it expires - both are credentials that happen not to look like one. Named separately from the API key rule because these are the two people most often forget to treat as secrets."
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
"label": "Escalate secrets in code being pushed",
|
|
998
|
+
"category": "Secrets & credentials",
|
|
999
|
+
"domain": "secrets",
|
|
1000
|
+
"action": "ESCALATE",
|
|
1001
|
+
"conditions": [
|
|
1002
|
+
{
|
|
1003
|
+
"field": "has_sensitive_data",
|
|
1004
|
+
"operator": "eq",
|
|
1005
|
+
"value": "true"
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
"field": "content_type",
|
|
1009
|
+
"operator": "eq",
|
|
1010
|
+
"value": "code"
|
|
1011
|
+
}
|
|
1012
|
+
],
|
|
1013
|
+
"or_conditions": [],
|
|
1014
|
+
"desc": "A secret in a message is usually a mistake you can retract. A secret committed into code outlives the conversation and follows the repository around, including into every clone and every branch. This narrows to that case, so you can be stricter about code without escalating every ordinary message."
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
"label": "Escalate several secrets found at once",
|
|
1018
|
+
"category": "Secrets & credentials",
|
|
1019
|
+
"domain": "secrets",
|
|
1020
|
+
"action": "ESCALATE",
|
|
1021
|
+
"conditions": [
|
|
1022
|
+
{
|
|
1023
|
+
"field": "detection_count",
|
|
1024
|
+
"operator": "gt",
|
|
1025
|
+
"value": "2"
|
|
1026
|
+
}
|
|
1027
|
+
],
|
|
1028
|
+
"or_conditions": [],
|
|
1029
|
+
"desc": "One key in a message is usually a slip. Three or more in a single payload usually means a whole config file, an environment dump, or a credential store went out by accident - a different and worse event. Nothing else looks at how many were found; severity only reports the worst single one."
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
"label": "Block anything high severity",
|
|
1033
|
+
"category": "Secrets & credentials",
|
|
1034
|
+
"domain": "secrets",
|
|
1035
|
+
"action": "BLOCK",
|
|
1036
|
+
"conditions": [
|
|
1037
|
+
{
|
|
1038
|
+
"field": "highest_severity",
|
|
1039
|
+
"operator": "eq",
|
|
1040
|
+
"value": "high"
|
|
1041
|
+
}
|
|
1042
|
+
],
|
|
1043
|
+
"or_conditions": [],
|
|
1044
|
+
"desc": "This is what already happens when no other rule matches, written down as a rule you can see and change. Worth adding precisely because the built-in behaviour is invisible: with this in your list you can read it, reorder it, loosen it to ESCALATE, or scope it to particular agents. Without it, the same outcome happens with nothing on the page explaining why."
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
"label": "Escalate a new OAuth connection",
|
|
1048
|
+
"category": "Access & permissions",
|
|
1049
|
+
"domain": "destructive",
|
|
1050
|
+
"action": "ESCALATE",
|
|
1051
|
+
"conditions": [
|
|
1052
|
+
{
|
|
1053
|
+
"field": "action_verb",
|
|
1054
|
+
"operator": "eq",
|
|
1055
|
+
"value": "grant_access"
|
|
1056
|
+
}
|
|
1057
|
+
],
|
|
1058
|
+
"or_conditions": [],
|
|
1059
|
+
"desc": "Before the agent lets an app or service into one of your accounts, it waits for you. This is the one that stops a quiet permission grant becoming permanent."
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
"label": "Notify when the agent shares or uploads a file",
|
|
1063
|
+
"category": "Access & permissions",
|
|
1064
|
+
"domain": "destructive",
|
|
1065
|
+
"action": "NOTIFY",
|
|
1066
|
+
"conditions": [
|
|
1067
|
+
{
|
|
1068
|
+
"field": "action_verb",
|
|
1069
|
+
"operator": "eq",
|
|
1070
|
+
"value": "share"
|
|
1071
|
+
}
|
|
1072
|
+
],
|
|
1073
|
+
"or_conditions": [],
|
|
1074
|
+
"desc": "Nothing is blocked. You get an email whenever the agent shares something or puts a file somewhere, including into your own Drive. The broadest visibility rule for files; use the Files & documents templates if you want only outward sharing."
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
"label": "Escalate adding a new admin or user",
|
|
1078
|
+
"category": "Access & permissions",
|
|
1079
|
+
"domain": "destructive",
|
|
1080
|
+
"action": "ESCALATE",
|
|
1081
|
+
"conditions": [
|
|
1082
|
+
{
|
|
1083
|
+
"field": "action_verb",
|
|
1084
|
+
"operator": "eq",
|
|
1085
|
+
"value": "add_user"
|
|
1086
|
+
}
|
|
1087
|
+
],
|
|
1088
|
+
"or_conditions": [],
|
|
1089
|
+
"desc": "Any change that gives another person access to a system waits for your approval first."
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
"label": "Block changes to billing settings",
|
|
1093
|
+
"category": "Access & permissions",
|
|
1094
|
+
"domain": "destructive",
|
|
1095
|
+
"action": "BLOCK",
|
|
1096
|
+
"conditions": [
|
|
1097
|
+
{
|
|
1098
|
+
"field": "action_verb",
|
|
1099
|
+
"operator": "eq",
|
|
1100
|
+
"value": "modify"
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
"field": "resource",
|
|
1104
|
+
"operator": "contains",
|
|
1105
|
+
"value": "billing"
|
|
1106
|
+
}
|
|
1107
|
+
],
|
|
1108
|
+
"or_conditions": [],
|
|
1109
|
+
"desc": "A hard stop on the agent editing billing or plan settings. Other modifications go through, only billing is off limits."
|
|
1110
|
+
},
|
|
1111
|
+
{
|
|
1112
|
+
"label": "Never use a specific model",
|
|
1113
|
+
"category": "AI & models",
|
|
1114
|
+
"domain": "model",
|
|
1115
|
+
"action": "BLOCK",
|
|
1116
|
+
"conditions": [
|
|
1117
|
+
{
|
|
1118
|
+
"field": "model",
|
|
1119
|
+
"operator": "contains",
|
|
1120
|
+
"value": "fable"
|
|
1121
|
+
}
|
|
1122
|
+
],
|
|
1123
|
+
"or_conditions": [],
|
|
1124
|
+
"desc": "A hard stop on one model. Matches on part of the name, so it keeps working when the version number changes. Replace \"fable\" with the model you want to rule out. BLOCK is right here because you have already made the decision: this agent does not run on that model."
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
"label": "Escalate an expensive single run",
|
|
1128
|
+
"category": "AI & models",
|
|
1129
|
+
"domain": "model",
|
|
1130
|
+
"action": "ESCALATE",
|
|
1131
|
+
"conditions": [
|
|
1132
|
+
{
|
|
1133
|
+
"field": "estimated_cost",
|
|
1134
|
+
"operator": "gt",
|
|
1135
|
+
"value": "5"
|
|
1136
|
+
}
|
|
1137
|
+
],
|
|
1138
|
+
"or_conditions": [],
|
|
1139
|
+
"desc": "The agent tells Troxy what it expects a piece of work to cost before starting. Anything over the threshold waits for you. Good for the case where an agent quietly decides a job needs a hundred times more thinking than usual."
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
"label": "Cap AI spend at $50 a day",
|
|
1143
|
+
"category": "AI & models",
|
|
1144
|
+
"domain": "model",
|
|
1145
|
+
"action": "BLOCK",
|
|
1146
|
+
"conditions": [
|
|
1147
|
+
{
|
|
1148
|
+
"field": "cost_per_day",
|
|
1149
|
+
"operator": "gt",
|
|
1150
|
+
"value": "50"
|
|
1151
|
+
}
|
|
1152
|
+
],
|
|
1153
|
+
"or_conditions": [],
|
|
1154
|
+
"desc": "A rolling 24 hour ceiling on what this agent costs to run. Blocks the run that would cross the line, not the one after it. Counts only what the agent reports, so treat it as a strong brake rather than a guarantee."
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
"label": "Escalate at 1 million tokens a day",
|
|
1158
|
+
"category": "AI & models",
|
|
1159
|
+
"domain": "model",
|
|
1160
|
+
"action": "ESCALATE",
|
|
1161
|
+
"conditions": [
|
|
1162
|
+
{
|
|
1163
|
+
"field": "tokens_per_day",
|
|
1164
|
+
"operator": "gt",
|
|
1165
|
+
"value": "1000000"
|
|
1166
|
+
}
|
|
1167
|
+
],
|
|
1168
|
+
"or_conditions": [],
|
|
1169
|
+
"desc": "Same rolling window, counted in tokens instead of dollars. Escalates rather than blocks, because a heavy day is sometimes exactly what you asked for and you are the one who can tell."
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
"label": "Notify on a runaway loop",
|
|
1173
|
+
"category": "AI & models",
|
|
1174
|
+
"domain": "model",
|
|
1175
|
+
"action": "NOTIFY",
|
|
1176
|
+
"conditions": [
|
|
1177
|
+
{
|
|
1178
|
+
"field": "model_calls_per_hour",
|
|
1179
|
+
"operator": "gt",
|
|
1180
|
+
"value": "100"
|
|
1181
|
+
}
|
|
1182
|
+
],
|
|
1183
|
+
"or_conditions": [],
|
|
1184
|
+
"desc": "The rule with the best chance of catching an agent stuck in a loop. Each individual call looks cheap and reasonable; the rate is what gives it away. Set to notify so it stays out of the way until something is genuinely wrong."
|
|
1185
|
+
},
|
|
1186
|
+
{
|
|
1187
|
+
"label": "Escalate an unapproved provider",
|
|
1188
|
+
"category": "AI & models",
|
|
1189
|
+
"domain": "model",
|
|
1190
|
+
"action": "ESCALATE",
|
|
1191
|
+
"conditions": [
|
|
1192
|
+
{
|
|
1193
|
+
"field": "provider",
|
|
1194
|
+
"operator": "neq",
|
|
1195
|
+
"value": "anthropic"
|
|
1196
|
+
}
|
|
1197
|
+
],
|
|
1198
|
+
"or_conditions": [],
|
|
1199
|
+
"desc": "For when you care where your data is processed as much as what it costs. Anything running outside the provider you named waits for your approval. Edit the provider after adding it."
|
|
1200
|
+
},
|
|
1201
|
+
{
|
|
1202
|
+
"label": "Escalate an expensive model on a big job",
|
|
1203
|
+
"category": "AI & models",
|
|
1204
|
+
"domain": "model",
|
|
1205
|
+
"action": "ESCALATE",
|
|
1206
|
+
"conditions": [
|
|
1207
|
+
{
|
|
1208
|
+
"field": "model",
|
|
1209
|
+
"operator": "contains",
|
|
1210
|
+
"value": "opus"
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
"field": "estimated_cost",
|
|
1214
|
+
"operator": "gt",
|
|
1215
|
+
"value": "2"
|
|
1216
|
+
}
|
|
1217
|
+
],
|
|
1218
|
+
"or_conditions": [],
|
|
1219
|
+
"desc": "Two conditions, so a quick question on a strong model still goes through and only a long job on it waits for you. The shape to copy when you want a rule that stays quiet during normal work."
|
|
1220
|
+
},
|
|
1221
|
+
{
|
|
1222
|
+
"label": "Notify on every model call",
|
|
1223
|
+
"category": "AI & models",
|
|
1224
|
+
"domain": "model",
|
|
1225
|
+
"action": "NOTIFY",
|
|
1226
|
+
"conditions": [],
|
|
1227
|
+
"or_conditions": [],
|
|
1228
|
+
"desc": "Nothing is blocked. You get an email every time the agent calls a model, whichever provider or model it is. Pure visibility for a new agent you are still evaluating."
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
"label": "Escalate at $200/month in AI spend",
|
|
1232
|
+
"category": "AI & models",
|
|
1233
|
+
"domain": "model",
|
|
1234
|
+
"action": "ESCALATE",
|
|
1235
|
+
"conditions": [
|
|
1236
|
+
{
|
|
1237
|
+
"field": "cost_per_month",
|
|
1238
|
+
"operator": "gt",
|
|
1239
|
+
"value": "200"
|
|
1240
|
+
}
|
|
1241
|
+
],
|
|
1242
|
+
"or_conditions": [],
|
|
1243
|
+
"desc": "A rolling 30-day ceiling, same as the daily cap but monthly. Escalates rather than blocks - a heavy month is sometimes a big project, not a problem. Edit the amount after adding it."
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
"label": "Escalate large token counts per call",
|
|
1247
|
+
"category": "AI & models",
|
|
1248
|
+
"domain": "model",
|
|
1249
|
+
"action": "ESCALATE",
|
|
1250
|
+
"conditions": [
|
|
1251
|
+
{
|
|
1252
|
+
"field": "tokens",
|
|
1253
|
+
"operator": "gt",
|
|
1254
|
+
"value": "50000"
|
|
1255
|
+
}
|
|
1256
|
+
],
|
|
1257
|
+
"or_conditions": [],
|
|
1258
|
+
"desc": "Flags any single model call that uses more than 50K tokens. Usually means the agent is stuffing a huge context window - sometimes that is real work, sometimes it is waste. This asks you which."
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
"label": "Block models over $10/MTok output",
|
|
1262
|
+
"category": "AI & models",
|
|
1263
|
+
"domain": "model",
|
|
1264
|
+
"action": "BLOCK",
|
|
1265
|
+
"conditions": [
|
|
1266
|
+
{
|
|
1267
|
+
"field": "output_price",
|
|
1268
|
+
"operator": "gt",
|
|
1269
|
+
"value": "10"
|
|
1270
|
+
}
|
|
1271
|
+
],
|
|
1272
|
+
"or_conditions": [],
|
|
1273
|
+
"desc": "A price ceiling. Blocks any model that costs more than $10 per million output tokens, which rules out the most expensive tier (GPT-4, Opus) while allowing mid-tier models. Edit the threshold after adding it."
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
"label": "Force a cheaper model for routine work",
|
|
1277
|
+
"category": "AI & models",
|
|
1278
|
+
"domain": "model",
|
|
1279
|
+
"action": "BLOCK",
|
|
1280
|
+
"conditions": [
|
|
1281
|
+
{
|
|
1282
|
+
"field": "estimated_cost",
|
|
1283
|
+
"operator": "lt",
|
|
1284
|
+
"value": "0.50"
|
|
1285
|
+
},
|
|
1286
|
+
{
|
|
1287
|
+
"field": "output_price",
|
|
1288
|
+
"operator": "gt",
|
|
1289
|
+
"value": "5"
|
|
1290
|
+
}
|
|
1291
|
+
],
|
|
1292
|
+
"or_conditions": [],
|
|
1293
|
+
"desc": "If a job is cheap (under 50 cents), block it from running on an expensive model. Lets big jobs use premium models while routine tasks fall back to something affordable. The shape of a smart default."
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
"label": "Notify on any call over 10K tokens",
|
|
1297
|
+
"category": "AI & models",
|
|
1298
|
+
"domain": "model",
|
|
1299
|
+
"action": "NOTIFY",
|
|
1300
|
+
"conditions": [
|
|
1301
|
+
{
|
|
1302
|
+
"field": "tokens",
|
|
1303
|
+
"operator": "gt",
|
|
1304
|
+
"value": "10000"
|
|
1305
|
+
}
|
|
1306
|
+
],
|
|
1307
|
+
"or_conditions": [],
|
|
1308
|
+
"desc": "A lighter version of the 50K rule. Nothing is blocked, but you see every call that uses a meaningful amount of context. Good early in the debugging phase with a new agent."
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
"label": "Escalate anything that cannot be undone",
|
|
1312
|
+
"category": "Destructive actions",
|
|
1313
|
+
"domain": "destructive",
|
|
1314
|
+
"action": "ESCALATE",
|
|
1315
|
+
"conditions": [
|
|
1316
|
+
{
|
|
1317
|
+
"field": "reversible",
|
|
1318
|
+
"operator": "eq",
|
|
1319
|
+
"value": "false"
|
|
1320
|
+
}
|
|
1321
|
+
],
|
|
1322
|
+
"or_conditions": [],
|
|
1323
|
+
"desc": "The broadest safety net. Anything the agent cannot straightforwardly undo waits for you, including actions it did not label as reversible."
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
"label": "Escalate deleting more than 10 items",
|
|
1327
|
+
"category": "Destructive actions",
|
|
1328
|
+
"domain": "destructive",
|
|
1329
|
+
"action": "ESCALATE",
|
|
1330
|
+
"conditions": [
|
|
1331
|
+
{
|
|
1332
|
+
"field": "action_verb",
|
|
1333
|
+
"operator": "eq",
|
|
1334
|
+
"value": "delete"
|
|
1335
|
+
},
|
|
1336
|
+
{
|
|
1337
|
+
"field": "item_count",
|
|
1338
|
+
"operator": "gt",
|
|
1339
|
+
"value": "10"
|
|
1340
|
+
}
|
|
1341
|
+
],
|
|
1342
|
+
"or_conditions": [],
|
|
1343
|
+
"desc": "Small deletes go through; a bulk delete of more than 10 files or records waits for your approval."
|
|
1344
|
+
},
|
|
1345
|
+
{
|
|
1346
|
+
"label": "Escalate dropping a database table",
|
|
1347
|
+
"category": "Destructive actions",
|
|
1348
|
+
"domain": "destructive",
|
|
1349
|
+
"action": "ESCALATE",
|
|
1350
|
+
"conditions": [
|
|
1351
|
+
{
|
|
1352
|
+
"field": "action_verb",
|
|
1353
|
+
"operator": "eq",
|
|
1354
|
+
"value": "drop"
|
|
1355
|
+
}
|
|
1356
|
+
],
|
|
1357
|
+
"or_conditions": [],
|
|
1358
|
+
"desc": "Holds any drop of a table or schema until you approve it."
|
|
1359
|
+
},
|
|
1360
|
+
{
|
|
1361
|
+
"label": "Escalate destroying cloud infrastructure",
|
|
1362
|
+
"category": "Destructive actions",
|
|
1363
|
+
"domain": "destructive",
|
|
1364
|
+
"action": "ESCALATE",
|
|
1365
|
+
"conditions": [
|
|
1366
|
+
{
|
|
1367
|
+
"field": "action_verb",
|
|
1368
|
+
"operator": "eq",
|
|
1369
|
+
"value": "destroy"
|
|
1370
|
+
}
|
|
1371
|
+
],
|
|
1372
|
+
"or_conditions": [],
|
|
1373
|
+
"desc": "Tearing down servers, buckets or other infrastructure waits for you. Sometimes you genuinely want staging gone, so this asks instead of refusing, which would only teach you to switch the policy off."
|
|
1374
|
+
},
|
|
1375
|
+
{
|
|
1376
|
+
"label": "Escalate a force-push to main",
|
|
1377
|
+
"category": "Destructive actions",
|
|
1378
|
+
"domain": "destructive",
|
|
1379
|
+
"action": "ESCALATE",
|
|
1380
|
+
"conditions": [
|
|
1381
|
+
{
|
|
1382
|
+
"field": "action_verb",
|
|
1383
|
+
"operator": "eq",
|
|
1384
|
+
"value": "force_push"
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
"field": "resource",
|
|
1388
|
+
"operator": "contains",
|
|
1389
|
+
"value": "main"
|
|
1390
|
+
}
|
|
1391
|
+
],
|
|
1392
|
+
"or_conditions": [],
|
|
1393
|
+
"desc": "Force-pushing a feature branch is fine; force-pushing anything named main waits for you."
|
|
1394
|
+
},
|
|
1395
|
+
{
|
|
1396
|
+
"label": "Notify on every destructive action",
|
|
1397
|
+
"category": "Destructive actions",
|
|
1398
|
+
"domain": "destructive",
|
|
1399
|
+
"action": "NOTIFY",
|
|
1400
|
+
"conditions": [],
|
|
1401
|
+
"or_conditions": [],
|
|
1402
|
+
"desc": "Nothing is blocked. You get an email each time the agent deletes, drops or overwrites anything."
|
|
1403
|
+
},
|
|
1404
|
+
{
|
|
1405
|
+
"label": "Block all destructive actions",
|
|
1406
|
+
"category": "Destructive actions",
|
|
1407
|
+
"domain": "destructive",
|
|
1408
|
+
"action": "BLOCK",
|
|
1409
|
+
"conditions": [],
|
|
1410
|
+
"or_conditions": [],
|
|
1411
|
+
"desc": "The strictest setting. Nothing destructive goes through - no deletes, drops, destroys, or overwrites. Use this for a new agent you do not trust yet, then relax to escalate once you know what it does."
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"label": "Escalate overwriting existing files",
|
|
1415
|
+
"category": "Destructive actions",
|
|
1416
|
+
"domain": "destructive",
|
|
1417
|
+
"action": "ESCALATE",
|
|
1418
|
+
"conditions": [
|
|
1419
|
+
{
|
|
1420
|
+
"field": "action_verb",
|
|
1421
|
+
"operator": "eq",
|
|
1422
|
+
"value": "overwrite"
|
|
1423
|
+
}
|
|
1424
|
+
],
|
|
1425
|
+
"or_conditions": [],
|
|
1426
|
+
"desc": "Overwriting a file is scarier than deleting one - a delete can be undone, a replace silently puts wrong content where right content was. This asks before any overwrite goes through."
|
|
1427
|
+
}
|
|
1428
|
+
]
|
|
1429
|
+
}
|