handoffprobe 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +533 -0
  3. package/dist/attacks/index.d.ts +3 -0
  4. package/dist/attacks/index.d.ts.map +1 -0
  5. package/dist/attacks/index.js +3 -0
  6. package/dist/attacks/index.js.map +1 -0
  7. package/dist/attacks/p0/approval.d.ts +5 -0
  8. package/dist/attacks/p0/approval.d.ts.map +1 -0
  9. package/dist/attacks/p0/approval.js +121 -0
  10. package/dist/attacks/p0/approval.js.map +1 -0
  11. package/dist/attacks/p0/authorization.d.ts +6 -0
  12. package/dist/attacks/p0/authorization.d.ts.map +1 -0
  13. package/dist/attacks/p0/authorization.js +241 -0
  14. package/dist/attacks/p0/authorization.js.map +1 -0
  15. package/dist/attacks/p0/credentials.d.ts +10 -0
  16. package/dist/attacks/p0/credentials.d.ts.map +1 -0
  17. package/dist/attacks/p0/credentials.js +206 -0
  18. package/dist/attacks/p0/credentials.js.map +1 -0
  19. package/dist/attacks/p0/identity.d.ts +10 -0
  20. package/dist/attacks/p0/identity.d.ts.map +1 -0
  21. package/dist/attacks/p0/identity.js +200 -0
  22. package/dist/attacks/p0/identity.js.map +1 -0
  23. package/dist/attacks/p0/index.d.ts +9 -0
  24. package/dist/attacks/p0/index.d.ts.map +1 -0
  25. package/dist/attacks/p0/index.js +9 -0
  26. package/dist/attacks/p0/index.js.map +1 -0
  27. package/dist/attacks/p0/lifecycle.d.ts +6 -0
  28. package/dist/attacks/p0/lifecycle.d.ts.map +1 -0
  29. package/dist/attacks/p0/lifecycle.js +142 -0
  30. package/dist/attacks/p0/lifecycle.js.map +1 -0
  31. package/dist/attacks/p0/target.d.ts +11 -0
  32. package/dist/attacks/p0/target.d.ts.map +1 -0
  33. package/dist/attacks/p0/target.js +177 -0
  34. package/dist/attacks/p0/target.js.map +1 -0
  35. package/dist/attacks/p0/tenant.d.ts +10 -0
  36. package/dist/attacks/p0/tenant.d.ts.map +1 -0
  37. package/dist/attacks/p0/tenant.js +155 -0
  38. package/dist/attacks/p0/tenant.js.map +1 -0
  39. package/dist/attacks/p0/types.d.ts +9 -0
  40. package/dist/attacks/p0/types.d.ts.map +1 -0
  41. package/dist/attacks/p0/types.js +2 -0
  42. package/dist/attacks/p0/types.js.map +1 -0
  43. package/dist/attacks/p1/approval.d.ts +5 -0
  44. package/dist/attacks/p1/approval.d.ts.map +1 -0
  45. package/dist/attacks/p1/approval.js +259 -0
  46. package/dist/attacks/p1/approval.js.map +1 -0
  47. package/dist/attacks/p1/audit.d.ts +4 -0
  48. package/dist/attacks/p1/audit.d.ts.map +1 -0
  49. package/dist/attacks/p1/audit.js +128 -0
  50. package/dist/attacks/p1/audit.js.map +1 -0
  51. package/dist/attacks/p1/authorization.d.ts +5 -0
  52. package/dist/attacks/p1/authorization.d.ts.map +1 -0
  53. package/dist/attacks/p1/authorization.js +239 -0
  54. package/dist/attacks/p1/authorization.js.map +1 -0
  55. package/dist/attacks/p1/index.d.ts +7 -0
  56. package/dist/attacks/p1/index.d.ts.map +1 -0
  57. package/dist/attacks/p1/index.js +7 -0
  58. package/dist/attacks/p1/index.js.map +1 -0
  59. package/dist/attacks/p1/race.d.ts +5 -0
  60. package/dist/attacks/p1/race.d.ts.map +1 -0
  61. package/dist/attacks/p1/race.js +255 -0
  62. package/dist/attacks/p1/race.js.map +1 -0
  63. package/dist/attacks/p1/replay.d.ts +6 -0
  64. package/dist/attacks/p1/replay.d.ts.map +1 -0
  65. package/dist/attacks/p1/replay.js +285 -0
  66. package/dist/attacks/p1/replay.js.map +1 -0
  67. package/dist/attacks/p1/types.d.ts +28 -0
  68. package/dist/attacks/p1/types.d.ts.map +1 -0
  69. package/dist/attacks/p1/types.js +2 -0
  70. package/dist/attacks/p1/types.js.map +1 -0
  71. package/dist/cli/config.d.ts +15 -0
  72. package/dist/cli/config.d.ts.map +1 -0
  73. package/dist/cli/config.js +100 -0
  74. package/dist/cli/config.js.map +1 -0
  75. package/dist/cli/diagnostics.d.ts +4 -0
  76. package/dist/cli/diagnostics.d.ts.map +1 -0
  77. package/dist/cli/diagnostics.js +23 -0
  78. package/dist/cli/diagnostics.js.map +1 -0
  79. package/dist/cli/discovery.d.ts +3 -0
  80. package/dist/cli/discovery.d.ts.map +1 -0
  81. package/dist/cli/discovery.js +75 -0
  82. package/dist/cli/discovery.js.map +1 -0
  83. package/dist/cli/execution-catalog.d.ts +12 -0
  84. package/dist/cli/execution-catalog.d.ts.map +1 -0
  85. package/dist/cli/execution-catalog.js +76 -0
  86. package/dist/cli/execution-catalog.js.map +1 -0
  87. package/dist/cli/protocols.d.ts +6 -0
  88. package/dist/cli/protocols.d.ts.map +1 -0
  89. package/dist/cli/protocols.js +6 -0
  90. package/dist/cli/protocols.js.map +1 -0
  91. package/dist/cli/reporters.d.ts +7 -0
  92. package/dist/cli/reporters.d.ts.map +1 -0
  93. package/dist/cli/reporters.js +126 -0
  94. package/dist/cli/reporters.js.map +1 -0
  95. package/dist/cli/run-cli.d.ts +6 -0
  96. package/dist/cli/run-cli.d.ts.map +1 -0
  97. package/dist/cli/run-cli.js +243 -0
  98. package/dist/cli/run-cli.js.map +1 -0
  99. package/dist/cli/test-command.d.ts +29 -0
  100. package/dist/cli/test-command.d.ts.map +1 -0
  101. package/dist/cli/test-command.js +118 -0
  102. package/dist/cli/test-command.js.map +1 -0
  103. package/dist/cli.d.ts +3 -0
  104. package/dist/cli.d.ts.map +1 -0
  105. package/dist/cli.js +11 -0
  106. package/dist/cli.js.map +1 -0
  107. package/dist/core/adapters.d.ts +23 -0
  108. package/dist/core/adapters.d.ts.map +1 -0
  109. package/dist/core/adapters.js +2 -0
  110. package/dist/core/adapters.js.map +1 -0
  111. package/dist/core/attacks.d.ts +29 -0
  112. package/dist/core/attacks.d.ts.map +1 -0
  113. package/dist/core/attacks.js +38 -0
  114. package/dist/core/attacks.js.map +1 -0
  115. package/dist/core/errors.d.ts +16 -0
  116. package/dist/core/errors.d.ts.map +1 -0
  117. package/dist/core/errors.js +22 -0
  118. package/dist/core/errors.js.map +1 -0
  119. package/dist/core/evidence.d.ts +18 -0
  120. package/dist/core/evidence.d.ts.map +1 -0
  121. package/dist/core/evidence.js +2 -0
  122. package/dist/core/evidence.js.map +1 -0
  123. package/dist/core/findings.d.ts +25 -0
  124. package/dist/core/findings.d.ts.map +1 -0
  125. package/dist/core/findings.js +4 -0
  126. package/dist/core/findings.js.map +1 -0
  127. package/dist/core/index.d.ts +10 -0
  128. package/dist/core/index.d.ts.map +1 -0
  129. package/dist/core/index.js +10 -0
  130. package/dist/core/index.js.map +1 -0
  131. package/dist/core/provenance.d.ts +8 -0
  132. package/dist/core/provenance.d.ts.map +1 -0
  133. package/dist/core/provenance.js +2 -0
  134. package/dist/core/provenance.js.map +1 -0
  135. package/dist/core/redaction.d.ts +4 -0
  136. package/dist/core/redaction.d.ts.map +1 -0
  137. package/dist/core/redaction.js +59 -0
  138. package/dist/core/redaction.js.map +1 -0
  139. package/dist/core/runner.d.ts +42 -0
  140. package/dist/core/runner.d.ts.map +1 -0
  141. package/dist/core/runner.js +181 -0
  142. package/dist/core/runner.js.map +1 -0
  143. package/dist/core/security-context.d.ts +64 -0
  144. package/dist/core/security-context.d.ts.map +1 -0
  145. package/dist/core/security-context.js +56 -0
  146. package/dist/core/security-context.js.map +1 -0
  147. package/dist/github-action/core.d.ts +34 -0
  148. package/dist/github-action/core.d.ts.map +1 -0
  149. package/dist/github-action/core.js +118 -0
  150. package/dist/github-action/core.js.map +1 -0
  151. package/dist/github-action/run-action.d.ts +2 -0
  152. package/dist/github-action/run-action.d.ts.map +1 -0
  153. package/dist/github-action/run-action.js +112 -0
  154. package/dist/github-action/run-action.js.map +1 -0
  155. package/dist/index.d.ts +6 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +6 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/p0-fixture/a2a/executor.d.ts +22 -0
  160. package/dist/p0-fixture/a2a/executor.d.ts.map +1 -0
  161. package/dist/p0-fixture/a2a/executor.js +183 -0
  162. package/dist/p0-fixture/a2a/executor.js.map +1 -0
  163. package/dist/p0-fixture/a2a/harness.d.ts +16 -0
  164. package/dist/p0-fixture/a2a/harness.d.ts.map +1 -0
  165. package/dist/p0-fixture/a2a/harness.js +160 -0
  166. package/dist/p0-fixture/a2a/harness.js.map +1 -0
  167. package/dist/p0-fixture/authorization.d.ts +24 -0
  168. package/dist/p0-fixture/authorization.d.ts.map +1 -0
  169. package/dist/p0-fixture/authorization.js +66 -0
  170. package/dist/p0-fixture/authorization.js.map +1 -0
  171. package/dist/p0-fixture/constants.d.ts +17 -0
  172. package/dist/p0-fixture/constants.d.ts.map +1 -0
  173. package/dist/p0-fixture/constants.js +17 -0
  174. package/dist/p0-fixture/constants.js.map +1 -0
  175. package/dist/p0-fixture/handoff/adapter.d.ts +6 -0
  176. package/dist/p0-fixture/handoff/adapter.d.ts.map +1 -0
  177. package/dist/p0-fixture/handoff/adapter.js +8 -0
  178. package/dist/p0-fixture/handoff/adapter.js.map +1 -0
  179. package/dist/p0-fixture/index.d.ts +11 -0
  180. package/dist/p0-fixture/index.d.ts.map +1 -0
  181. package/dist/p0-fixture/index.js +11 -0
  182. package/dist/p0-fixture/index.js.map +1 -0
  183. package/dist/p0-fixture/mcp/fake-tools.d.ts +7 -0
  184. package/dist/p0-fixture/mcp/fake-tools.d.ts.map +1 -0
  185. package/dist/p0-fixture/mcp/fake-tools.js +322 -0
  186. package/dist/p0-fixture/mcp/fake-tools.js.map +1 -0
  187. package/dist/p0-fixture/mcp/harness.d.ts +16 -0
  188. package/dist/p0-fixture/mcp/harness.d.ts.map +1 -0
  189. package/dist/p0-fixture/mcp/harness.js +114 -0
  190. package/dist/p0-fixture/mcp/harness.js.map +1 -0
  191. package/dist/p0-fixture/mcp/types.d.ts +29 -0
  192. package/dist/p0-fixture/mcp/types.d.ts.map +1 -0
  193. package/dist/p0-fixture/mcp/types.js +2 -0
  194. package/dist/p0-fixture/mcp/types.js.map +1 -0
  195. package/dist/p0-fixture/payload-hash.d.ts +2 -0
  196. package/dist/p0-fixture/payload-hash.d.ts.map +1 -0
  197. package/dist/p0-fixture/payload-hash.js +20 -0
  198. package/dist/p0-fixture/payload-hash.js.map +1 -0
  199. package/dist/p0-fixture/reference.d.ts +8 -0
  200. package/dist/p0-fixture/reference.d.ts.map +1 -0
  201. package/dist/p0-fixture/reference.js +42 -0
  202. package/dist/p0-fixture/reference.js.map +1 -0
  203. package/dist/p0-fixture/scenario.d.ts +14 -0
  204. package/dist/p0-fixture/scenario.d.ts.map +1 -0
  205. package/dist/p0-fixture/scenario.js +22 -0
  206. package/dist/p0-fixture/scenario.js.map +1 -0
  207. package/dist/p0-fixture/state.d.ts +43 -0
  208. package/dist/p0-fixture/state.d.ts.map +1 -0
  209. package/dist/p0-fixture/state.js +85 -0
  210. package/dist/p0-fixture/state.js.map +1 -0
  211. package/dist/p0-fixture/target-adapter.d.ts +20 -0
  212. package/dist/p0-fixture/target-adapter.d.ts.map +1 -0
  213. package/dist/p0-fixture/target-adapter.js +62 -0
  214. package/dist/p0-fixture/target-adapter.js.map +1 -0
  215. package/dist/p1-fixture/approval-target-adapter.d.ts +47 -0
  216. package/dist/p1-fixture/approval-target-adapter.d.ts.map +1 -0
  217. package/dist/p1-fixture/approval-target-adapter.js +172 -0
  218. package/dist/p1-fixture/approval-target-adapter.js.map +1 -0
  219. package/dist/p1-fixture/audit-target-adapter.d.ts +36 -0
  220. package/dist/p1-fixture/audit-target-adapter.d.ts.map +1 -0
  221. package/dist/p1-fixture/audit-target-adapter.js +226 -0
  222. package/dist/p1-fixture/audit-target-adapter.js.map +1 -0
  223. package/dist/p1-fixture/barrier.d.ts +10 -0
  224. package/dist/p1-fixture/barrier.d.ts.map +1 -0
  225. package/dist/p1-fixture/barrier.js +44 -0
  226. package/dist/p1-fixture/barrier.js.map +1 -0
  227. package/dist/p1-fixture/clock.d.ts +7 -0
  228. package/dist/p1-fixture/clock.d.ts.map +1 -0
  229. package/dist/p1-fixture/clock.js +30 -0
  230. package/dist/p1-fixture/clock.js.map +1 -0
  231. package/dist/p1-fixture/index.d.ts +9 -0
  232. package/dist/p1-fixture/index.d.ts.map +1 -0
  233. package/dist/p1-fixture/index.js +9 -0
  234. package/dist/p1-fixture/index.js.map +1 -0
  235. package/dist/p1-fixture/race-target-adapter.d.ts +49 -0
  236. package/dist/p1-fixture/race-target-adapter.d.ts.map +1 -0
  237. package/dist/p1-fixture/race-target-adapter.js +384 -0
  238. package/dist/p1-fixture/race-target-adapter.js.map +1 -0
  239. package/dist/p1-fixture/replay-target-adapter.d.ts +44 -0
  240. package/dist/p1-fixture/replay-target-adapter.d.ts.map +1 -0
  241. package/dist/p1-fixture/replay-target-adapter.js +248 -0
  242. package/dist/p1-fixture/replay-target-adapter.js.map +1 -0
  243. package/dist/p1-fixture/state.d.ts +78 -0
  244. package/dist/p1-fixture/state.d.ts.map +1 -0
  245. package/dist/p1-fixture/state.js +191 -0
  246. package/dist/p1-fixture/state.js.map +1 -0
  247. package/dist/p1-fixture/target-adapter.d.ts +30 -0
  248. package/dist/p1-fixture/target-adapter.d.ts.map +1 -0
  249. package/dist/p1-fixture/target-adapter.js +142 -0
  250. package/dist/p1-fixture/target-adapter.js.map +1 -0
  251. package/dist/protocol-lab/a2a/executor.d.ts +13 -0
  252. package/dist/protocol-lab/a2a/executor.d.ts.map +1 -0
  253. package/dist/protocol-lab/a2a/executor.js +112 -0
  254. package/dist/protocol-lab/a2a/executor.js.map +1 -0
  255. package/dist/protocol-lab/a2a/harness.d.ts +11 -0
  256. package/dist/protocol-lab/a2a/harness.d.ts.map +1 -0
  257. package/dist/protocol-lab/a2a/harness.js +160 -0
  258. package/dist/protocol-lab/a2a/harness.js.map +1 -0
  259. package/dist/protocol-lab/evidence.d.ts +17 -0
  260. package/dist/protocol-lab/evidence.d.ts.map +1 -0
  261. package/dist/protocol-lab/evidence.js +28 -0
  262. package/dist/protocol-lab/evidence.js.map +1 -0
  263. package/dist/protocol-lab/fixture.d.ts +11 -0
  264. package/dist/protocol-lab/fixture.d.ts.map +1 -0
  265. package/dist/protocol-lab/fixture.js +54 -0
  266. package/dist/protocol-lab/fixture.js.map +1 -0
  267. package/dist/protocol-lab/handoff/adapter.d.ts +9 -0
  268. package/dist/protocol-lab/handoff/adapter.d.ts.map +1 -0
  269. package/dist/protocol-lab/handoff/adapter.js +13 -0
  270. package/dist/protocol-lab/handoff/adapter.js.map +1 -0
  271. package/dist/protocol-lab/handoff/translate.d.ts +3 -0
  272. package/dist/protocol-lab/handoff/translate.d.ts.map +1 -0
  273. package/dist/protocol-lab/handoff/translate.js +14 -0
  274. package/dist/protocol-lab/handoff/translate.js.map +1 -0
  275. package/dist/protocol-lab/mcp/fake-tools.d.ts +5 -0
  276. package/dist/protocol-lab/mcp/fake-tools.d.ts.map +1 -0
  277. package/dist/protocol-lab/mcp/fake-tools.js +58 -0
  278. package/dist/protocol-lab/mcp/fake-tools.js.map +1 -0
  279. package/dist/protocol-lab/mcp/harness.d.ts +7 -0
  280. package/dist/protocol-lab/mcp/harness.d.ts.map +1 -0
  281. package/dist/protocol-lab/mcp/harness.js +97 -0
  282. package/dist/protocol-lab/mcp/harness.js.map +1 -0
  283. package/dist/protocol-lab/models.d.ts +31 -0
  284. package/dist/protocol-lab/models.d.ts.map +1 -0
  285. package/dist/protocol-lab/models.js +2 -0
  286. package/dist/protocol-lab/models.js.map +1 -0
  287. package/dist/protocol-lab/run.d.ts +2 -0
  288. package/dist/protocol-lab/run.d.ts.map +1 -0
  289. package/dist/protocol-lab/run.js +22 -0
  290. package/dist/protocol-lab/run.js.map +1 -0
  291. package/dist/protocol-lab/target-adapter.d.ts +10 -0
  292. package/dist/protocol-lab/target-adapter.d.ts.map +1 -0
  293. package/dist/protocol-lab/target-adapter.js +33 -0
  294. package/dist/protocol-lab/target-adapter.js.map +1 -0
  295. package/package.json +77 -0
