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.
- package/LICENSE +201 -0
- package/README.md +533 -0
- package/dist/attacks/index.d.ts +3 -0
- package/dist/attacks/index.d.ts.map +1 -0
- package/dist/attacks/index.js +3 -0
- package/dist/attacks/index.js.map +1 -0
- package/dist/attacks/p0/approval.d.ts +5 -0
- package/dist/attacks/p0/approval.d.ts.map +1 -0
- package/dist/attacks/p0/approval.js +121 -0
- package/dist/attacks/p0/approval.js.map +1 -0
- package/dist/attacks/p0/authorization.d.ts +6 -0
- package/dist/attacks/p0/authorization.d.ts.map +1 -0
- package/dist/attacks/p0/authorization.js +241 -0
- package/dist/attacks/p0/authorization.js.map +1 -0
- package/dist/attacks/p0/credentials.d.ts +10 -0
- package/dist/attacks/p0/credentials.d.ts.map +1 -0
- package/dist/attacks/p0/credentials.js +206 -0
- package/dist/attacks/p0/credentials.js.map +1 -0
- package/dist/attacks/p0/identity.d.ts +10 -0
- package/dist/attacks/p0/identity.d.ts.map +1 -0
- package/dist/attacks/p0/identity.js +200 -0
- package/dist/attacks/p0/identity.js.map +1 -0
- package/dist/attacks/p0/index.d.ts +9 -0
- package/dist/attacks/p0/index.d.ts.map +1 -0
- package/dist/attacks/p0/index.js +9 -0
- package/dist/attacks/p0/index.js.map +1 -0
- package/dist/attacks/p0/lifecycle.d.ts +6 -0
- package/dist/attacks/p0/lifecycle.d.ts.map +1 -0
- package/dist/attacks/p0/lifecycle.js +142 -0
- package/dist/attacks/p0/lifecycle.js.map +1 -0
- package/dist/attacks/p0/target.d.ts +11 -0
- package/dist/attacks/p0/target.d.ts.map +1 -0
- package/dist/attacks/p0/target.js +177 -0
- package/dist/attacks/p0/target.js.map +1 -0
- package/dist/attacks/p0/tenant.d.ts +10 -0
- package/dist/attacks/p0/tenant.d.ts.map +1 -0
- package/dist/attacks/p0/tenant.js +155 -0
- package/dist/attacks/p0/tenant.js.map +1 -0
- package/dist/attacks/p0/types.d.ts +9 -0
- package/dist/attacks/p0/types.d.ts.map +1 -0
- package/dist/attacks/p0/types.js +2 -0
- package/dist/attacks/p0/types.js.map +1 -0
- package/dist/attacks/p1/approval.d.ts +5 -0
- package/dist/attacks/p1/approval.d.ts.map +1 -0
- package/dist/attacks/p1/approval.js +259 -0
- package/dist/attacks/p1/approval.js.map +1 -0
- package/dist/attacks/p1/audit.d.ts +4 -0
- package/dist/attacks/p1/audit.d.ts.map +1 -0
- package/dist/attacks/p1/audit.js +128 -0
- package/dist/attacks/p1/audit.js.map +1 -0
- package/dist/attacks/p1/authorization.d.ts +5 -0
- package/dist/attacks/p1/authorization.d.ts.map +1 -0
- package/dist/attacks/p1/authorization.js +239 -0
- package/dist/attacks/p1/authorization.js.map +1 -0
- package/dist/attacks/p1/index.d.ts +7 -0
- package/dist/attacks/p1/index.d.ts.map +1 -0
- package/dist/attacks/p1/index.js +7 -0
- package/dist/attacks/p1/index.js.map +1 -0
- package/dist/attacks/p1/race.d.ts +5 -0
- package/dist/attacks/p1/race.d.ts.map +1 -0
- package/dist/attacks/p1/race.js +255 -0
- package/dist/attacks/p1/race.js.map +1 -0
- package/dist/attacks/p1/replay.d.ts +6 -0
- package/dist/attacks/p1/replay.d.ts.map +1 -0
- package/dist/attacks/p1/replay.js +285 -0
- package/dist/attacks/p1/replay.js.map +1 -0
- package/dist/attacks/p1/types.d.ts +28 -0
- package/dist/attacks/p1/types.d.ts.map +1 -0
- package/dist/attacks/p1/types.js +2 -0
- package/dist/attacks/p1/types.js.map +1 -0
- package/dist/cli/config.d.ts +15 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +100 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/diagnostics.d.ts +4 -0
- package/dist/cli/diagnostics.d.ts.map +1 -0
- package/dist/cli/diagnostics.js +23 -0
- package/dist/cli/diagnostics.js.map +1 -0
- package/dist/cli/discovery.d.ts +3 -0
- package/dist/cli/discovery.d.ts.map +1 -0
- package/dist/cli/discovery.js +75 -0
- package/dist/cli/discovery.js.map +1 -0
- package/dist/cli/execution-catalog.d.ts +12 -0
- package/dist/cli/execution-catalog.d.ts.map +1 -0
- package/dist/cli/execution-catalog.js +76 -0
- package/dist/cli/execution-catalog.js.map +1 -0
- package/dist/cli/protocols.d.ts +6 -0
- package/dist/cli/protocols.d.ts.map +1 -0
- package/dist/cli/protocols.js +6 -0
- package/dist/cli/protocols.js.map +1 -0
- package/dist/cli/reporters.d.ts +7 -0
- package/dist/cli/reporters.d.ts.map +1 -0
- package/dist/cli/reporters.js +126 -0
- package/dist/cli/reporters.js.map +1 -0
- package/dist/cli/run-cli.d.ts +6 -0
- package/dist/cli/run-cli.d.ts.map +1 -0
- package/dist/cli/run-cli.js +243 -0
- package/dist/cli/run-cli.js.map +1 -0
- package/dist/cli/test-command.d.ts +29 -0
- package/dist/cli/test-command.d.ts.map +1 -0
- package/dist/cli/test-command.js +118 -0
- package/dist/cli/test-command.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/adapters.d.ts +23 -0
- package/dist/core/adapters.d.ts.map +1 -0
- package/dist/core/adapters.js +2 -0
- package/dist/core/adapters.js.map +1 -0
- package/dist/core/attacks.d.ts +29 -0
- package/dist/core/attacks.d.ts.map +1 -0
- package/dist/core/attacks.js +38 -0
- package/dist/core/attacks.js.map +1 -0
- package/dist/core/errors.d.ts +16 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +22 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/evidence.d.ts +18 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +2 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/findings.d.ts +25 -0
- package/dist/core/findings.d.ts.map +1 -0
- package/dist/core/findings.js +4 -0
- package/dist/core/findings.js.map +1 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/provenance.d.ts +8 -0
- package/dist/core/provenance.d.ts.map +1 -0
- package/dist/core/provenance.js +2 -0
- package/dist/core/provenance.js.map +1 -0
- package/dist/core/redaction.d.ts +4 -0
- package/dist/core/redaction.d.ts.map +1 -0
- package/dist/core/redaction.js +59 -0
- package/dist/core/redaction.js.map +1 -0
- package/dist/core/runner.d.ts +42 -0
- package/dist/core/runner.d.ts.map +1 -0
- package/dist/core/runner.js +181 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/core/security-context.d.ts +64 -0
- package/dist/core/security-context.d.ts.map +1 -0
- package/dist/core/security-context.js +56 -0
- package/dist/core/security-context.js.map +1 -0
- package/dist/github-action/core.d.ts +34 -0
- package/dist/github-action/core.d.ts.map +1 -0
- package/dist/github-action/core.js +118 -0
- package/dist/github-action/core.js.map +1 -0
- package/dist/github-action/run-action.d.ts +2 -0
- package/dist/github-action/run-action.d.ts.map +1 -0
- package/dist/github-action/run-action.js +112 -0
- package/dist/github-action/run-action.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/p0-fixture/a2a/executor.d.ts +22 -0
- package/dist/p0-fixture/a2a/executor.d.ts.map +1 -0
- package/dist/p0-fixture/a2a/executor.js +183 -0
- package/dist/p0-fixture/a2a/executor.js.map +1 -0
- package/dist/p0-fixture/a2a/harness.d.ts +16 -0
- package/dist/p0-fixture/a2a/harness.d.ts.map +1 -0
- package/dist/p0-fixture/a2a/harness.js +160 -0
- package/dist/p0-fixture/a2a/harness.js.map +1 -0
- package/dist/p0-fixture/authorization.d.ts +24 -0
- package/dist/p0-fixture/authorization.d.ts.map +1 -0
- package/dist/p0-fixture/authorization.js +66 -0
- package/dist/p0-fixture/authorization.js.map +1 -0
- package/dist/p0-fixture/constants.d.ts +17 -0
- package/dist/p0-fixture/constants.d.ts.map +1 -0
- package/dist/p0-fixture/constants.js +17 -0
- package/dist/p0-fixture/constants.js.map +1 -0
- package/dist/p0-fixture/handoff/adapter.d.ts +6 -0
- package/dist/p0-fixture/handoff/adapter.d.ts.map +1 -0
- package/dist/p0-fixture/handoff/adapter.js +8 -0
- package/dist/p0-fixture/handoff/adapter.js.map +1 -0
- package/dist/p0-fixture/index.d.ts +11 -0
- package/dist/p0-fixture/index.d.ts.map +1 -0
- package/dist/p0-fixture/index.js +11 -0
- package/dist/p0-fixture/index.js.map +1 -0
- package/dist/p0-fixture/mcp/fake-tools.d.ts +7 -0
- package/dist/p0-fixture/mcp/fake-tools.d.ts.map +1 -0
- package/dist/p0-fixture/mcp/fake-tools.js +322 -0
- package/dist/p0-fixture/mcp/fake-tools.js.map +1 -0
- package/dist/p0-fixture/mcp/harness.d.ts +16 -0
- package/dist/p0-fixture/mcp/harness.d.ts.map +1 -0
- package/dist/p0-fixture/mcp/harness.js +114 -0
- package/dist/p0-fixture/mcp/harness.js.map +1 -0
- package/dist/p0-fixture/mcp/types.d.ts +29 -0
- package/dist/p0-fixture/mcp/types.d.ts.map +1 -0
- package/dist/p0-fixture/mcp/types.js +2 -0
- package/dist/p0-fixture/mcp/types.js.map +1 -0
- package/dist/p0-fixture/payload-hash.d.ts +2 -0
- package/dist/p0-fixture/payload-hash.d.ts.map +1 -0
- package/dist/p0-fixture/payload-hash.js +20 -0
- package/dist/p0-fixture/payload-hash.js.map +1 -0
- package/dist/p0-fixture/reference.d.ts +8 -0
- package/dist/p0-fixture/reference.d.ts.map +1 -0
- package/dist/p0-fixture/reference.js +42 -0
- package/dist/p0-fixture/reference.js.map +1 -0
- package/dist/p0-fixture/scenario.d.ts +14 -0
- package/dist/p0-fixture/scenario.d.ts.map +1 -0
- package/dist/p0-fixture/scenario.js +22 -0
- package/dist/p0-fixture/scenario.js.map +1 -0
- package/dist/p0-fixture/state.d.ts +43 -0
- package/dist/p0-fixture/state.d.ts.map +1 -0
- package/dist/p0-fixture/state.js +85 -0
- package/dist/p0-fixture/state.js.map +1 -0
- package/dist/p0-fixture/target-adapter.d.ts +20 -0
- package/dist/p0-fixture/target-adapter.d.ts.map +1 -0
- package/dist/p0-fixture/target-adapter.js +62 -0
- package/dist/p0-fixture/target-adapter.js.map +1 -0
- package/dist/p1-fixture/approval-target-adapter.d.ts +47 -0
- package/dist/p1-fixture/approval-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/approval-target-adapter.js +172 -0
- package/dist/p1-fixture/approval-target-adapter.js.map +1 -0
- package/dist/p1-fixture/audit-target-adapter.d.ts +36 -0
- package/dist/p1-fixture/audit-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/audit-target-adapter.js +226 -0
- package/dist/p1-fixture/audit-target-adapter.js.map +1 -0
- package/dist/p1-fixture/barrier.d.ts +10 -0
- package/dist/p1-fixture/barrier.d.ts.map +1 -0
- package/dist/p1-fixture/barrier.js +44 -0
- package/dist/p1-fixture/barrier.js.map +1 -0
- package/dist/p1-fixture/clock.d.ts +7 -0
- package/dist/p1-fixture/clock.d.ts.map +1 -0
- package/dist/p1-fixture/clock.js +30 -0
- package/dist/p1-fixture/clock.js.map +1 -0
- package/dist/p1-fixture/index.d.ts +9 -0
- package/dist/p1-fixture/index.d.ts.map +1 -0
- package/dist/p1-fixture/index.js +9 -0
- package/dist/p1-fixture/index.js.map +1 -0
- package/dist/p1-fixture/race-target-adapter.d.ts +49 -0
- package/dist/p1-fixture/race-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/race-target-adapter.js +384 -0
- package/dist/p1-fixture/race-target-adapter.js.map +1 -0
- package/dist/p1-fixture/replay-target-adapter.d.ts +44 -0
- package/dist/p1-fixture/replay-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/replay-target-adapter.js +248 -0
- package/dist/p1-fixture/replay-target-adapter.js.map +1 -0
- package/dist/p1-fixture/state.d.ts +78 -0
- package/dist/p1-fixture/state.d.ts.map +1 -0
- package/dist/p1-fixture/state.js +191 -0
- package/dist/p1-fixture/state.js.map +1 -0
- package/dist/p1-fixture/target-adapter.d.ts +30 -0
- package/dist/p1-fixture/target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/target-adapter.js +142 -0
- package/dist/p1-fixture/target-adapter.js.map +1 -0
- package/dist/protocol-lab/a2a/executor.d.ts +13 -0
- package/dist/protocol-lab/a2a/executor.d.ts.map +1 -0
- package/dist/protocol-lab/a2a/executor.js +112 -0
- package/dist/protocol-lab/a2a/executor.js.map +1 -0
- package/dist/protocol-lab/a2a/harness.d.ts +11 -0
- package/dist/protocol-lab/a2a/harness.d.ts.map +1 -0
- package/dist/protocol-lab/a2a/harness.js +160 -0
- package/dist/protocol-lab/a2a/harness.js.map +1 -0
- package/dist/protocol-lab/evidence.d.ts +17 -0
- package/dist/protocol-lab/evidence.d.ts.map +1 -0
- package/dist/protocol-lab/evidence.js +28 -0
- package/dist/protocol-lab/evidence.js.map +1 -0
- package/dist/protocol-lab/fixture.d.ts +11 -0
- package/dist/protocol-lab/fixture.d.ts.map +1 -0
- package/dist/protocol-lab/fixture.js +54 -0
- package/dist/protocol-lab/fixture.js.map +1 -0
- package/dist/protocol-lab/handoff/adapter.d.ts +9 -0
- package/dist/protocol-lab/handoff/adapter.d.ts.map +1 -0
- package/dist/protocol-lab/handoff/adapter.js +13 -0
- package/dist/protocol-lab/handoff/adapter.js.map +1 -0
- package/dist/protocol-lab/handoff/translate.d.ts +3 -0
- package/dist/protocol-lab/handoff/translate.d.ts.map +1 -0
- package/dist/protocol-lab/handoff/translate.js +14 -0
- package/dist/protocol-lab/handoff/translate.js.map +1 -0
- package/dist/protocol-lab/mcp/fake-tools.d.ts +5 -0
- package/dist/protocol-lab/mcp/fake-tools.d.ts.map +1 -0
- package/dist/protocol-lab/mcp/fake-tools.js +58 -0
- package/dist/protocol-lab/mcp/fake-tools.js.map +1 -0
- package/dist/protocol-lab/mcp/harness.d.ts +7 -0
- package/dist/protocol-lab/mcp/harness.d.ts.map +1 -0
- package/dist/protocol-lab/mcp/harness.js +97 -0
- package/dist/protocol-lab/mcp/harness.js.map +1 -0
- package/dist/protocol-lab/models.d.ts +31 -0
- package/dist/protocol-lab/models.d.ts.map +1 -0
- package/dist/protocol-lab/models.js +2 -0
- package/dist/protocol-lab/models.js.map +1 -0
- package/dist/protocol-lab/run.d.ts +2 -0
- package/dist/protocol-lab/run.d.ts.map +1 -0
- package/dist/protocol-lab/run.js +22 -0
- package/dist/protocol-lab/run.js.map +1 -0
- package/dist/protocol-lab/target-adapter.d.ts +10 -0
- package/dist/protocol-lab/target-adapter.d.ts.map +1 -0
- package/dist/protocol-lab/target-adapter.js +33 -0
- package/dist/protocol-lab/target-adapter.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { cloneSecurityContext } from '../core/index.js';
|
|
2
|
+
import { P0TargetAdapter } from '../p0-fixture/index.js';
|
|
3
|
+
import { EvidenceRecorder } from '../protocol-lab/evidence.js';
|
|
4
|
+
import { createP1FixtureState, evaluateP1Delegation, registerP1Delegation } from './state.js';
|
|
5
|
+
export class P1AuthorizationTargetAdapter {
|
|
6
|
+
fixture;
|
|
7
|
+
scenario;
|
|
8
|
+
id;
|
|
9
|
+
constructor(fixture, scenario) {
|
|
10
|
+
this.fixture = fixture;
|
|
11
|
+
this.scenario = scenario;
|
|
12
|
+
this.id = ['p1', fixture, scenario.id].join(':');
|
|
13
|
+
}
|
|
14
|
+
async execute(input) {
|
|
15
|
+
if (input.signal.aborted) {
|
|
16
|
+
throw new Error('P1 execution was aborted before start.');
|
|
17
|
+
}
|
|
18
|
+
const originalContext = cloneSecurityContext(input.context);
|
|
19
|
+
const translatedContext = cloneSecurityContext(input.context);
|
|
20
|
+
const recorder = new EvidenceRecorder(input.runId, this.fixture, input.correlationId);
|
|
21
|
+
const state = createP1FixtureState();
|
|
22
|
+
registerP1Delegation(state, this.scenario.delegation);
|
|
23
|
+
const decision = evaluateP1Delegation(state, this.scenario.delegation.id, this.scenario.logicalTime, this.scenario.request);
|
|
24
|
+
recorder.record({
|
|
25
|
+
protocol: 'HANDOFF',
|
|
26
|
+
protocolVersion: 'handoffprobe-p1-v1',
|
|
27
|
+
boundary: 'a2a-delegation -> handoff-authorization',
|
|
28
|
+
event: 'p1.authorization',
|
|
29
|
+
context: translatedContext,
|
|
30
|
+
details: {
|
|
31
|
+
scenarioId: this.scenario.id,
|
|
32
|
+
delegationId: this.scenario.delegation.id,
|
|
33
|
+
logicalTime: this.scenario.logicalTime,
|
|
34
|
+
issuedAt: this.scenario.delegation.issuedAt,
|
|
35
|
+
expiresAt: this.scenario.delegation.expiresAt,
|
|
36
|
+
delegationChain: this.scenario.delegation.chain,
|
|
37
|
+
requiredChain: this.scenario.request.requiredChain,
|
|
38
|
+
taskId: this.scenario.request.taskId,
|
|
39
|
+
runId: this.scenario.request.runId,
|
|
40
|
+
allowed: decision.allowed,
|
|
41
|
+
reasons: decision.reasons,
|
|
42
|
+
expired: decision.expired,
|
|
43
|
+
chainMatches: decision.chainMatches,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
/*
|
|
47
|
+
* Secure fixture:
|
|
48
|
+
* invalid P1 authority is stopped before
|
|
49
|
+
* the protected MCP execution.
|
|
50
|
+
*
|
|
51
|
+
* Vulnerable fixture:
|
|
52
|
+
* the handoff ignores the failed P1
|
|
53
|
+
* authority decision and continues into
|
|
54
|
+
* the normal A2A -> MCP execution path.
|
|
55
|
+
*/
|
|
56
|
+
if (!decision.allowed && this.fixture === 'secure') {
|
|
57
|
+
recorder.record({
|
|
58
|
+
protocol: 'HANDOFF',
|
|
59
|
+
protocolVersion: 'handoffprobe-p1-v1',
|
|
60
|
+
boundary: 'handoff-authorization -> mcp',
|
|
61
|
+
event: 'p1.authorization.blocked',
|
|
62
|
+
context: translatedContext,
|
|
63
|
+
details: {
|
|
64
|
+
scenarioId: this.scenario.id,
|
|
65
|
+
delegationId: this.scenario.delegation.id,
|
|
66
|
+
reasons: decision.reasons,
|
|
67
|
+
sideEffectCounterBefore: 0,
|
|
68
|
+
sideEffectCounterAfter: 0,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
originalContext,
|
|
73
|
+
translatedContext,
|
|
74
|
+
evidence: recorder.events,
|
|
75
|
+
output: {
|
|
76
|
+
scenarioId: this.scenario.id,
|
|
77
|
+
fixture: this.fixture,
|
|
78
|
+
delegationId: this.scenario.delegation.id,
|
|
79
|
+
logicalTime: this.scenario.logicalTime,
|
|
80
|
+
decision,
|
|
81
|
+
executed: false,
|
|
82
|
+
sideEffectCounterBefore: 0,
|
|
83
|
+
sideEffectCounterAfter: 0,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (!decision.allowed) {
|
|
88
|
+
recorder.record({
|
|
89
|
+
protocol: 'HANDOFF',
|
|
90
|
+
protocolVersion: 'handoffprobe-p1-v1',
|
|
91
|
+
boundary: 'handoff-authorization -> mcp',
|
|
92
|
+
event: 'p1.authorization.bypassed',
|
|
93
|
+
context: translatedContext,
|
|
94
|
+
details: {
|
|
95
|
+
scenarioId: this.scenario.id,
|
|
96
|
+
delegationId: this.scenario.delegation.id,
|
|
97
|
+
reasons: decision.reasons,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/*
|
|
102
|
+
* The inner P0 target always uses its
|
|
103
|
+
* secure enforcement mode.
|
|
104
|
+
*
|
|
105
|
+
* This is important: P1 is testing the
|
|
106
|
+
* missing cross-boundary expiry/lineage
|
|
107
|
+
* protection, not disabling the already
|
|
108
|
+
* working P0 authorization checks.
|
|
109
|
+
*/
|
|
110
|
+
const downstream = new P0TargetAdapter('secure', this.scenario.p0Scenario);
|
|
111
|
+
const inner = await downstream.execute(input);
|
|
112
|
+
const p0Output = inner.output;
|
|
113
|
+
const before = p0Output.mcpResult.envelope.before.sideEffectCounter;
|
|
114
|
+
const after = p0Output.mcpResult.envelope.after.sideEffectCounter;
|
|
115
|
+
const offset = recorder.events.length;
|
|
116
|
+
const innerEvidence = inner.evidence.map((event, index) => ({
|
|
117
|
+
...event,
|
|
118
|
+
sequence: offset + index + 1,
|
|
119
|
+
fixture: this.fixture,
|
|
120
|
+
}));
|
|
121
|
+
if (input.signal.aborted) {
|
|
122
|
+
throw new Error('P1 execution was aborted.');
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
originalContext,
|
|
126
|
+
translatedContext: cloneSecurityContext(inner.translatedContext),
|
|
127
|
+
evidence: [...recorder.events, ...innerEvidence],
|
|
128
|
+
output: {
|
|
129
|
+
scenarioId: this.scenario.id,
|
|
130
|
+
fixture: this.fixture,
|
|
131
|
+
delegationId: this.scenario.delegation.id,
|
|
132
|
+
logicalTime: this.scenario.logicalTime,
|
|
133
|
+
decision,
|
|
134
|
+
executed: p0Output.mcpResult.envelope.authorization.executed,
|
|
135
|
+
sideEffectCounterBefore: before,
|
|
136
|
+
sideEffectCounterAfter: after,
|
|
137
|
+
p0Output,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=target-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target-adapter.js","sourceRoot":"","sources":["../../src/p1-fixture/target-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type AgentExecutor, type ExecutionEventBus, type RequestContext } from '@a2a-js/sdk/server';
|
|
2
|
+
import type { HandoffAdapter } from '../../core/index.js';
|
|
3
|
+
import type { EvidenceRecorder } from '../evidence.js';
|
|
4
|
+
import type { LabRunState } from '../models.js';
|
|
5
|
+
export declare class HandoffLabExecutor implements AgentExecutor {
|
|
6
|
+
private readonly handoffAdapter;
|
|
7
|
+
private readonly recorder;
|
|
8
|
+
private readonly state;
|
|
9
|
+
constructor(handoffAdapter: HandoffAdapter, recorder: EvidenceRecorder, state: LabRunState);
|
|
10
|
+
execute(requestContext: RequestContext, eventBus: ExecutionEventBus): Promise<void>;
|
|
11
|
+
cancelTask(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/protocol-lab/a2a/executor.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,cAAc,CAAC;AA8DjE,qBAAa,kBAAmB,YAAW,aAAa;IAEpD,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAFL,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,WAAW;IAG/B,OAAO,CAAC,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+DzF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Role } from '@a2a-js/sdk';
|
|
2
|
+
import { AgentEvent, } from '@a2a-js/sdk/server';
|
|
3
|
+
import { callReadInvoiceThroughMcp } from '../mcp/harness.js';
|
|
4
|
+
function readContext(value) {
|
|
5
|
+
if (typeof value === 'object' &&
|
|
6
|
+
value !== null &&
|
|
7
|
+
'principal' in value &&
|
|
8
|
+
'caller' in value &&
|
|
9
|
+
'downstream' in value &&
|
|
10
|
+
'tenant' in value &&
|
|
11
|
+
'resource' in value &&
|
|
12
|
+
'capabilities' in value) {
|
|
13
|
+
const candidate = value;
|
|
14
|
+
if (typeof candidate.principal === 'string' &&
|
|
15
|
+
typeof candidate.caller === 'string' &&
|
|
16
|
+
typeof candidate.downstream === 'string' &&
|
|
17
|
+
typeof candidate.tenant === 'string' &&
|
|
18
|
+
typeof candidate.resource === 'string' &&
|
|
19
|
+
Array.isArray(candidate.capabilities) &&
|
|
20
|
+
candidate.capabilities.every((item) => typeof item === 'string')) {
|
|
21
|
+
return {
|
|
22
|
+
principal: candidate.principal,
|
|
23
|
+
caller: candidate.caller,
|
|
24
|
+
downstream: candidate.downstream,
|
|
25
|
+
tenant: candidate.tenant,
|
|
26
|
+
resource: candidate.resource,
|
|
27
|
+
capabilities: [...candidate.capabilities],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new Error('A2A request does not contain a valid HandoffProbe security context.');
|
|
32
|
+
}
|
|
33
|
+
function createTextMessage(messageId, contextId, text) {
|
|
34
|
+
return {
|
|
35
|
+
messageId,
|
|
36
|
+
contextId,
|
|
37
|
+
taskId: '',
|
|
38
|
+
role: Role.ROLE_AGENT,
|
|
39
|
+
metadata: undefined,
|
|
40
|
+
extensions: [],
|
|
41
|
+
referenceTaskIds: [],
|
|
42
|
+
parts: [
|
|
43
|
+
{
|
|
44
|
+
content: {
|
|
45
|
+
$case: 'text',
|
|
46
|
+
value: text,
|
|
47
|
+
},
|
|
48
|
+
mediaType: 'application/json',
|
|
49
|
+
filename: '',
|
|
50
|
+
metadata: undefined,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export class HandoffLabExecutor {
|
|
56
|
+
handoffAdapter;
|
|
57
|
+
recorder;
|
|
58
|
+
state;
|
|
59
|
+
constructor(handoffAdapter, recorder, state) {
|
|
60
|
+
this.handoffAdapter = handoffAdapter;
|
|
61
|
+
this.recorder = recorder;
|
|
62
|
+
this.state = state;
|
|
63
|
+
}
|
|
64
|
+
async execute(requestContext, eventBus) {
|
|
65
|
+
const original = readContext(requestContext.request.metadata?.handoffprobeContext);
|
|
66
|
+
this.recorder.record({
|
|
67
|
+
protocol: 'A2A',
|
|
68
|
+
protocolVersion: '1.0',
|
|
69
|
+
boundary: 'a2a-rest -> agent-executor',
|
|
70
|
+
event: 'a2a.receiver.receive',
|
|
71
|
+
context: original,
|
|
72
|
+
details: {
|
|
73
|
+
messageId: requestContext.userMessage.messageId,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
const translated = await this.handoffAdapter.translate(original);
|
|
77
|
+
this.state.translatedContext = translated;
|
|
78
|
+
this.recorder.record({
|
|
79
|
+
protocol: 'HANDOFF',
|
|
80
|
+
protocolVersion: 'handoffprobe-v1',
|
|
81
|
+
boundary: 'a2a-receiver -> mcp-client',
|
|
82
|
+
event: 'handoff.translate',
|
|
83
|
+
context: translated,
|
|
84
|
+
details: {
|
|
85
|
+
originalPrincipal: original.principal,
|
|
86
|
+
translatedPrincipal: translated.principal,
|
|
87
|
+
fixture: this.recorder.fixture,
|
|
88
|
+
handoffAdapter: this.handoffAdapter.id,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
const mcp = await callReadInvoiceThroughMcp(translated, this.recorder);
|
|
92
|
+
this.state.mcpEra = mcp.era;
|
|
93
|
+
this.state.toolResult = mcp.result;
|
|
94
|
+
const responseText = JSON.stringify(mcp.result);
|
|
95
|
+
this.recorder.record({
|
|
96
|
+
protocol: 'A2A',
|
|
97
|
+
protocolVersion: '1.0',
|
|
98
|
+
boundary: 'agent-executor -> a2a-rest',
|
|
99
|
+
event: 'a2a.receiver.respond',
|
|
100
|
+
context: translated,
|
|
101
|
+
details: {
|
|
102
|
+
invoiceId: mcp.result.invoiceId,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
eventBus.publish(AgentEvent.message(createTextMessage(`${this.recorder.runId}-response`, requestContext.contextId, responseText)));
|
|
106
|
+
eventBus.finished();
|
|
107
|
+
}
|
|
108
|
+
cancelTask() {
|
|
109
|
+
return Promise.resolve();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/protocol-lab/a2a/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HandoffAdapter } from '../../core/index.js';
|
|
2
|
+
import type { EvidenceRecorder } from '../evidence.js';
|
|
3
|
+
import type { FixtureMode, LabRunState, SecurityContext } from '../models.js';
|
|
4
|
+
export declare function executeA2aFixture(input: {
|
|
5
|
+
fixture: FixtureMode;
|
|
6
|
+
recorder: EvidenceRecorder;
|
|
7
|
+
state: LabRunState;
|
|
8
|
+
context: SecurityContext;
|
|
9
|
+
handoffAdapter: HandoffAdapter;
|
|
10
|
+
}): Promise<string>;
|
|
11
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/protocol-lab/a2a/harness.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAuG9E,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;CAChC,GAAG,OAAO,CAAC,MAAM,CAAC,CAsFlB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { once } from 'node:events';
|
|
2
|
+
import { Role } from '@a2a-js/sdk';
|
|
3
|
+
import { ClientFactory, RestTransportFactory } from '@a2a-js/sdk/client';
|
|
4
|
+
import { DefaultRequestHandler, InMemoryTaskStore } from '@a2a-js/sdk/server';
|
|
5
|
+
import { agentCardHandler, restHandler, UserBuilder } from '@a2a-js/sdk/server/express';
|
|
6
|
+
import express from 'express';
|
|
7
|
+
import { HandoffLabExecutor } from './executor.js';
|
|
8
|
+
function createAgentCard(restUrl) {
|
|
9
|
+
return {
|
|
10
|
+
name: 'HandoffProbe Protocol Lab Receiver',
|
|
11
|
+
description: 'Local deterministic A2A receiver used by HandoffProbe protocol fixtures.',
|
|
12
|
+
provider: undefined,
|
|
13
|
+
version: '0.0.0',
|
|
14
|
+
capabilities: {
|
|
15
|
+
streaming: false,
|
|
16
|
+
pushNotifications: false,
|
|
17
|
+
extensions: [],
|
|
18
|
+
},
|
|
19
|
+
defaultInputModes: ['application/json'],
|
|
20
|
+
defaultOutputModes: ['application/json'],
|
|
21
|
+
skills: [
|
|
22
|
+
{
|
|
23
|
+
id: 'handoff-read-invoice',
|
|
24
|
+
name: 'Handoff fake invoice read',
|
|
25
|
+
description: 'Translates A2A security context into a local MCP fake-tool request.',
|
|
26
|
+
tags: ['handoff', 'security', 'fixture'],
|
|
27
|
+
examples: [],
|
|
28
|
+
inputModes: ['application/json'],
|
|
29
|
+
outputModes: ['application/json'],
|
|
30
|
+
securityRequirements: [],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
securitySchemes: {},
|
|
34
|
+
securityRequirements: [],
|
|
35
|
+
supportedInterfaces: [
|
|
36
|
+
{
|
|
37
|
+
url: restUrl,
|
|
38
|
+
protocolBinding: 'HTTP+JSON',
|
|
39
|
+
protocolVersion: '1.0',
|
|
40
|
+
tenant: '',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
signatures: [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function createRequest(runId, context) {
|
|
47
|
+
return {
|
|
48
|
+
tenant: '',
|
|
49
|
+
message: {
|
|
50
|
+
messageId: `${runId}-request`,
|
|
51
|
+
contextId: `${runId}-context`,
|
|
52
|
+
taskId: '',
|
|
53
|
+
role: Role.ROLE_USER,
|
|
54
|
+
metadata: undefined,
|
|
55
|
+
extensions: [],
|
|
56
|
+
referenceTaskIds: [],
|
|
57
|
+
parts: [
|
|
58
|
+
{
|
|
59
|
+
content: {
|
|
60
|
+
$case: 'text',
|
|
61
|
+
value: 'Read the authorized invoice.',
|
|
62
|
+
},
|
|
63
|
+
mediaType: 'text/plain',
|
|
64
|
+
filename: '',
|
|
65
|
+
metadata: undefined,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
configuration: undefined,
|
|
70
|
+
metadata: {
|
|
71
|
+
handoffprobeContext: {
|
|
72
|
+
...context,
|
|
73
|
+
capabilities: [...context.capabilities],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function closeServer(server) {
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
server.close((error) => {
|
|
81
|
+
if (error === undefined) {
|
|
82
|
+
resolve();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
reject(error);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function extractMessageText(result) {
|
|
91
|
+
if ('messageId' in result) {
|
|
92
|
+
const part = result.parts[0];
|
|
93
|
+
if (part?.content?.$case === 'text') {
|
|
94
|
+
return part.content.value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw new Error('Expected A2A receiver to return a direct Message.');
|
|
98
|
+
}
|
|
99
|
+
export async function executeA2aFixture(input) {
|
|
100
|
+
const app = express();
|
|
101
|
+
const server = app.listen(0, '127.0.0.1');
|
|
102
|
+
await once(server, 'listening');
|
|
103
|
+
const address = server.address();
|
|
104
|
+
if (address === null || typeof address === 'string') {
|
|
105
|
+
await closeServer(server);
|
|
106
|
+
throw new Error('Unable to determine A2A loopback port.');
|
|
107
|
+
}
|
|
108
|
+
const baseUrl = `http://127.0.0.1:${address.port}`;
|
|
109
|
+
const agentCard = createAgentCard(`${baseUrl}/a2a`);
|
|
110
|
+
const executor = new HandoffLabExecutor(input.handoffAdapter, input.recorder, input.state);
|
|
111
|
+
const requestHandler = new DefaultRequestHandler(agentCard, new InMemoryTaskStore(), executor);
|
|
112
|
+
app.use(express.json());
|
|
113
|
+
app.use('/.well-known/agent-card.json', agentCardHandler({
|
|
114
|
+
agentCardProvider: requestHandler,
|
|
115
|
+
}));
|
|
116
|
+
app.use('/a2a', restHandler({
|
|
117
|
+
requestHandler,
|
|
118
|
+
userBuilder: UserBuilder.noAuthentication,
|
|
119
|
+
}));
|
|
120
|
+
try {
|
|
121
|
+
const factory = new ClientFactory({
|
|
122
|
+
transports: [new RestTransportFactory()],
|
|
123
|
+
preferredTransports: ['HTTP+JSON'],
|
|
124
|
+
});
|
|
125
|
+
const client = await factory.createFromAgentCard(agentCard);
|
|
126
|
+
input.recorder.record({
|
|
127
|
+
protocol: 'A2A',
|
|
128
|
+
protocolVersion: '1.0',
|
|
129
|
+
boundary: 'fixture-client -> a2a-rest',
|
|
130
|
+
event: 'a2a.client.send',
|
|
131
|
+
context: input.context,
|
|
132
|
+
details: {
|
|
133
|
+
binding: 'HTTP+JSON',
|
|
134
|
+
transport: 'loopback-http',
|
|
135
|
+
path: '/a2a',
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
const response = await client.sendMessage(createRequest(input.recorder.runId, input.context));
|
|
139
|
+
const responseText = extractMessageText(response);
|
|
140
|
+
const responseContext = input.state.translatedContext;
|
|
141
|
+
if (responseContext === undefined) {
|
|
142
|
+
throw new Error('A2A executor did not persist translated context.');
|
|
143
|
+
}
|
|
144
|
+
input.recorder.record({
|
|
145
|
+
protocol: 'A2A',
|
|
146
|
+
protocolVersion: '1.0',
|
|
147
|
+
boundary: 'a2a-rest -> fixture-client',
|
|
148
|
+
event: 'a2a.client.receive',
|
|
149
|
+
context: responseContext,
|
|
150
|
+
details: {
|
|
151
|
+
responseType: 'message',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
return responseText;
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
await closeServer(server);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../src/protocol-lab/a2a/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EvidenceEvent, FixtureMode, SecurityContext } from './models.js';
|
|
2
|
+
export declare class EvidenceRecorder {
|
|
3
|
+
readonly runId: string;
|
|
4
|
+
readonly fixture: FixtureMode;
|
|
5
|
+
readonly events: EvidenceEvent[];
|
|
6
|
+
readonly correlationId: string;
|
|
7
|
+
constructor(runId: string, fixture: FixtureMode, correlationId?: string);
|
|
8
|
+
record(input: {
|
|
9
|
+
protocol: EvidenceEvent['protocol'];
|
|
10
|
+
protocolVersion: string;
|
|
11
|
+
boundary: string;
|
|
12
|
+
event: string;
|
|
13
|
+
context: SecurityContext;
|
|
14
|
+
details?: Record<string, unknown>;
|
|
15
|
+
}): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/protocol-lab/evidence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE/E,qBAAa,gBAAgB;IAMzB,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,OAAO,EAAE,WAAW;IAN/B,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAM;IAEtC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAGpB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EAC7B,aAAa,CAAC,EAAE,MAAM;IAKxB,MAAM,CAAC,KAAK,EAAE;QACZ,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;QACpC,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,eAAe,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,GAAG,IAAI;CAeT"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cloneSecurityContext, redactRecord } from '../core/index.js';
|
|
2
|
+
export class EvidenceRecorder {
|
|
3
|
+
runId;
|
|
4
|
+
fixture;
|
|
5
|
+
events = [];
|
|
6
|
+
correlationId;
|
|
7
|
+
constructor(runId, fixture, correlationId) {
|
|
8
|
+
this.runId = runId;
|
|
9
|
+
this.fixture = fixture;
|
|
10
|
+
this.correlationId = correlationId ?? runId;
|
|
11
|
+
}
|
|
12
|
+
record(input) {
|
|
13
|
+
this.events.push({
|
|
14
|
+
runId: this.runId,
|
|
15
|
+
correlationId: this.correlationId,
|
|
16
|
+
sequence: this.events.length + 1,
|
|
17
|
+
fixture: this.fixture,
|
|
18
|
+
protocol: input.protocol,
|
|
19
|
+
protocolVersion: input.protocolVersion,
|
|
20
|
+
boundary: input.boundary,
|
|
21
|
+
event: input.event,
|
|
22
|
+
context: cloneSecurityContext(input.context),
|
|
23
|
+
details: redactRecord(input.details ?? {}),
|
|
24
|
+
provenance: [],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/protocol-lab/evidence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGtE,MAAM,OAAO,gBAAgB;IAMhB;IACA;IANF,MAAM,GAAoB,EAAE,CAAC;IAE7B,aAAa,CAAS;IAE/B,YACW,KAAa,EACb,OAAoB,EAC7B,aAAsB;QAFb,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAa;QAG7B,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,KAAK,CAAC;IAC9C,CAAC;IAED,MAAM,CAAC,KAON;QACC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YAChC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC;YAC5C,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;YAC1C,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HandoffAdapter } from '../core/index.js';
|
|
2
|
+
import type { FixtureMode, ProtocolLabResult, SecurityContext } from './models.js';
|
|
3
|
+
export declare const REFERENCE_CONTEXT: SecurityContext;
|
|
4
|
+
export interface ProtocolFixtureOptions {
|
|
5
|
+
runId?: string;
|
|
6
|
+
correlationId?: string;
|
|
7
|
+
context?: SecurityContext;
|
|
8
|
+
handoffAdapter?: HandoffAdapter;
|
|
9
|
+
}
|
|
10
|
+
export declare function runProtocolFixture(fixture: FixtureMode, options?: ProtocolFixtureOptions): Promise<ProtocolLabResult>;
|
|
11
|
+
//# sourceMappingURL=fixture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture.d.ts","sourceRoot":"","sources":["../../src/protocol-lab/fixture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,KAAK,EAAE,WAAW,EAAe,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEhG,eAAO,MAAM,iBAAiB,EAAE,eAO/B,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAMD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAiD5B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { cloneSecurityContext } from '../core/index.js';
|
|
2
|
+
import { executeA2aFixture } from './a2a/harness.js';
|
|
3
|
+
import { EvidenceRecorder } from './evidence.js';
|
|
4
|
+
import { ProtocolLabHandoffAdapter } from './handoff/adapter.js';
|
|
5
|
+
export const REFERENCE_CONTEXT = {
|
|
6
|
+
principal: 'user:alice',
|
|
7
|
+
caller: 'agent:sales',
|
|
8
|
+
downstream: 'agent:billing',
|
|
9
|
+
tenant: 'tenant:acme',
|
|
10
|
+
resource: 'invoice:INV-1001',
|
|
11
|
+
capabilities: ['invoice.read'],
|
|
12
|
+
};
|
|
13
|
+
function defaultRunId(fixture) {
|
|
14
|
+
return fixture === 'secure' ? 'hp-lab-secure-001' : 'hp-lab-vulnerable-001';
|
|
15
|
+
}
|
|
16
|
+
export async function runProtocolFixture(fixture, options = {}) {
|
|
17
|
+
const runId = options.runId ?? defaultRunId(fixture);
|
|
18
|
+
const correlationId = options.correlationId ?? runId;
|
|
19
|
+
const context = cloneSecurityContext(options.context ?? REFERENCE_CONTEXT);
|
|
20
|
+
const recorder = new EvidenceRecorder(runId, fixture, correlationId);
|
|
21
|
+
const state = {};
|
|
22
|
+
const handoffAdapter = options.handoffAdapter ?? new ProtocolLabHandoffAdapter(fixture);
|
|
23
|
+
const responseText = await executeA2aFixture({
|
|
24
|
+
fixture,
|
|
25
|
+
recorder,
|
|
26
|
+
state,
|
|
27
|
+
context,
|
|
28
|
+
handoffAdapter,
|
|
29
|
+
});
|
|
30
|
+
const translatedContext = state.translatedContext;
|
|
31
|
+
const toolResult = state.toolResult;
|
|
32
|
+
if (translatedContext === undefined) {
|
|
33
|
+
throw new Error('Fixture produced no translated context.');
|
|
34
|
+
}
|
|
35
|
+
if (toolResult === undefined) {
|
|
36
|
+
throw new Error('Fixture produced no fake-tool result.');
|
|
37
|
+
}
|
|
38
|
+
if (state.mcpEra === 'modern') {
|
|
39
|
+
return {
|
|
40
|
+
runId,
|
|
41
|
+
fixture,
|
|
42
|
+
a2aProtocolVersion: '1.0',
|
|
43
|
+
mcpProtocolVersion: '2026-07-28',
|
|
44
|
+
mcpEra: state.mcpEra,
|
|
45
|
+
originalContext: context,
|
|
46
|
+
translatedContext,
|
|
47
|
+
toolResult,
|
|
48
|
+
responseText,
|
|
49
|
+
evidence: recorder.events,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`Fixture did not negotiate modern MCP era: ${String(state.mcpEra)}`);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=fixture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture.js","sourceRoot":"","sources":["../../src/protocol-lab/fixture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,MAAM,CAAC,MAAM,iBAAiB,GAAoB;IAChD,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,aAAa;IACrB,UAAU,EAAE,eAAe;IAC3B,MAAM,EAAE,aAAa;IACrB,QAAQ,EAAE,kBAAkB;IAC5B,YAAY,EAAE,CAAC,cAAc,CAAC;CAC/B,CAAC;AASF,SAAS,YAAY,CAAC,OAAoB;IACxC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,uBAAuB,CAAC;AAC9E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAoB,EACpB,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAErD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC;IAErD,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,OAAO,IAAI,iBAAiB,CAAC,CAAC;IAE3E,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAErE,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAExF,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC;QAC3C,OAAO;QACP,QAAQ;QACR,KAAK;QACL,OAAO;QACP,cAAc;KACf,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAElD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IAEpC,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO;YACL,KAAK;YACL,OAAO;YACP,kBAAkB,EAAE,KAAK;YACzB,kBAAkB,EAAE,YAAY;YAChC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,eAAe,EAAE,OAAO;YACxB,iBAAiB;YACjB,UAAU;YACV,YAAY;YACZ,QAAQ,EAAE,QAAQ,CAAC,MAAM;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,6CAA6C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HandoffAdapter, SecurityContext } from '../../core/index.js';
|
|
2
|
+
import type { FixtureMode } from '../models.js';
|
|
3
|
+
export declare class ProtocolLabHandoffAdapter implements HandoffAdapter {
|
|
4
|
+
readonly fixture: FixtureMode;
|
|
5
|
+
readonly id: string;
|
|
6
|
+
constructor(fixture: FixtureMode);
|
|
7
|
+
translate(context: SecurityContext): SecurityContext;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/protocol-lab/handoff/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,qBAAa,yBAA0B,YAAW,cAAc;IAGlD,QAAQ,CAAC,OAAO,EAAE,WAAW;IAFzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAEC,OAAO,EAAE,WAAW;IAIzC,SAAS,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe;CAGrD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { translateSecurityContext } from './translate.js';
|
|
2
|
+
export class ProtocolLabHandoffAdapter {
|
|
3
|
+
fixture;
|
|
4
|
+
id;
|
|
5
|
+
constructor(fixture) {
|
|
6
|
+
this.fixture = fixture;
|
|
7
|
+
this.id = `protocol-lab-handoff:${fixture}`;
|
|
8
|
+
}
|
|
9
|
+
translate(context) {
|
|
10
|
+
return translateSecurityContext(context, this.fixture);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/protocol-lab/handoff/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,OAAO,yBAAyB;IAGf;IAFZ,EAAE,CAAS;IAEpB,YAAqB,OAAoB;QAApB,YAAO,GAAP,OAAO,CAAa;QACvC,IAAI,CAAC,EAAE,GAAG,wBAAwB,OAAO,EAAE,CAAC;IAC9C,CAAC;IAED,SAAS,CAAC,OAAwB;QAChC,OAAO,wBAAwB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../../src/protocol-lab/handoff/translate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEjE,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,WAAW,GACnB,eAAe,CAajB"}
|