@highflame/policy 2.2.41 → 2.2.43

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.
Files changed (32) hide show
  1. package/_schemas/agent_ops/context.json +0 -42
  2. package/_schemas/agent_ops/schema.cedarschema +44 -6
  3. package/_schemas/ai_gateway/context.json +300 -0
  4. package/_schemas/ai_gateway/schema.cedarschema +107 -3
  5. package/_schemas/guardrails/context.json +0 -36
  6. package/_schemas/guardrails/detectors.json +0 -1
  7. package/_schemas/guardrails/schema.cedarschema +43 -5
  8. package/_schemas/guardrails/templates/dual_attribution.cedar +110 -0
  9. package/_schemas/guardrails/templates/multi_turn_trajectory.cedar +116 -0
  10. package/_schemas/guardrails/templates/profiles/output_protection/credentials.cedar +35 -0
  11. package/_schemas/guardrails/templates/profiles/output_protection/data_leakage.cedar +63 -0
  12. package/_schemas/guardrails/templates/profiles/output_protection/harmful_content.cedar +58 -0
  13. package/_schemas/guardrails/templates/profiles/output_protection/injection_carried_back.cedar +39 -0
  14. package/_schemas/guardrails/templates/session_risk_accumulation.cedar +103 -0
  15. package/_schemas/guardrails/templates/templates.json +157 -11
  16. package/_schemas/overwatch/context.json +65 -0
  17. package/_schemas/overwatch/detectors.json +47 -0
  18. package/_schemas/overwatch/schema.cedarschema +90 -0
  19. package/dist/agent_ops-context.gen.d.ts +1 -2
  20. package/dist/agent_ops-context.gen.js +0 -2
  21. package/dist/ai_gateway-entities.gen.js +5 -1
  22. package/dist/guardrails-context.gen.d.ts +1 -2
  23. package/dist/guardrails-context.gen.js +0 -2
  24. package/dist/guardrails-defaults.gen.js +751 -11
  25. package/dist/overwatch-context.gen.d.ts +3 -1
  26. package/dist/overwatch-context.gen.js +4 -0
  27. package/dist/overwatch-detectors.gen.js +16 -0
  28. package/dist/parser.d.ts +2 -1
  29. package/dist/parser.js +124 -37
  30. package/dist/service-schemas.gen.d.ts +4 -4
  31. package/dist/service-schemas.gen.js +354 -32
  32. package/package.json +1 -1
@@ -25,12 +25,6 @@
25
25
  "required": false,
26
26
  "description": "Principal identity class projected from the token: 'human', 'agent', 'service', or 'mcp_server'"
27
27
  },
28
- {
29
- "key": "principal",
30
- "type": "string",
31
- "required": false,
32
- "description": "Stable principal identifier projected from the token (e.g. a ZeroID / WIMSE URI or user id)"
33
- },
34
28
  {
35
29
  "key": "request_id",
36
30
  "type": "string",
@@ -817,12 +811,6 @@
817
811
  "required": false,
818
812
  "description": "Principal identity class projected from the token: 'human', 'agent', 'service', or 'mcp_server'"
819
813
  },
820
- {
821
- "key": "principal",
822
- "type": "string",
823
- "required": false,
824
- "description": "Stable principal identifier projected from the token (e.g. a ZeroID / WIMSE URI or user id)"
825
- },
826
814
  {
827
815
  "key": "request_id",
828
816
  "type": "string",
@@ -1609,12 +1597,6 @@
1609
1597
  "required": false,
1610
1598
  "description": "Principal identity class: 'human', 'agent', 'service', or 'mcp_server'"
1611
1599
  },
1612
- {
1613
- "key": "principal",
1614
- "type": "string",
1615
- "required": false,
1616
- "description": "Stable principal identifier"
1617
- },
1618
1600
  {
1619
1601
  "key": "request_id",
1620
1602
  "type": "string",
@@ -2372,12 +2354,6 @@
2372
2354
  "required": false,
2373
2355
  "description": "Principal identity class: 'human', 'agent', 'service', or 'mcp_server'"
2374
2356
  },