@@ -0,0 +1,239 @@
1
+ import { P0_AUTHORIZED_DOWNSTREAM, P0_AUTHORIZED_RESOURCE, P0_AUTHORIZED_TENANT, P0_CALLER, P0_CAPABILITY_UPDATE, P0_PRINCIPAL, createP0ReferenceContext, createP0UpdateInvoiceScenario, } from '../../p0-fixture/index.js';
2
+ const FULL_DELEGATION_CHAIN = [P0_PRINCIPAL, P0_CALLER, P0_AUTHORIZED_DOWNSTREAM];
3
+ function projectSources(section) {
4
+ return [
5
+ {
6
+ kind: 'project',
7
+ title: 'P1 Security Test Specification',
8
+ locator: `docs/P1_TEST_SPECIFICATION.md#${section}`,
9
+ },
10
+ {
11
+ kind: 'project',
12
+ title: 'Attack Catalog',
13
+ locator: 'docs/ATTACK_CATALOG.md#v01-p1--add-after-p0-engine-is-credible',
14
+ },
15
+ ];
16
+ }
17
+ function createDefinition(input) {
18
+ return {
19
+ id: input.id,
20
+ name: input.name,
21
+ category: 'authorization',
22
+ defaultSeverity: 'high',
23
+ priority: 'P1',
24
+ preconditions: input.preconditions,
25
+ mutationSteps: input.mutationSteps,
26
+ expectedInvariant: input.invariant,
27
+ evidenceRequirements: input.evidence,
28
+ applicability: {
29
+ a2a: ['1.0'],
30
+ mcp: ['2026-07-28'],
31
+ },
32
+ propertyClass: 'composition_responsibility',
33
+ sourceReferences: projectSources(input.section),
34
+ sideEffectClass: 'synthetic',
35
+ destructive: false,
36
+ };
37
+ }
38
+ function createUpdateContext() {
39
+ const context = createP0ReferenceContext();
40
+ if (context.upstreamAuthority === undefined || context.effectiveAuthority === undefined) {
41
+ throw new Error('P1 authorization attacks require authority bindings.');
42
+ }
43
+ context.capabilities = [P0_CAPABILITY_UPDATE];
44
+ context.upstreamAuthority.capabilities = [P0_CAPABILITY_UPDATE];
45
+ context.effectiveAuthority.capabilities = [P0_CAPABILITY_UPDATE];
46
+ return context;
47
+ }
48
+ function relevantEvidenceSequences(result) {
49
+ const relevant = new Set([
50
+ 'p1.authorization',
51
+ 'p1.authorization.blocked',
52
+ 'p1.authorization.bypassed',
53
+ 'handoff.translate',
54
+ 'p0.authorization',
55
+ 'mcp.tool.call',
56
+ 'mcp.tool.result',
57
+ ]);
58
+ return result.evidence
59
+ .filter((event) => relevant.has(event.event))
60
+ .map((event) => event.sequence);
61
+ }
62
+ function evaluateInvalidAuthority(result, messages) {
63
+ const output = result.output;
64
+ const evidenceSequences = relevantEvidenceSequences(result);
65
+ /*
66
+ * The attack only proves something when
67
+ * the P1 mutation actually made the
68
+ * delegation invalid.
69
+ */
70
+ if (output.decision.allowed) {
71
+ return {
72
+ status: 'inconclusive',
73
+ observedBehavior: 'The intended P1 mutation did not create an invalid delegation state.',
74
+ evidenceSequences,
75
+ };
76
+ }
77
+ if (!output.executed && output.sideEffectCounterAfter === output.sideEffectCounterBefore) {
78
+ return {
79
+ status: 'pass',
80
+ observedBehavior: messages.pass,
81
+ evidenceSequences,
82
+ };
83
+ }
84
+ if (output.executed && output.sideEffectCounterAfter > output.sideEffectCounterBefore) {
85
+ return {
86
+ status: 'fail',
87
+ observedBehavior: messages.fail,
88
+ evidenceSequences,
89
+ };
90
+ }
91
+ return {
92
+ status: 'inconclusive',
93
+ observedBehavior: 'Delegation evidence and synthetic side-effect evidence could not establish a deterministic PASS or FAIL.',
94
+ evidenceSequences,
95
+ };
96
+ }
97
+ const AUTH_004_DEFINITION = createDefinition({
98
+ id: 'HP-AUTH-004',
99
+ name: 'Expired delegation reuse',
100
+ preconditions: [
101
+ 'A delegation is valid before its deterministic expiry point.',
102
+ 'The delegation authorizes invoice.update for invoice:INV-1001.',
103
+ 'The protected action crosses the A2A to MCP handoff.',
104
+ ],
105
+ mutationSteps: [
106
+ 'Advance deterministic logical time to the delegation expiry boundary.',
107
+ 'Reuse the expired translated delegation.',
108
+ 'Attempt the protected update_invoice action.',
109
+ ],
110
+ invariant: 'Authority that expired before downstream authorization must not authorize the protected action.',
111
+ evidence: [
112
+ 'delegation ID',
113
+ 'issued point',
114
+ 'expiry point',
115
+ 'authorization point',
116
+ 'delegation validity state',
117
+ 'authorization result',
118
+ 'selected MCP tool',
119
+ 'side-effect counter before and after',
120
+ ],
121
+ section: 'hp-auth-004--expired-delegation-reuse',
122
+ });
123
+ const AUTH_005_DEFINITION = createDefinition({
124
+ id: 'HP-AUTH-005',
125
+ name: 'Delegation-chain truncation',
126
+ preconditions: [
127
+ 'Authorization requires the full user:alice to agent:sales to agent:billing delegation chain.',
128
+ 'The protected action crosses the A2A to MCP handoff.',
129
+ ],
130
+ mutationSteps: [
131
+ 'Remove agent:sales from the translated delegation chain.',
132
+ 'Preserve the final principal, delegate, tenant, resource and capability.',
133
+ 'Attempt the protected update_invoice action using the shortened chain.',
134
+ ],
135
+ invariant: 'Removing a security-relevant intermediate delegation hop must not preserve equivalent downstream authority.',
136
+ evidence: [
137
+ 'original required delegation chain',
138
+ 'translated delegation chain',
139
+ 'missing delegation hop',
140
+ 'authorization result',
141
+ 'selected MCP tool',
142
+ 'side-effect counter before and after',
143
+ ],
144
+ section: 'hp-auth-005--delegation-chain-truncation',
145
+ });
146
+ const AUTH_004_CASE = {
147
+ definition: AUTH_004_DEFINITION,
148
+ evaluate(result) {
149
+ return evaluateInvalidAuthority(result, {
150
+ pass: 'The expired delegation was rejected before protected MCP execution and no synthetic side effect occurred.',
151
+ fail: 'The expired delegation crossed the handoff and executed a protected synthetic invoice mutation.',
152
+ });
153
+ },
154
+ };
155
+ const AUTH_005_CASE = {
156
+ definition: AUTH_005_DEFINITION,
157
+ evaluate(result) {
158
+ return evaluateInvalidAuthority(result, {
159
+ pass: 'The truncated delegation chain was rejected before protected MCP execution and no synthetic side effect occurred.',
160
+ fail: 'The truncated delegation chain was treated as equivalent and executed a protected synthetic invoice mutation.',
161
+ });
162
+ },
163
+ };
164
+ export const HP_AUTH_004 = {
165
+ attack: AUTH_004_CASE,
166
+ scenario: {
167
+ id: 'expired-delegation-reuse',
168
+ delegation: {
169
+ id: 'delegation:DEL-1001',
170
+ principal: P0_PRINCIPAL,
171
+ delegate: P0_AUTHORIZED_DOWNSTREAM,
172
+ tenant: P0_AUTHORIZED_TENANT,
173
+ resources: [P0_AUTHORIZED_RESOURCE],
174
+ capabilities: [P0_CAPABILITY_UPDATE],
175
+ chain: [...FULL_DELEGATION_CHAIN],
176
+ taskId: 'task:P1-TASK-A',
177
+ runId: 'run:P1-RUN-A',
178
+ issuedAt: 10,
179
+ expiresAt: 20,
180
+ singleUse: false,
181
+ },
182
+ request: {
183
+ principal: P0_PRINCIPAL,
184
+ delegate: P0_AUTHORIZED_DOWNSTREAM,
185
+ tenant: P0_AUTHORIZED_TENANT,
186
+ resource: P0_AUTHORIZED_RESOURCE,
187
+ capability: P0_CAPABILITY_UPDATE,
188
+ taskId: 'task:P1-TASK-A',
189
+ runId: 'run:P1-RUN-A',
190
+ requiredChain: FULL_DELEGATION_CHAIN,
191
+ },
192
+ /*
193
+ * Exactly the expiry boundary.
194
+ * No sleeping or wall clock.
195
+ */
196
+ logicalTime: 20,
197
+ p0Scenario: createP0UpdateInvoiceScenario(24004),
198
+ },
199
+ createContext: createUpdateContext,
200
+ };
201
+ export const HP_AUTH_005 = {
202
+ attack: AUTH_005_CASE,
203
+ scenario: {
204
+ id: 'delegation-chain-truncation',
205
+ delegation: {
206
+ id: 'delegation:DEL-1002',
207
+ principal: P0_PRINCIPAL,
208
+ delegate: P0_AUTHORIZED_DOWNSTREAM,
209
+ tenant: P0_AUTHORIZED_TENANT,
210
+ resources: [P0_AUTHORIZED_RESOURCE],
211
+ capabilities: [P0_CAPABILITY_UPDATE],
212
+ /*
213
+ * Mutation:
214
+ * agent:sales was removed.
215
+ */
216
+ chain: [P0_PRINCIPAL, P0_AUTHORIZED_DOWNSTREAM],
217
+ taskId: 'task:P1-TASK-A',
218
+ runId: 'run:P1-RUN-A',
219
+ issuedAt: 10,
220
+ expiresAt: 30,
221
+ singleUse: false,
222
+ },
223
+ request: {
224
+ principal: P0_PRINCIPAL,
225
+ delegate: P0_AUTHORIZED_DOWNSTREAM,
226
+ tenant: P0_AUTHORIZED_TENANT,
227
+ resource: P0_AUTHORIZED_RESOURCE,
228
+ capability: P0_CAPABILITY_UPDATE,
229
+ taskId: 'task:P1-TASK-A',
230
+ runId: 'run:P1-RUN-A',
231
+ requiredChain: FULL_DELEGATION_CHAIN,
232
+ },
233
+ logicalTime: 15,
234
+ p0Scenario: createP0UpdateInvoiceScenario(24005),
235
+ },
236
+ createContext: createUpdateContext,
237
+ };
238
+ export const P1_AUTHORIZATION_ATTACKS = [HP_AUTH_004, HP_AUTH_005];
239
+ //# sourceMappingURL=authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/attacks/p1/authorization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './approval.js';
2
+ export * from './audit.js';
3
+ export * from './authorization.js';
4
+ export * from './race.js';
5
+ export * from './replay.js';
6
+ export * from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/attacks/p1/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './approval.js';
2
+ export * from './audit.js';
3
+ export * from './authorization.js';
4
+ export * from './race.js';
5
+ export * from './replay.js';
6
+ export * from './types.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/attacks/p1/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { P1RaceAttackPlan } from './types.js';
2
+ export declare const HP_RACE_001: P1RaceAttackPlan;
3
+ export declare const HP_RACE_002: P1RaceAttackPlan;
4
+ export declare const P1_RACE_ATTACKS: readonly P1RaceAttackPlan[];
5
+ //# sourceMappingURL=race.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"race.d.ts","sourceRoot":"","sources":["../../../src/attacks/p1/race.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAuQnD,eAAO,MAAM,WAAW,EAAE,gBAqBzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,gBAsBzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,SAAS,gBAAgB,EAA+B,CAAC"}
@@ -0,0 +1,255 @@
1
+ import { P0_AUTHORIZED_DOWNSTREAM, P0_AUTHORIZED_RESOURCE, P0_AUTHORIZED_TENANT, P0_CALLER, P0_CAPABILITY_UPDATE, P0_PRINCIPAL, createP0ReferenceContext, createP0UpdateInvoiceScenario, } from '../../p0-fixture/index.js';
2
+ const FULL_CHAIN = [P0_PRINCIPAL, P0_CALLER, P0_AUTHORIZED_DOWNSTREAM];
3
+ function projectSources(section) {
4
+ return [
5
+ {
6
+ kind: 'project',
7
+ title: 'P1 Security Test Specification',
8
+ locator: `docs/P1_TEST_SPECIFICATION.md#${section}`,
9
+ },
10
+ {
11
+ kind: 'project',
12
+ title: 'Attack Catalog',
13
+ locator: 'docs/ATTACK_CATALOG.md#v01-p1--add-after-p0-engine-is-credible',
14
+ },
15
+ ];
16
+ }
17
+ function createDefinition(input) {
18
+ return {
19
+ id: input.id,
20
+ name: input.name,
21
+ category: 'race',
22
+ defaultSeverity: 'high',
23
+ priority: 'P1',
24
+ preconditions: input.preconditions,
25
+ mutationSteps: input.mutationSteps,
26
+ expectedInvariant: input.invariant,
27
+ evidenceRequirements: input.evidence,
28
+ applicability: {
29
+ a2a: ['1.0'],
30
+ mcp: ['2026-07-28'],
31
+ },
32
+ propertyClass: 'composition_responsibility',
33
+ sourceReferences: projectSources(input.section),
34
+ sideEffectClass: 'synthetic',
35
+ destructive: false,
36
+ };
37
+ }
38
+ function createUpdateContext() {
39
+ const context = createP0ReferenceContext();
40
+ if (context.upstreamAuthority === undefined || context.effectiveAuthority === undefined) {
41
+ throw new Error('P1 race attacks require authority bindings.');
42
+ }
43
+ context.capabilities = [P0_CAPABILITY_UPDATE];
44
+ context.upstreamAuthority.capabilities = [P0_CAPABILITY_UPDATE];
45
+ context.effectiveAuthority.capabilities = [P0_CAPABILITY_UPDATE];
46
+ return context;
47
+ }
48
+ function createDelegation(input) {
49
+ return {
50
+ id: input.id,
51
+ principal: P0_PRINCIPAL,
52
+ delegate: P0_AUTHORIZED_DOWNSTREAM,
53
+ tenant: P0_AUTHORIZED_TENANT,
54
+ resources: [P0_AUTHORIZED_RESOURCE],
55
+ capabilities: [P0_CAPABILITY_UPDATE],
56
+ chain: [...FULL_CHAIN],
57
+ taskId: 'task:P1-RACE-A',
58
+ runId: 'run:P1-RACE-A',
59
+ issuedAt: 10,
60
+ expiresAt: 40,
61
+ singleUse: input.singleUse,
62
+ };
63
+ }
64
+ function createRequest() {
65
+ return {
66
+ principal: P0_PRINCIPAL,
67
+ delegate: P0_AUTHORIZED_DOWNSTREAM,
68
+ tenant: P0_AUTHORIZED_TENANT,
69
+ resource: P0_AUTHORIZED_RESOURCE,
70
+ capability: P0_CAPABILITY_UPDATE,
71
+ taskId: 'task:P1-RACE-A',
72
+ runId: 'run:P1-RACE-A',
73
+ requiredChain: FULL_CHAIN,
74
+ };
75
+ }
76
+ function relevantEvidenceSequences(result) {
77
+ const relevant = new Set([
78
+ 'p1.race.arrive',
79
+ 'p1.race.release',
80
+ 'p1.race.authorization',
81
+ 'p1.race.blocked',
82
+ 'p1.race.side_effect',
83
+ 'p1.partial.capture',
84
+ 'p1.partial.invalidate',
85
+ 'p1.partial.resume',
86
+ 'p1.partial.blocked',
87
+ 'p1.partial.side_effect',
88
+ 'handoff.translate',
89
+ 'mcp.tool.call',
90
+ 'mcp.tool.result',
91
+ ]);
92
+ return result.evidence
93
+ .filter((event) => relevant.has(event.event))
94
+ .map((event) => event.sequence);
95
+ }
96
+ function evaluateRace001(result) {
97
+ const output = result.output;
98
+ const evidenceSequences = relevantEvidenceSequences(result);
99
+ if (output.barrierArrivals !== 2) {
100
+ return {
101
+ status: 'inconclusive',
102
+ observedBehavior: 'Both deterministic race attempts did not reach the synchronization barrier.',
103
+ evidenceSequences,
104
+ };
105
+ }
106
+ const delta = output.sideEffectCounterAfter - output.sideEffectCounterBefore;
107
+ if (output.executedAttempts.length === 1 && delta === 1) {
108
+ return {
109
+ status: 'pass',
110
+ observedBehavior: 'Exactly one concurrent attempt consumed the one-time authority and only one synthetic protected side effect occurred.',
111
+ evidenceSequences,
112
+ };
113
+ }
114
+ if (output.executedAttempts.length === 2 && delta === 2) {
115
+ return {
116
+ status: 'fail',
117
+ observedBehavior: 'Both concurrent attempts reused the same one-time authority and produced two protected synthetic side effects.',
118
+ evidenceSequences,
119
+ };
120
+ }
121
+ return {
122
+ status: 'inconclusive',
123
+ observedBehavior: 'Race evidence did not establish a deterministic single or double protected execution.',
124
+ evidenceSequences,
125
+ };
126
+ }
127
+ function evaluateRace002(result) {
128
+ const output = result.output;
129
+ const evidenceSequences = relevantEvidenceSequences(result);
130
+ if (!output.initialDecision.allowed ||
131
+ output.currentDecision.allowed ||
132
+ !output.currentDecision.reasons.includes('delegation_invalidated')) {
133
+ return {
134
+ status: 'inconclusive',
135
+ observedBehavior: 'The fixture did not establish a valid captured state followed by deterministic invalidation.',
136
+ evidenceSequences,
137
+ };
138
+ }
139
+ const delta = output.sideEffectCounterAfter - output.sideEffectCounterBefore;
140
+ if (output.executedAttempts.length === 0 && delta === 0) {
141
+ return {
142
+ status: 'pass',
143
+ observedBehavior: 'The resumed operation revalidated current security state and rejected the stale captured authority.',
144
+ evidenceSequences,
145
+ };
146
+ }
147
+ if (output.executedAttempts.length === 1 && output.capturedStateUsed && delta === 1) {
148
+ return {
149
+ status: 'fail',
150
+ observedBehavior: 'The interrupted operation resumed using stale captured authority after that authority had been invalidated.',
151
+ evidenceSequences,
152
+ };
153
+ }
154
+ return {
155
+ status: 'inconclusive',
156
+ observedBehavior: 'Partial-failure evidence could not establish a deterministic stale-state PASS or FAIL.',
157
+ evidenceSequences,
158
+ };
159
+ }
160
+ const RACE_001_DEFINITION = createDefinition({
161
+ id: 'HP-RACE-001',
162
+ name: 'Parallel one-time authority consumption',
163
+ preconditions: [
164
+ 'One valid delegation is explicitly single-use.',
165
+ 'Two execution attempts target the same protected logical action.',
166
+ ],
167
+ mutationSteps: [
168
+ 'Start both attempts before either consumes the authority.',
169
+ 'Hold both at a deterministic synchronization barrier.',
170
+ 'Release them in fixed order against the same single-use delegation.',
171
+ ],
172
+ invariant: 'One-time authority must authorize at most one successful protected side effect.',
173
+ evidence: [
174
+ 'delegation ID',
175
+ 'single-use marker',
176
+ 'both attempt IDs',
177
+ 'barrier arrival and release events',
178
+ 'consumption state',
179
+ 'authorization result per attempt',
180
+ 'synthetic side-effect counter',
181
+ ],
182
+ section: 'hp-race-001--parallel-one-time-authority-consumption',
183
+ });
184
+ const RACE_002_DEFINITION = createDefinition({
185
+ id: 'HP-RACE-002',
186
+ name: 'Partial-failure stale execution',
187
+ preconditions: [
188
+ 'A protected operation begins with valid authority.',
189
+ 'The translated security state can be captured before protected execution.',
190
+ ],
191
+ mutationSteps: [
192
+ 'Pause after translation but before protected execution.',
193
+ 'Invalidate the governing delegation during the interruption.',
194
+ 'Resume using the previously captured state.',
195
+ ],
196
+ invariant: 'A resumed operation must revalidate security state that may have changed during an interruption.',
197
+ evidence: [
198
+ 'logical action ID',
199
+ 'interruption point',
200
+ 'captured authorization state',
201
+ 'invalidation event',
202
+ 'resume attempt',
203
+ 'current revalidation result',
204
+ 'deterministic sequence ordering',
205
+ 'synthetic side-effect counter',
206
+ ],
207
+ section: 'hp-race-002--partial-failure-stale-execution',
208
+ });
209
+ const RACE_001_CASE = {
210
+ definition: RACE_001_DEFINITION,
211
+ evaluate: evaluateRace001,
212
+ };
213
+ const RACE_002_CASE = {
214
+ definition: RACE_002_DEFINITION,
215
+ evaluate: evaluateRace002,
216
+ };
217
+ export const HP_RACE_001 = {
218
+ attack: RACE_001_CASE,
219
+ scenario: {
220
+ id: 'parallel-one-time-authority',
221
+ kind: 'parallel-one-time-authority',
222
+ actionId: 'action:ACT-RACE-1001',
223
+ firstAttemptId: 'attempt:ATT-1',
224
+ secondAttemptId: 'attempt:ATT-2',
225
+ delegation: createDelegation({
226
+ id: 'delegation:DEL-ONCE-1001',
227
+ singleUse: true,
228
+ }),
229
+ request: createRequest(),
230
+ logicalTime: 15,
231
+ p0Scenario: createP0UpdateInvoiceScenario(24701),
232
+ },
233
+ createContext: createUpdateContext,
234
+ };
235
+ export const HP_RACE_002 = {
236
+ attack: RACE_002_CASE,
237
+ scenario: {
238
+ id: 'partial-failure-stale-execution',
239
+ kind: 'partial-failure-stale-execution',
240
+ actionId: 'action:ACT-STALE-1001',
241
+ firstAttemptId: 'attempt:ATT-1',
242
+ secondAttemptId: 'attempt:ATT-2',
243
+ delegation: createDelegation({
244
+ id: 'delegation:DEL-STALE-1001',
245
+ singleUse: false,
246
+ }),
247
+ request: createRequest(),
248
+ logicalTime: 15,
249
+ invalidationTime: 16,
250
+ p0Scenario: createP0UpdateInvoiceScenario(24702),
251
+ },
252
+ createContext: createUpdateContext,
253
+ };
254
+ export const P1_RACE_ATTACKS = [HP_RACE_001, HP_RACE_002];
255
+ //# sourceMappingURL=race.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"race.js","sourceRoot":"","sources":["../../../src/attacks/p1/race.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { P1ReplayAttackPlan } from './types.js';
2
+ export declare const HP_REPLAY_001: P1ReplayAttackPlan;
3
+ export declare const HP_REPLAY_002: P1ReplayAttackPlan;
4
+ export declare const HP_REPLAY_003: P1ReplayAttackPlan;
5
+ export declare const P1_REPLAY_ATTACKS: readonly P1ReplayAttackPlan[];
6
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../../src/attacks/p1/replay.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAoYrD,eAAO,MAAM,aAAa,EAAE,kBA8B3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,kBA8B3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,kBAgC3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,SAAS,kBAAkB,EAI1D,CAAC"}