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,322 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
+
import * as z from 'zod/v4';
|
|
3
|
+
import { evaluateP0Authorization } from '../authorization.js';
|
|
4
|
+
import { P0_CAPABILITY_READ, P0_CAPABILITY_REFUND, P0_CAPABILITY_UPDATE } from '../constants.js';
|
|
5
|
+
import { hashApprovalPayload } from '../payload-hash.js';
|
|
6
|
+
import { recordSyntheticEmail, recordSyntheticRefund, snapshotP0FixtureState, updateSyntheticInvoice, } from '../state.js';
|
|
7
|
+
const SEND_EMAIL_CAPABILITY = 'message.send';
|
|
8
|
+
const readInvoiceSchema = z.object({
|
|
9
|
+
resource: z.string(),
|
|
10
|
+
});
|
|
11
|
+
const updateInvoiceSchema = z.object({
|
|
12
|
+
resource: z.string(),
|
|
13
|
+
amountCents: z.number().int(),
|
|
14
|
+
});
|
|
15
|
+
const refundPaymentSchema = z.object({
|
|
16
|
+
resource: z.string(),
|
|
17
|
+
amount: z.number(),
|
|
18
|
+
recipient: z.string(),
|
|
19
|
+
approvalId: z.string(),
|
|
20
|
+
});
|
|
21
|
+
const sendEmailSchema = z.object({
|
|
22
|
+
resource: z.string(),
|
|
23
|
+
recipient: z.string(),
|
|
24
|
+
subject: z.string(),
|
|
25
|
+
});
|
|
26
|
+
function requiredCapability(tool) {
|
|
27
|
+
switch (tool) {
|
|
28
|
+
case 'read_invoice':
|
|
29
|
+
return P0_CAPABILITY_READ;
|
|
30
|
+
case 'update_invoice':
|
|
31
|
+
return P0_CAPABILITY_UPDATE;
|
|
32
|
+
case 'refund_payment':
|
|
33
|
+
return P0_CAPABILITY_REFUND;
|
|
34
|
+
case 'send_email':
|
|
35
|
+
return SEND_EMAIL_CAPABILITY;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function approvalMatches(context, tool, payload, approvalId) {
|
|
39
|
+
if (tool !== 'refund_payment') {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const approval = context.approval;
|
|
43
|
+
if (approval === undefined || approvalId === undefined) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return (approval.approvalId === approvalId &&
|
|
47
|
+
approval.tool === tool &&
|
|
48
|
+
approval.payloadHash === hashApprovalPayload(payload));
|
|
49
|
+
}
|
|
50
|
+
function buildAuthorization(input) {
|
|
51
|
+
const capability = requiredCapability(input.tool);
|
|
52
|
+
const decision = evaluateP0Authorization(input.context, {
|
|
53
|
+
principal: input.context.principal,
|
|
54
|
+
downstream: input.context.downstream,
|
|
55
|
+
tenant: input.context.tenant,
|
|
56
|
+
resource: input.resource,
|
|
57
|
+
capability,
|
|
58
|
+
tool: input.tool,
|
|
59
|
+
});
|
|
60
|
+
const semanticBindingMatches = input.context.capabilities.includes(capability);
|
|
61
|
+
const approval = approvalMatches(input.context, input.tool, input.approvalPayload, input.approvalId);
|
|
62
|
+
const forwardedCredential = input.context.forwardedCredential;
|
|
63
|
+
const credentialAudienceMatches = forwardedCredential === undefined
|
|
64
|
+
? null
|
|
65
|
+
: forwardedCredential.audience === input.downstreamAudience;
|
|
66
|
+
const credentialAccepted = forwardedCredential !== undefined &&
|
|
67
|
+
(credentialAudienceMatches === true || input.mode === 'bypass');
|
|
68
|
+
const reasons = [...decision.reasons];
|
|
69
|
+
if (!semanticBindingMatches) {
|
|
70
|
+
reasons.push('tool_capability_semantic_mismatch');
|
|
71
|
+
}
|
|
72
|
+
if (credentialAudienceMatches === false) {
|
|
73
|
+
reasons.push('credential_audience_mismatch');
|
|
74
|
+
}
|
|
75
|
+
if (approval === false) {
|
|
76
|
+
reasons.push('approval_binding_mismatch');
|
|
77
|
+
}
|
|
78
|
+
const invariantAllowed = decision.allowed &&
|
|
79
|
+
semanticBindingMatches &&
|
|
80
|
+
approval !== false &&
|
|
81
|
+
credentialAudienceMatches !== false;
|
|
82
|
+
const executed = invariantAllowed || input.mode === 'bypass';
|
|
83
|
+
return {
|
|
84
|
+
policyMode: input.mode,
|
|
85
|
+
invariantAllowed,
|
|
86
|
+
executed,
|
|
87
|
+
decision,
|
|
88
|
+
approvalMatches: approval,
|
|
89
|
+
semanticBindingMatches,
|
|
90
|
+
downstreamAudience: input.downstreamAudience,
|
|
91
|
+
credentialForwarded: forwardedCredential !== undefined,
|
|
92
|
+
credentialAudienceMatches,
|
|
93
|
+
credentialAccepted,
|
|
94
|
+
reasons,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function recordAuthorization(recorder, context, input) {
|
|
98
|
+
recorder.record({
|
|
99
|
+
protocol: 'TOOL',
|
|
100
|
+
protocolVersion: 'local-p0-fixture-v1',
|
|
101
|
+
boundary: 'mcp-server -> p0-authorization',
|
|
102
|
+
event: 'p0.authorization',
|
|
103
|
+
context,
|
|
104
|
+
details: {
|
|
105
|
+
selectedTool: input.tool,
|
|
106
|
+
requestedCapability: input.capability,
|
|
107
|
+
targetResource: input.resource,
|
|
108
|
+
upstreamAuthority: context.upstreamAuthority,
|
|
109
|
+
translatedAuthority: context.effectiveAuthority,
|
|
110
|
+
authorizationResult: input.authorization.invariantAllowed,
|
|
111
|
+
executed: input.authorization.executed,
|
|
112
|
+
policyMode: input.authorization.policyMode,
|
|
113
|
+
authorizationReasons: input.authorization.reasons,
|
|
114
|
+
approvalMatches: input.authorization.approvalMatches,
|
|
115
|
+
semanticBindingMatches: input.authorization.semanticBindingMatches,
|
|
116
|
+
downstreamAudience: input.authorization.downstreamAudience,
|
|
117
|
+
credentialFingerprint: context.forwardedCredential?.fingerprint,
|
|
118
|
+
credentialClass: context.forwardedCredential?.credentialClass,
|
|
119
|
+
credentialAudience: context.forwardedCredential?.audience,
|
|
120
|
+
credentialForwarded: input.authorization.credentialForwarded,
|
|
121
|
+
credentialAudienceMatches: input.authorization.credentialAudienceMatches,
|
|
122
|
+
credentialAccepted: input.authorization.credentialAccepted,
|
|
123
|
+
sideEffectStateBefore: input.before,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function recordResult(recorder, context, envelope) {
|
|
128
|
+
recorder.record({
|
|
129
|
+
protocol: 'TOOL',
|
|
130
|
+
protocolVersion: 'local-p0-fixture-v1',
|
|
131
|
+
boundary: 'p0-tool -> mcp-server',
|
|
132
|
+
event: 'p0.tool.result',
|
|
133
|
+
context,
|
|
134
|
+
details: {
|
|
135
|
+
selectedTool: envelope.tool,
|
|
136
|
+
authorizationResult: envelope.authorization.invariantAllowed,
|
|
137
|
+
executed: envelope.authorization.executed,
|
|
138
|
+
sideEffectStateBefore: envelope.before,
|
|
139
|
+
sideEffectStateAfter: envelope.after,
|
|
140
|
+
output: envelope.output,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function textResult(envelope) {
|
|
145
|
+
return {
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: 'text',
|
|
149
|
+
text: JSON.stringify(envelope),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export function createP0FakeToolServer(recorder, context, state, era, mode, downstreamAudience) {
|
|
155
|
+
const server = new McpServer({
|
|
156
|
+
name: 'handoffprobe-p0-fixture-mcp',
|
|
157
|
+
version: '0.0.0',
|
|
158
|
+
});
|
|
159
|
+
server.registerTool('read_invoice', {
|
|
160
|
+
title: 'Read synthetic invoice',
|
|
161
|
+
description: 'Reads deterministic in-memory invoice data.',
|
|
162
|
+
inputSchema: readInvoiceSchema,
|
|
163
|
+
}, ({ resource }) => {
|
|
164
|
+
const before = snapshotP0FixtureState(state);
|
|
165
|
+
const authorization = buildAuthorization({
|
|
166
|
+
context,
|
|
167
|
+
tool: 'read_invoice',
|
|
168
|
+
resource,
|
|
169
|
+
mode,
|
|
170
|
+
downstreamAudience,
|
|
171
|
+
});
|
|
172
|
+
recordAuthorization(recorder, context, {
|
|
173
|
+
tool: 'read_invoice',
|
|
174
|
+
resource,
|
|
175
|
+
capability: P0_CAPABILITY_READ,
|
|
176
|
+
authorization,
|
|
177
|
+
before,
|
|
178
|
+
});
|
|
179
|
+
const invoice = authorization.executed ? (state.invoices[resource] ?? null) : null;
|
|
180
|
+
const after = snapshotP0FixtureState(state);
|
|
181
|
+
const envelope = {
|
|
182
|
+
tool: 'read_invoice',
|
|
183
|
+
authorization,
|
|
184
|
+
before,
|
|
185
|
+
after,
|
|
186
|
+
output: {
|
|
187
|
+
invoice,
|
|
188
|
+
mcpEra: era,
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
recordResult(recorder, context, envelope);
|
|
192
|
+
return textResult(envelope);
|
|
193
|
+
});
|
|
194
|
+
server.registerTool('update_invoice', {
|
|
195
|
+
title: 'Update synthetic invoice',
|
|
196
|
+
description: 'Updates only deterministic in-memory invoice data.',
|
|
197
|
+
inputSchema: updateInvoiceSchema,
|
|
198
|
+
}, ({ resource, amountCents }) => {
|
|
199
|
+
const before = snapshotP0FixtureState(state);
|
|
200
|
+
const authorization = buildAuthorization({
|
|
201
|
+
context,
|
|
202
|
+
tool: 'update_invoice',
|
|
203
|
+
resource,
|
|
204
|
+
mode,
|
|
205
|
+
downstreamAudience,
|
|
206
|
+
});
|
|
207
|
+
recordAuthorization(recorder, context, {
|
|
208
|
+
tool: 'update_invoice',
|
|
209
|
+
resource,
|
|
210
|
+
capability: P0_CAPABILITY_UPDATE,
|
|
211
|
+
authorization,
|
|
212
|
+
before,
|
|
213
|
+
});
|
|
214
|
+
const invoice = authorization.executed
|
|
215
|
+
? updateSyntheticInvoice(state, resource, amountCents)
|
|
216
|
+
: null;
|
|
217
|
+
const after = snapshotP0FixtureState(state);
|
|
218
|
+
const envelope = {
|
|
219
|
+
tool: 'update_invoice',
|
|
220
|
+
authorization,
|
|
221
|
+
before,
|
|
222
|
+
after,
|
|
223
|
+
output: {
|
|
224
|
+
invoice,
|
|
225
|
+
mcpEra: era,
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
recordResult(recorder, context, envelope);
|
|
229
|
+
return textResult(envelope);
|
|
230
|
+
});
|
|
231
|
+
server.registerTool('refund_payment', {
|
|
232
|
+
title: 'Record synthetic refund',
|
|
233
|
+
description: 'Writes only to the deterministic in-memory refund ledger.',
|
|
234
|
+
inputSchema: refundPaymentSchema,
|
|
235
|
+
}, ({ resource, amount, recipient, approvalId }) => {
|
|
236
|
+
const before = snapshotP0FixtureState(state);
|
|
237
|
+
const payload = {
|
|
238
|
+
amount,
|
|
239
|
+
recipient,
|
|
240
|
+
};
|
|
241
|
+
const authorization = buildAuthorization({
|
|
242
|
+
context,
|
|
243
|
+
tool: 'refund_payment',
|
|
244
|
+
resource,
|
|
245
|
+
mode,
|
|
246
|
+
downstreamAudience,
|
|
247
|
+
approvalPayload: payload,
|
|
248
|
+
approvalId,
|
|
249
|
+
});
|
|
250
|
+
recordAuthorization(recorder, context, {
|
|
251
|
+
tool: 'refund_payment',
|
|
252
|
+
resource,
|
|
253
|
+
capability: P0_CAPABILITY_REFUND,
|
|
254
|
+
authorization,
|
|
255
|
+
before,
|
|
256
|
+
});
|
|
257
|
+
const refund = authorization.executed
|
|
258
|
+
? recordSyntheticRefund(state, {
|
|
259
|
+
amount,
|
|
260
|
+
recipient,
|
|
261
|
+
approvalId,
|
|
262
|
+
})
|
|
263
|
+
: null;
|
|
264
|
+
const after = snapshotP0FixtureState(state);
|
|
265
|
+
const envelope = {
|
|
266
|
+
tool: 'refund_payment',
|
|
267
|
+
authorization,
|
|
268
|
+
before,
|
|
269
|
+
after,
|
|
270
|
+
output: {
|
|
271
|
+
refund,
|
|
272
|
+
approvedPayloadHash: context.approval?.payloadHash,
|
|
273
|
+
executedPayloadHash: hashApprovalPayload(payload),
|
|
274
|
+
mcpEra: era,
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
recordResult(recorder, context, envelope);
|
|
278
|
+
return textResult(envelope);
|
|
279
|
+
});
|
|
280
|
+
server.registerTool('send_email', {
|
|
281
|
+
title: 'Record synthetic email',
|
|
282
|
+
description: 'Writes only to the deterministic in-memory outbox.',
|
|
283
|
+
inputSchema: sendEmailSchema,
|
|
284
|
+
}, ({ resource, recipient, subject }) => {
|
|
285
|
+
const before = snapshotP0FixtureState(state);
|
|
286
|
+
const authorization = buildAuthorization({
|
|
287
|
+
context,
|
|
288
|
+
tool: 'send_email',
|
|
289
|
+
resource,
|
|
290
|
+
mode,
|
|
291
|
+
downstreamAudience,
|
|
292
|
+
});
|
|
293
|
+
recordAuthorization(recorder, context, {
|
|
294
|
+
tool: 'send_email',
|
|
295
|
+
resource,
|
|
296
|
+
capability: SEND_EMAIL_CAPABILITY,
|
|
297
|
+
authorization,
|
|
298
|
+
before,
|
|
299
|
+
});
|
|
300
|
+
const message = authorization.executed
|
|
301
|
+
? recordSyntheticEmail(state, {
|
|
302
|
+
recipient,
|
|
303
|
+
subject,
|
|
304
|
+
})
|
|
305
|
+
: null;
|
|
306
|
+
const after = snapshotP0FixtureState(state);
|
|
307
|
+
const envelope = {
|
|
308
|
+
tool: 'send_email',
|
|
309
|
+
authorization,
|
|
310
|
+
before,
|
|
311
|
+
after,
|
|
312
|
+
output: {
|
|
313
|
+
message,
|
|
314
|
+
mcpEra: era,
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
recordResult(recorder, context, envelope);
|
|
318
|
+
return textResult(envelope);
|
|
319
|
+
});
|
|
320
|
+
return server;
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=fake-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-tools.js","sourceRoot":"","sources":["../../../src/p0-fixture/mcp/fake-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SecurityContext } from '../../core/index.js';
|
|
2
|
+
import type { EvidenceRecorder } from '../../protocol-lab/evidence.js';
|
|
3
|
+
import type { P0FixtureState } from '../state.js';
|
|
4
|
+
import type { P0EnforcementMode, P0McpExecutionResult, P0McpToolName } from './types.js';
|
|
5
|
+
export interface P0McpCallInput {
|
|
6
|
+
context: SecurityContext;
|
|
7
|
+
recorder: EvidenceRecorder;
|
|
8
|
+
state: P0FixtureState;
|
|
9
|
+
mode?: P0EnforcementMode;
|
|
10
|
+
audience?: string;
|
|
11
|
+
cancelLifecycleBeforeTool?: boolean;
|
|
12
|
+
tool: P0McpToolName;
|
|
13
|
+
arguments: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export declare function callP0ToolThroughMcp(input: P0McpCallInput): Promise<P0McpExecutionResult>;
|
|
16
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/p0-fixture/mcp/harness.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,EAEd,MAAM,YAAY,CAAC;AAmBpB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAEzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6I/F"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
|
|
2
|
+
import { createMcpHandler } from '@modelcontextprotocol/server';
|
|
3
|
+
import { P0_MCP_AUDIENCE } from '../constants.js';
|
|
4
|
+
import { createP0FakeToolServer } from './fake-tools.js';
|
|
5
|
+
function readTextContent(content) {
|
|
6
|
+
for (const block of content) {
|
|
7
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
8
|
+
return block.text;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
throw new Error('P0 MCP fake tool returned no text content.');
|
|
12
|
+
}
|
|
13
|
+
export async function callP0ToolThroughMcp(input) {
|
|
14
|
+
const mode = input.mode ?? 'enforce';
|
|
15
|
+
const downstreamAudience = input.audience ?? P0_MCP_AUDIENCE;
|
|
16
|
+
const handler = createMcpHandler(({ era }) => createP0FakeToolServer(input.recorder, input.context, input.state, era, mode, downstreamAudience), {
|
|
17
|
+
legacy: 'reject',
|
|
18
|
+
});
|
|
19
|
+
const transport = new StreamableHTTPClientTransport(new URL('http://handoffprobe.local/p0-mcp'), {
|
|
20
|
+
fetch: (requestInput, init) => handler.fetch(new Request(requestInput, init)),
|
|
21
|
+
});
|
|
22
|
+
const client = new Client({
|
|
23
|
+
name: 'handoffprobe-p0-fixture',
|
|
24
|
+
version: '0.0.0',
|
|
25
|
+
}, {
|
|
26
|
+
versionNegotiation: {
|
|
27
|
+
mode: {
|
|
28
|
+
pin: '2026-07-28',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
try {
|
|
33
|
+
await client.connect(transport);
|
|
34
|
+
const era = client.getProtocolEra();
|
|
35
|
+
if (era !== 'modern') {
|
|
36
|
+
throw new Error(`Expected modern MCP era but received ${String(era)}.`);
|
|
37
|
+
}
|
|
38
|
+
input.recorder.record({
|
|
39
|
+
protocol: 'MCP',
|
|
40
|
+
protocolVersion: '2026-07-28',
|
|
41
|
+
boundary: 'handoff-translation -> p0-mcp-client',
|
|
42
|
+
event: 'mcp.client.connected',
|
|
43
|
+
context: input.context,
|
|
44
|
+
details: {
|
|
45
|
+
era,
|
|
46
|
+
enforcementMode: mode,
|
|
47
|
+
downstreamAudience,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
input.recorder.record({
|
|
51
|
+
protocol: 'MCP',
|
|
52
|
+
protocolVersion: '2026-07-28',
|
|
53
|
+
boundary: 'p0-mcp-client -> p0-mcp-server',
|
|
54
|
+
event: 'mcp.tool.call',
|
|
55
|
+
context: input.context,
|
|
56
|
+
details: {
|
|
57
|
+
selectedTool: input.tool,
|
|
58
|
+
targetResource: input.arguments.resource,
|
|
59
|
+
enforcementMode: mode,
|
|
60
|
+
downstreamAudience,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
if (input.cancelLifecycleBeforeTool === true) {
|
|
64
|
+
const lifecycle = input.context.lifecycle;
|
|
65
|
+
if (lifecycle === undefined) {
|
|
66
|
+
throw new Error('Lifecycle cancellation requested without lifecycle context.');
|
|
67
|
+
}
|
|
68
|
+
const previousState = lifecycle.state;
|
|
69
|
+
lifecycle.state = 'cancelled';
|
|
70
|
+
input.recorder.record({
|
|
71
|
+
protocol: 'CORE',
|
|
72
|
+
protocolVersion: 'p0-lifecycle-v1',
|
|
73
|
+
boundary: 'governing-a2a-task -> p0-mcp-tool',
|
|
74
|
+
event: 'lifecycle.cancel',
|
|
75
|
+
context: input.context,
|
|
76
|
+
details: {
|
|
77
|
+
taskId: lifecycle.taskId,
|
|
78
|
+
previousState,
|
|
79
|
+
state: lifecycle.state,
|
|
80
|
+
delayPoint: 'after_mcp_request_before_tool_execution',
|
|
81
|
+
sideEffectCounterBefore: input.state.sideEffectCounter,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const result = await client.callTool({
|
|
86
|
+
name: input.tool,
|
|
87
|
+
arguments: input.arguments,
|
|
88
|
+
});
|
|
89
|
+
const envelope = JSON.parse(readTextContent(result.content));
|
|
90
|
+
input.recorder.record({
|
|
91
|
+
protocol: 'MCP',
|
|
92
|
+
protocolVersion: '2026-07-28',
|
|
93
|
+
boundary: 'p0-mcp-server -> handoff-translation',
|
|
94
|
+
event: 'mcp.tool.result',
|
|
95
|
+
context: input.context,
|
|
96
|
+
details: {
|
|
97
|
+
selectedTool: input.tool,
|
|
98
|
+
authorizationResult: envelope.authorization.invariantAllowed,
|
|
99
|
+
executed: envelope.authorization.executed,
|
|
100
|
+
sideEffectCounterBefore: envelope.before.sideEffectCounter,
|
|
101
|
+
sideEffectCounterAfter: envelope.after.sideEffectCounter,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
era,
|
|
106
|
+
envelope,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await client.close();
|
|
111
|
+
await handler.close();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../src/p0-fixture/mcp/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { P0AuthorizationDecision } from '../authorization.js';
|
|
2
|
+
import type { P0FixtureSnapshot } from '../state.js';
|
|
3
|
+
export type P0McpToolName = 'read_invoice' | 'update_invoice' | 'refund_payment' | 'send_email';
|
|
4
|
+
export type P0EnforcementMode = 'enforce' | 'bypass';
|
|
5
|
+
export interface P0ToolAuthorization {
|
|
6
|
+
policyMode: P0EnforcementMode;
|
|
7
|
+
invariantAllowed: boolean;
|
|
8
|
+
executed: boolean;
|
|
9
|
+
decision: P0AuthorizationDecision | null;
|
|
10
|
+
approvalMatches: boolean | null;
|
|
11
|
+
semanticBindingMatches: boolean;
|
|
12
|
+
downstreamAudience: string;
|
|
13
|
+
credentialForwarded: boolean;
|
|
14
|
+
credentialAudienceMatches: boolean | null;
|
|
15
|
+
credentialAccepted: boolean;
|
|
16
|
+
reasons: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface P0ToolEnvelope {
|
|
19
|
+
tool: P0McpToolName;
|
|
20
|
+
authorization: P0ToolAuthorization;
|
|
21
|
+
before: P0FixtureSnapshot;
|
|
22
|
+
after: P0FixtureSnapshot;
|
|
23
|
+
output: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface P0McpExecutionResult {
|
|
26
|
+
era: 'modern';
|
|
27
|
+
envelope: P0ToolEnvelope;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/p0-fixture/mcp/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,YAAY,CAAC;AAEhG,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACzC,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,sBAAsB,EAAE,OAAO,CAAC;IAEhC,kBAAkB,EAAE,MAAM,CAAC;IAE3B,mBAAmB,EAAE,OAAO,CAAC;IAE7B,yBAAyB,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1C,kBAAkB,EAAE,OAAO,CAAC;IAE5B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,aAAa,EAAE,mBAAmB,CAAC;IACnC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,QAAQ,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/p0-fixture/mcp/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-hash.d.ts","sourceRoot":"","sources":["../../src/p0-fixture/payload-hash.ts"],"names":[],"mappings":"AAoBA,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAM5D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
function canonicalize(value) {
|
|
3
|
+
if (Array.isArray(value)) {
|
|
4
|
+
return value.map((item) => canonicalize(item));
|
|
5
|
+
}
|
|
6
|
+
if (value !== null && typeof value === 'object') {
|
|
7
|
+
const result = {};
|
|
8
|
+
for (const key of Object.keys(value).sort()) {
|
|
9
|
+
result[key] = canonicalize(value[key]);
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
export function hashApprovalPayload(payload) {
|
|
16
|
+
const serialized = JSON.stringify(canonicalize(payload));
|
|
17
|
+
const digest = createHash('sha256').update(serialized).digest('hex');
|
|
18
|
+
return `sha256:${digest}`;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=payload-hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-hash.js","sourceRoot":"","sources":["../../src/p0-fixture/payload-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAErE,OAAO,UAAU,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AuthorityGrant, SecurityContext } from '../core/index.js';
|
|
2
|
+
export declare const P0_APPROVED_REFUND_PAYLOAD: {
|
|
3
|
+
readonly amount: 20;
|
|
4
|
+
readonly recipient: "acct:A";
|
|
5
|
+
};
|
|
6
|
+
export declare function createReferenceAuthority(): AuthorityGrant;
|
|
7
|
+
export declare function createP0ReferenceContext(): SecurityContext;
|
|
8
|
+
//# sourceMappingURL=reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/p0-fixture/reference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAexE,eAAO,MAAM,0BAA0B;;;CAG7B,CAAC;AAEX,wBAAgB,wBAAwB,IAAI,cAAc,CAQzD;AAED,wBAAgB,wBAAwB,IAAI,eAAe,CA8B1D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { P0_APPROVAL_ID, P0_AUTHORIZED_DOWNSTREAM, P0_AUTHORIZED_RESOURCE, P0_AUTHORIZED_TENANT, P0_CALLER, P0_CAPABILITY_READ, P0_CREDENTIAL_FINGERPRINT, P0_MCP_AUDIENCE, P0_PRINCIPAL, P0_TASK_ID, } from './constants.js';
|
|
2
|
+
import { hashApprovalPayload } from './payload-hash.js';
|
|
3
|
+
export const P0_APPROVED_REFUND_PAYLOAD = {
|
|
4
|
+
amount: 20,
|
|
5
|
+
recipient: 'acct:A',
|
|
6
|
+
};
|
|
7
|
+
export function createReferenceAuthority() {
|
|
8
|
+
return {
|
|
9
|
+
principal: P0_PRINCIPAL,
|
|
10
|
+
delegate: P0_AUTHORIZED_DOWNSTREAM,
|
|
11
|
+
tenant: P0_AUTHORIZED_TENANT,
|
|
12
|
+
resources: [P0_AUTHORIZED_RESOURCE],
|
|
13
|
+
capabilities: [P0_CAPABILITY_READ],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function createP0ReferenceContext() {
|
|
17
|
+
return {
|
|
18
|
+
principal: P0_PRINCIPAL,
|
|
19
|
+
caller: P0_CALLER,
|
|
20
|
+
downstream: P0_AUTHORIZED_DOWNSTREAM,
|
|
21
|
+
tenant: P0_AUTHORIZED_TENANT,
|
|
22
|
+
resource: P0_AUTHORIZED_RESOURCE,
|
|
23
|
+
capabilities: [P0_CAPABILITY_READ],
|
|
24
|
+
upstreamAuthority: createReferenceAuthority(),
|
|
25
|
+
effectiveAuthority: createReferenceAuthority(),
|
|
26
|
+
approval: {
|
|
27
|
+
approvalId: P0_APPROVAL_ID,
|
|
28
|
+
tool: 'refund_payment',
|
|
29
|
+
payloadHash: hashApprovalPayload(P0_APPROVED_REFUND_PAYLOAD),
|
|
30
|
+
},
|
|
31
|
+
upstreamCredential: {
|
|
32
|
+
fingerprint: P0_CREDENTIAL_FINGERPRINT,
|
|
33
|
+
credentialClass: 'bearer',
|
|
34
|
+
audience: P0_MCP_AUDIENCE,
|
|
35
|
+
},
|
|
36
|
+
lifecycle: {
|
|
37
|
+
taskId: P0_TASK_ID,
|
|
38
|
+
state: 'active',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference.js","sourceRoot":"","sources":["../../src/p0-fixture/reference.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,SAAS,EACT,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,MAAM,EAAE,EAAE;IACV,SAAS,EAAE,QAAQ;CACX,CAAC;AAEX,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,SAAS,EAAE,YAAY;QACvB,QAAQ,EAAE,wBAAwB;QAClC,MAAM,EAAE,oBAAoB;QAC5B,SAAS,EAAE,CAAC,sBAAsB,CAAC;QACnC,YAAY,EAAE,CAAC,kBAAkB,CAAC;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,SAAS,EAAE,YAAY;QACvB,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,wBAAwB;QACpC,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EAAE,sBAAsB;QAChC,YAAY,EAAE,CAAC,kBAAkB,CAAC;QAElC,iBAAiB,EAAE,wBAAwB,EAAE;QAE7C,kBAAkB,EAAE,wBAAwB,EAAE;QAE9C,QAAQ,EAAE;YACR,UAAU,EAAE,cAAc;YAC1B,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,mBAAmB,CAAC,0BAA0B,CAAC;SAC7D;QAED,kBAAkB,EAAE;YAClB,WAAW,EAAE,yBAAyB;YACtC,eAAe,EAAE,QAAQ;YACzB,QAAQ,EAAE,eAAe;SAC1B;QAED,SAAS,EAAE;YACT,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,QAAQ;SAChB;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SecurityContext } from '../core/index.js';
|
|
2
|
+
import type { P0McpToolName } from './mcp/types.js';
|
|
3
|
+
export type P0FixtureMode = 'secure' | 'vulnerable';
|
|
4
|
+
export interface P0Scenario {
|
|
5
|
+
id: string;
|
|
6
|
+
tool: P0McpToolName;
|
|
7
|
+
mcpAudience?: string;
|
|
8
|
+
lifecycleTracking?: boolean;
|
|
9
|
+
cancelLifecycleBeforeTool?: boolean;
|
|
10
|
+
buildArguments(context: SecurityContext): Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare const P0_READ_INVOICE_SCENARIO: P0Scenario;
|
|
13
|
+
export declare function createP0UpdateInvoiceScenario(amountCents: number): P0Scenario;
|
|
14
|
+
//# sourceMappingURL=scenario.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../../src/p0-fixture/scenario.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IAEpB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnE;AAED,eAAO,MAAM,wBAAwB,EAAE,UAStC,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAY7E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const P0_READ_INVOICE_SCENARIO = {
|
|
2
|
+
id: 'read-authorized-invoice',
|
|
3
|
+
tool: 'read_invoice',
|
|
4
|
+
buildArguments(context) {
|
|
5
|
+
return {
|
|
6
|
+
resource: context.resource,
|
|
7
|
+
};
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
export function createP0UpdateInvoiceScenario(amountCents) {
|
|
11
|
+
return {
|
|
12
|
+
id: `update-invoice-${amountCents}`,
|
|
13
|
+
tool: 'update_invoice',
|
|
14
|
+
buildArguments(context) {
|
|
15
|
+
return {
|
|
16
|
+
resource: context.resource,
|
|
17
|
+
amountCents,
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=scenario.js.map
|