2375
- {
2376
- "key": "principal",
2377
- "type": "string",
2378
- "required": false,
2379
- "description": "Stable principal identifier"
2380
- },
2381
2357
  {
2382
2358
  "key": "request_id",
2383
2359
  "type": "string",
@@ -2752,12 +2728,6 @@
2752
2728
  "required": false,
2753
2729
  "description": "Principal identity class: 'human', 'agent', 'service', or 'mcp_server'"
2754
2730
  },
2755
- {
2756
- "key": "principal",
2757
- "type": "string",
2758
- "required": false,
2759
- "description": "Stable principal identifier"
2760
- },
2761
2731
  {
2762
2732
  "key": "request_id",
2763
2733
  "type": "string",
@@ -3145,12 +3115,6 @@
3145
3115
  "required": false,
3146
3116
  "description": "Principal identity class: 'human', 'agent', 'service', or 'mcp_server'"
3147
3117
  },
3148
- {
3149
- "key": "principal",
3150
- "type": "string",
3151
- "required": false,
3152
- "description": "Stable principal identifier"
3153
- },
3154
3118
  {
3155
3119
  "key": "request_id",
3156
3120
  "type": "string",
@@ -3565,12 +3529,6 @@
3565
3529
  "required": false,
3566
3530
  "description": "Principal identity class: 'human', 'agent', 'service', or 'mcp_server'"
3567
3531
  },
3568
- {
3569
- "key": "principal",
3570
- "type": "string",
3571
- "required": false,
3572
- "description": "Stable principal identifier (ZeroID / WIMSE URI or user id)"
3573
- },
3574
3532
  {
3575
3533
  "key": "agent_trust_level",
3576
3534
  "type": "string",
@@ -122,6 +122,44 @@ namespace AgentOps {
122
122
  // Context Types (Action-Specific)
123
123
  // =========================================================================
124
124
 
125
+ /// The ZeroID NHI principal block (ADR 0009 / CAP-IDN-011).
126
+ ///
127
+ /// A record, not a string: Shield projects the whole identity block under
128
+ /// `context.principal`, so policies read members off it —
129
+ ///
130
+ /// permit ... when { context has principal &&
131
+ /// context.principal.trust_level == "first_party" };
132
+ /// forbid ... unless { context has principal &&
133
+ /// context.principal has act_sub };
134
+ ///
135
+ /// Declared once and shared by every action context so a new member cannot
136
+ /// land on one action and go missing on another.
137
+ ///
138
+ /// `act` (RFC 8693 delegation) is flattened to `act_sub` / `act_iss`
139
+ /// because Cedar records are flat key/value at each level; the full
140
+ /// delegation tree is reconstructable audit-side by joining on `mission_id`.
141
+ ///
142
+ /// Every member is optional except `delegation_depth`: the projector omits
143
+ /// a field whose value is empty, but always emits the depth because zero is
144
+ /// the meaningful base case for a direct (non-delegated) token. The record
145
+ /// itself is optional — it is absent, not empty, when the request carries no
146
+ /// NHI claims (RS256 human tokens, internal-service callers), so
147
+ /// `context has principal` is false rather than true-but-empty.
148
+ type PrincipalContext = {
149
+ "identity_type"?: String, // "human" | "agent" | "service" | "mcp_server"
150
+ "sub_type"?: String, // Identity subtype (e.g. "coding_agent")
151
+ "trust_level"?: String, // "first_party" | "verified" | "unverified"
152
+ "framework"?: String, // Agent framework (e.g. "langchain")
153
+ "publisher"?: String, // Agent publisher
154
+ "capabilities"?: Set<String>, // Capabilities granted to the identity
155
+ "scopes"?: Set<String>, // OAuth scopes carried by the token
156
+ "delegation_depth": Long, // Delegation hops; 0 for a direct token
157
+ "act_sub"?: String, // RFC 8693 actor — the accountable human
158
+ "act_iss"?: String, // Issuer of the actor claim
159
+ "mission_id"?: String, // Correlates one delegation tree
160
+ "grant_type"?: String, // How the token was obtained (e.g. "api_key")
161
+ };
162
+
125
163
  /// Context for the process_response action.
126
164
  ///
127
165
  /// An alias, not a copy: prompts and responses are inspected by the same
@@ -136,7 +174,7 @@ namespace AgentOps {
136
174
  "role"?: String,
137
175
  "privilege_scope"?: Set<String>,
138
176
  "identity_type"?: String, // Principal identity class: "human" | "agent" | "service" | "mcp_server"
139
- "principal"?: String, // Stable principal identifier (e.g. ZeroID / WIMSE URI or user id)
177
+ "principal"?: PrincipalContext, // ZeroID NHI identity block; absent when the token carries no NHI claims
140
178
  // Core metadata (required)
141
179
  "request_id": String,
142
180
  "timestamp": Long,
@@ -331,7 +369,7 @@ namespace AgentOps {
331
369
  "role"?: String,
332
370
  "privilege_scope"?: Set<String>,
333
371
  "identity_type"?: String,
334
- "principal"?: String,
372
+ "principal"?: PrincipalContext, // ZeroID NHI identity block; absent when the token carries no NHI claims
335
373
  // Core metadata (required)
336
374
  "request_id": String,
337
375
  "timestamp": Long,
@@ -542,7 +580,7 @@ namespace AgentOps {
542
580
  "role"?: String,
543
581
  "privilege_scope"?: Set<String>,
544
582
  "identity_type"?: String,
545
- "principal"?: String,
583
+ "principal"?: PrincipalContext, // ZeroID NHI identity block; absent when the token carries no NHI claims
546
584
  // Core metadata (required)
547
585
  "request_id": String,
548
586
  "timestamp": Long,
@@ -650,7 +688,7 @@ namespace AgentOps {
650
688
  "role"?: String,
651
689
  "privilege_scope"?: Set<String>,
652
690
  "identity_type"?: String,
653
- "principal"?: String,
691
+ "principal"?: PrincipalContext, // ZeroID NHI identity block; absent when the token carries no NHI claims
654
692
  // Core metadata (required)
655
693
  "request_id": String,
656
694
  "timestamp": Long,
@@ -762,7 +800,7 @@ namespace AgentOps {
762
800
  "role"?: String,
763
801
  "privilege_scope"?: Set<String>,
764
802
  "identity_type"?: String,
765
- "principal"?: String,
803
+ "principal"?: PrincipalContext, // ZeroID NHI identity block; absent when the token carries no NHI claims
766
804
  // Core metadata (required)
767
805
  "request_id": String,
768
806
  "timestamp": Long,
@@ -895,7 +933,7 @@ namespace AgentOps {
895
933
  "role"?: String,
896
934
  "privilege_scope"?: Set<String>,
897
935
  "identity_type"?: String, // Principal identity class: "human" | "agent" | "service" | "mcp_server"
898
- "principal"?: String, // Stable principal identifier (ZeroID / WIMSE URI or user id)
936
+ "principal"?: PrincipalContext, // ZeroID NHI identity block; absent when the token carries no NHI claims
899
937
  "agent_trust_level"?: String, // "untrusted" | "low" | "verified" | "trusted"
900
938
 
901
939
  // Core metadata (required)
@@ -779,6 +779,306 @@
779
779
  }
780
780
  ]
781
781
  },
782
+ {
783
+ "name": "list",
784
+ "description": "Enumerate a server's tools, prompts, or resources — threat focus: tool poisoning and rug pull in the returned descriptions",
785
+ "context_attributes": [
786
+ {
787
+ "key": "role",
788
+ "type": "string",
789
+ "required": false,
790
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011)."
791
+ },
792
+ {
793
+ "key": "privilege_scope",
794
+ "type": "array",
795
+ "required": false,
796
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011)."
797
+ },
798
+ {
799
+ "key": "content",
800
+ "type": "string",
801
+ "required": false,
802
+ "description": "The enumerated item's description — the text scanned for poisoning. Absent when the item declares none."
803
+ },
804
+ {
805
+ "key": "mcp_server",
806
+ "type": "string",
807
+ "required": false,
808
+ "description": "MCP server being enumerated"
809
+ },
810
+ {
811
+ "key": "tool_name",
812
+ "type": "string",
813
+ "required": false,
814
+ "description": "Name of the enumerated item being evaluated"
815
+ },
816
+ {
817
+ "key": "tool_risk_score",
818
+ "type": "number",
819
+ "required": false,
820
+ "description": "Tool risk score"
821
+ },
822
+ {
823
+ "key": "tool_category",
824
+ "type": "string",
825
+ "required": false,
826
+ "description": "\"safe\", \"sensitive\", \"dangerous\""
827
+ },
828
+ {
829
+ "key": "tool_is_sensitive",
830
+ "type": "boolean",
831
+ "required": false,
832
+ "description": "Tool is sensitive"
833
+ },
834
+ {
835
+ "key": "tool_is_builtin",
836
+ "type": "boolean",
837
+ "required": false,
838
+ "description": "Tool is builtin"
839
+ },
840
+ {
841
+ "key": "tool_operation_classes",
842
+ "type": "array",
843
+ "required": false,
844
+ "description": "Tool operation classes"
845
+ },
846
+ {
847
+ "key": "threat_count",
848
+ "type": "number",
849
+ "required": false,
850
+ "description": "Total threats detected"
851
+ },
852
+ {
853
+ "key": "highest_severity",
854
+ "type": "string",
855
+ "required": false,
856
+ "description": "Highest threat severity"
857
+ },
858
+ {
859
+ "key": "threat_categories",
860
+ "type": "array",
861
+ "required": false,
862
+ "description": "Threat category names"
863
+ },
864
+ {
865
+ "key": "detected_threats",
866
+ "type": "array",
867
+ "required": false,
868
+ "description": "Detection rule names that matched"
869
+ },
870
+ {
871
+ "key": "max_threat_severity",
872
+ "type": "number",
873
+ "required": false,
874
+ "description": "Numeric severity (0=none, 4=critical)"
875
+ },
876
+ {
877
+ "key": "tool_poisoning_score",
878
+ "type": "number",
879
+ "required": false,
880
+ "description": "Hidden instructions in a tool description"
881
+ },
882
+ {
883
+ "key": "tool_poisoning_detected",
884
+ "type": "boolean",
885
+ "required": false,
886
+ "description": "Hidden instructions found in the description"
887
+ },
888
+ {
889
+ "key": "rug_pull_score",
890
+ "type": "number",
891
+ "required": false,
892
+ "description": "Description drift after trust establishment"
893
+ },
894
+ {
895
+ "key": "rug_pull_detected",
896
+ "type": "boolean",
897
+ "required": false,
898
+ "description": "Description drifted after trust was established"
899
+ },
900
+ {
901
+ "key": "indirect_injection_score",
902
+ "type": "number",
903
+ "required": false,
904
+ "description": "Indirect injection score"
905
+ },
906
+ {
907
+ "key": "injection_score",
908
+ "type": "number",
909
+ "required": false,
910
+ "description": "Prompt injection classifier confidence (0-100)"
911
+ },
912
+ {
913
+ "key": "jailbreak_score",
914
+ "type": "number",
915
+ "required": false,
916
+ "description": "Jailbreak classifier confidence (0-100)"
917
+ },
918
+ {
919
+ "key": "secrets_detected",
920
+ "type": "boolean",
921
+ "required": false,
922
+ "description": "Whether secrets were detected in the description"
923
+ },
924
+ {
925
+ "key": "secret_types",
926
+ "type": "array",
927
+ "required": false,
928
+ "description": "Secret types detected"
929
+ },
930
+ {
931
+ "key": "secret_count",
932
+ "type": "number",
933
+ "required": false,
934
+ "description": "Number of secrets detected"
935
+ },
936
+ {
937
+ "key": "pii_detected",
938
+ "type": "boolean",
939
+ "required": false,
940
+ "description": "Whether PII was detected"
941
+ },
942
+ {
943
+ "key": "pii_types",
944
+ "type": "array",
945
+ "required": false,
946
+ "description": "PII types detected"
947
+ },
948
+ {
949
+ "key": "pii_count",
950
+ "type": "number",
951
+ "required": false,
952
+ "description": "Number of PII entities"
953
+ },
954
+ {
955
+ "key": "pii_score",
956
+ "type": "number",
957
+ "required": false,
958
+ "description": "PII confidence (0-100)"
959
+ },
960
+ {
961
+ "key": "mcp_server_verified",
962
+ "type": "boolean",
963
+ "required": false,
964
+ "description": "Whether the server is from a verified registry"
965
+ },
966
+ {
967
+ "key": "mcp_config_risk",
968
+ "type": "boolean",
969
+ "required": false,
970
+ "description": "Server config flagged risky"
971
+ },
972
+ {
973
+ "key": "mcp_risk_score",
974
+ "type": "number",
975
+ "required": false,
976
+ "description": "Server risk score (0-100)"
977
+ },
978
+ {
979
+ "key": "session_threat_turns",
980
+ "type": "number",
981
+ "required": false,
982
+ "description": "Session-aggregated threat turns across prior turns"
983
+ },
984
+ {
985
+ "key": "session_cumulative_risk_score",
986
+ "type": "number",
987
+ "required": false,
988
+ "description": "Session-aggregated cumulative risk score across prior turns"
989
+ },
990
+ {
991
+ "key": "session_injection_detected",
992
+ "type": "boolean",
993
+ "required": false,
994
+ "description": "Session-aggregated injection detected across prior turns"
995
+ },
996
+ {
997
+ "key": "session_command_injection",
998
+ "type": "boolean",
999
+ "required": false,
1000
+ "description": "Session-aggregated command injection across prior turns"
1001
+ },
1002
+ {
1003
+ "key": "session_pii_detected",
1004
+ "type": "boolean",
1005
+ "required": false,
1006
+ "description": "Session-aggregated pii detected across prior turns"
1007
+ },
1008
+ {
1009
+ "key": "session_pii_types",
1010
+ "type": "array",
1011
+ "required": false,
1012
+ "description": "Session-aggregated pii types across prior turns"
1013
+ },
1014
+ {
1015
+ "key": "session_secrets_detected",
1016
+ "type": "boolean",
1017
+ "required": false,
1018
+ "description": "Session-aggregated secrets detected across prior turns"
1019
+ },
1020
+ {
1021
+ "key": "session_secret_types",
1022
+ "type": "array",
1023
+ "required": false,
1024
+ "description": "Session-aggregated secret types across prior turns"
1025
+ },
1026
+ {
1027
+ "key": "session_max_injection_score",
1028
+ "type": "number",
1029
+ "required": false,
1030
+ "description": "Session-aggregated max injection score across prior turns"
1031
+ },
1032
+ {
1033
+ "key": "session_max_jailbreak_score",
1034
+ "type": "number",
1035
+ "required": false,
1036
+ "description": "Session-aggregated max jailbreak score across prior turns"
1037
+ },
1038
+ {
1039
+ "key": "session_max_command_injection_score",
1040
+ "type": "number",
1041
+ "required": false,
1042
+ "description": "Session-aggregated max command injection score across prior turns"
1043
+ },
1044
+ {
1045
+ "key": "session_max_pii_score",
1046
+ "type": "number",
1047
+ "required": false,
1048
+ "description": "Session-aggregated max pii score across prior turns"
1049
+ },
1050
+ {
1051
+ "key": "session_max_secret_score",
1052
+ "type": "number",
1053
+ "required": false,
1054
+ "description": "Session-aggregated max secret score across prior turns"
1055
+ },
1056
+ {
1057
+ "key": "rpm_remaining_pct",
1058
+ "type": "number",
1059
+ "required": false,
1060
+ "description": "Requests-per-minute headroom remaining"
1061
+ },
1062
+ {
1063
+ "key": "rpm_exceeded",
1064
+ "type": "boolean",
1065
+ "required": false,
1066
+ "description": "RPM limit exceeded"
1067
+ },
1068
+ {
1069
+ "key": "tpm_remaining_pct",
1070
+ "type": "number",
1071
+ "required": false,
1072
+ "description": "Tokens-per-minute headroom remaining"
1073
+ },
1074
+ {
1075
+ "key": "tpm_exceeded",
1076
+ "type": "boolean",
1077
+ "required": false,
1078
+ "description": "TPM limit exceeded"
1079
+ }
1080
+ ]
1081
+ },
782
1082
  {
783
1083
  "name": "process_prompt",
784
1084
  "description": "Process a prompt (MCP or LLM chat completion) — threat focus: injection, jailbreak, secrets, PII, content safety",
@@ -74,7 +74,7 @@ entity FilePath in [Project];
74
74
  // ACTIONS
75
75
  // =============================================================================
76
76
 
77
- // Call an MCP tool
77
+ // Call an MCP tool (tools/call). Enumeration is the `list` action.
78
78
  // Threat focus: command injection, tool poisoning, rug pull, secrets, PII
79
79
  action call_tool appliesTo {
80
80
  principal: [User, MCP_Client],
@@ -274,6 +274,108 @@ action connect_server appliesTo {
274
274
  },
275
275
  };
276
276
 
277
+ // Enumerate a server's tools, prompts, or resources
278
+ // (tools/list, prompts/list, resources/list)
279
+ //
280
+ // Threat focus: tool poisoning and rug pull in the DESCRIPTIONS returned by
281
+ // enumeration — the text a host feeds the model when it assembles the
282
+ // session's tool schema, and the vector a rug-pull exploits between scans.
283
+ //
284
+ // Distinct from the actions it enumerates, and deliberately NOT default-locked
285
+ // (highflame-shield#515 / INV-AUTHZ-003). Listing is host plumbing: the model
286
+ // never decides to enumerate, the host does it to build the session. Folding
287
+ // it into call_tool / process_prompt / read_file made enumeration inherit
288
+ // their lock, and because a list names no tool, no conditioned grant
289
+ // (`context has tool_name && ...`) can ever match it — so an agent holding a
290
+ // correct grant for every tool it uses was still denied the enumeration step,
291
+ // and without tools/list it cannot call anything at all. The only grant that
292
+ // could match was an unconditioned one, which would have lifted the lock for
293
+ // every call as well. There is no way to express "may list, may not call"
294
+ // while a list and a call are the same action. See highflame-firehog#589.
295
+ //
296
+ // Authorization over WHAT may be enumerated is expressed through the list
297
+ // CONTENTS (the grant-derived list filter), not by denying the request.
298
+ action list appliesTo {
299
+ principal: [User, MCP_Client],
300
+ resource: [Server],
301
+ context: {
302
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
303
+ role?: String,
304
+ privilege_scope?: Set<String>,
305
+
306
+ // --- Content ---
307
+ // The enumerated item's description. Optional: a tool may declare none,
308
+ // and a policy must still evaluate when it does not.
309
+ content?: String,
310
+ mcp_server?: String,
311
+
312
+ // --- Enumerated item identity ---
313
+ // The list is scanned one item at a time, so the item being evaluated
314
+ // rides here while the resource stays the server being enumerated.
315
+ tool_name?: String,
316
+ tool_risk_score?: Long,
317
+ tool_category?: String, // "safe", "sensitive", "dangerous"
318
+ tool_is_sensitive?: Bool,
319
+ tool_is_builtin?: Bool,
320
+ tool_operation_classes?: Set<String>,
321
+
322
+ // --- Threat Detection ---
323
+ threat_count?: Long,
324
+ highest_severity?: String,
325
+ threat_categories?: Set<String>,
326
+ detected_threats?: Set<String>,
327
+ max_threat_severity?: Long,
328
+
329
+ // --- Agent Security (0-100) — the reason this action scans at all ---
330
+ tool_poisoning_score?: Long, // Hidden instructions in a tool description
331
+ tool_poisoning_detected?: Bool,
332
+ rug_pull_score?: Long, // Description drift after trust establishment
333
+ rug_pull_detected?: Bool,
334
+ indirect_injection_score?: Long,
335
+
336
+ // --- ML Detector Confidence Scores (0-100) ---
337
+ injection_score?: Long,
338
+ jailbreak_score?: Long,
339
+
340
+ // --- Secrets ---
341
+ secrets_detected?: Bool,
342
+ secret_types?: Set<String>,
343
+ secret_count?: Long,
344
+
345
+ // --- PII Detection ---
346
+ pii_detected?: Bool,
347
+ pii_types?: Set<String>,
348
+ pii_count?: Long,
349
+ pii_score?: Long,
350
+
351
+ // --- MCP Trust & Config Risk ---
352
+ mcp_server_verified?: Bool,
353
+ mcp_config_risk?: Bool,
354
+ mcp_risk_score?: Long,
355
+
356
+ // --- Session-Aware Threat Aggregation ---
357
+ session_threat_turns?: Long,
358
+ session_cumulative_risk_score?: Long,
359
+ session_injection_detected?: Bool,
360
+ session_command_injection?: Bool,
361
+ session_pii_detected?: Bool,
362
+ session_pii_types?: Set<String>,
363
+ session_secrets_detected?: Bool,
364
+ session_secret_types?: Set<String>,
365
+ session_max_injection_score?: Long,
366
+ session_max_jailbreak_score?: Long,
367
+ session_max_command_injection_score?: Long,
368
+ session_max_pii_score?: Long,
369
+ session_max_secret_score?: Long,
370
+
371
+ // Rate Limiting — gateway-metered, Shield-decided (ADR 0014)
372
+ rpm_remaining_pct?: Long,
373
+ rpm_exceeded?: Bool,
374
+ tpm_remaining_pct?: Long,
375
+ tpm_exceeded?: Bool,
376
+ },
377
+ };
378
+
277
379
  // Shared content-inspection context.
278
380
  //
279
381
  // Prompts and responses are inspected by the same detector pipeline and so
@@ -361,7 +463,8 @@ type ContentInspectionContext = {
361
463
  tpm_exceeded?: Bool,
362
464
  };
363
465
 
364
- // Process a prompt (MCP prompts/get or LLM chat completions)
466
+ // Process a prompt (MCP prompts/get or LLM chat completions).
467
+ // Enumeration (prompts/list) is the `list` action.
365
468
  // Threat focus: injection, jailbreak, secrets, PII, content safety
366
469
  action process_prompt appliesTo {
367
470
  principal: [User, MCP_Client],
@@ -384,7 +487,8 @@ action process_response appliesTo {
384
487
  context: ContentInspectionContext,
385
488
  };
386
489
 
387
- // Read an MCP resource (resources/read, resources/list)
490
+ // Read an MCP resource (resources/read). Enumeration (resources/list)
491
+ // is the `list` action.
388
492
  // Threat focus: secrets exposure, PII exposure, sensitive paths
389
493
  action read_file appliesTo {
390
494
  principal: [User, MCP_Client],