create-metamynd-agent 0.7.1 → 0.7.2
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/README.md +28 -8
- package/index.mjs +39 -16
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -135,23 +135,43 @@ npm start
|
|
|
135
135
|
### Separate tool gateway (default)
|
|
136
136
|
|
|
137
137
|
This is the other half of **without MetaMynd, you can be bypassed**: WITH it — specifically, with
|
|
138
|
-
`gateway/`, the second process this scaffolds by default —
|
|
139
|
-
platform's own MCP counterparty can't
|
|
138
|
+
`gateway/`, the second process this scaffolds by default — calling the tool directly instead of
|
|
139
|
+
through the check no longer works, the same way the hosted platform's own MCP counterparty can't
|
|
140
|
+
be talked around by a compromised agent. See [Not solved by the gateway](#not-solved-by-the-gateway)
|
|
141
|
+
below for the two things this specifically does **not** cover.
|
|
140
142
|
|
|
141
143
|
`guard.guardTool()` in `index.mjs` still runs — it's a fast, local, client-side pre-check that gives
|
|
142
144
|
good UX (fail fast on an obviously-blocked call, no round trip) — but it is **not** what stops a
|
|
143
145
|
bypass. It still calls its handler in the SAME process regardless of where the decision came from,
|
|
144
146
|
so anything able to call that handler directly gets the same result the gate would have given it.
|
|
145
147
|
|
|
146
|
-
What actually stops
|
|
148
|
+
What actually stops that bypass is that `bookFlight()` doesn't exist in the agent's process at all.
|
|
147
149
|
It exists only in `gateway/server.mjs` — a separate process, started separately, holding any real
|
|
148
150
|
tool credentials the agent process never sees — which independently re-verifies every request
|
|
149
|
-
against the agent's own published policy bundle before running it
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
against the agent's own published policy bundle before running it, and **binds that request to the
|
|
152
|
+
actual body being executed** (`@metamynd/agentsafe-http-gateway` ≥ 0.2.0) — closing a confused-deputy
|
|
153
|
+
gap found during testing, where a signed cheap request could be governed while a different, expensive
|
|
154
|
+
body was the one that actually ran. Same shape as the mutual counterparty check in
|
|
155
|
+
[`@metamynd/agentsafe-mcp-guard`](https://www.npmjs.com/package/@metamynd/agentsafe-mcp-guard), built
|
|
156
|
+
with [`@metamynd/agentsafe-http-gateway`](https://www.npmjs.com/package/@metamynd/agentsafe-http-gateway).
|
|
157
|
+
It's a minimal slice of the fuller pattern proven end to end in `demo/duffel-mcp-gateway` in the
|
|
153
158
|
AgentSafe repo (mutual handshake, x402 payment binding, capability tokens) — this scaffold gives you
|
|
154
|
-
just the part that closes the bypass, not the whole protocol.
|
|
159
|
+
just the part that closes the direct-call bypass, not the whole protocol.
|
|
160
|
+
|
|
161
|
+
#### Not solved by the gateway
|
|
162
|
+
|
|
163
|
+
Named precisely, not left implicit:
|
|
164
|
+
|
|
165
|
+
- **Replay.** The gateway checks a signed request is fresh, not that it hasn't been used before —
|
|
166
|
+
a captured valid request can be resent within the freshness window. Single-use nonce consumption
|
|
167
|
+
is the stateful issuer gate's job (`POST /policy/mandate/authorize`); this scaffold never calls it.
|
|
168
|
+
- **Cumulative spend.** Each call is checked against the per-transaction cap correctly, but the
|
|
169
|
+
mandate's TOTAL budget isn't tracked at the gateway — many separately-legal calls can still add
|
|
170
|
+
up past it. The real total is only enforced where a hold is actually reserved: the issuer gate.
|
|
171
|
+
|
|
172
|
+
Both require wiring the full authorize-before-execute flow (agent calls the stateful gate first,
|
|
173
|
+
gateway checks a decision bound to that specific authorization) rather than per-request policy
|
|
174
|
+
re-evaluation alone — see `gateway/README.md`'s own "Beyond this minimal slice" section.
|
|
155
175
|
|
|
156
176
|
Pass `--no-gateway` to opt out and get the old single-process scaffold instead — e.g. if you're
|
|
157
177
|
already running your own separate gateway and don't need this one. **You are back to being
|
package/index.mjs
CHANGED
|
@@ -28,7 +28,9 @@ const GUARD_VERSION = '^0.5.0';
|
|
|
28
28
|
const MCP_GUARD_PKG = '@metamynd/agentsafe-mcp-guard';
|
|
29
29
|
const MCP_GUARD_VERSION = '^0.1.0';
|
|
30
30
|
const GATEWAY_PKG = '@metamynd/agentsafe-http-gateway';
|
|
31
|
-
|
|
31
|
+
// 0.2.0 fixes a confused-deputy gap (payload not bound to the signed request) — the CLI must
|
|
32
|
+
// never scaffold a range that could resolve below it.
|
|
33
|
+
const GATEWAY_VERSION = '^0.2.0';
|
|
32
34
|
const DEFAULT_API = 'https://metamynd.ai/api/v1';
|
|
33
35
|
const DEFAULT_GATEWAY_PORT = 4401; // distinct from --harness's dashboard (4400)
|
|
34
36
|
|
|
@@ -689,15 +691,17 @@ A MetaMynd/AgentSafe-governed agent, scaffolded with \`create-metamynd-agent\`.
|
|
|
689
691
|
|
|
690
692
|
${gatewaySection}${
|
|
691
693
|
withGateway
|
|
692
|
-
? `**With MetaMynd's gateway,
|
|
693
|
-
This scaffold's default shape (agent + separate
|
|
694
|
-
default) is the actual enforcement boundary
|
|
695
|
-
client-side convenience, not a
|
|
696
|
-
|
|
697
|
-
exists in \`./gateway\`, a process this one
|
|
698
|
-
every request against this agent's own policy
|
|
699
|
-
|
|
700
|
-
README
|
|
694
|
+
? `**With MetaMynd's gateway, calling the tool directly and skipping the check no longer
|
|
695
|
+
works** — that's what this section is about. This scaffold's default shape (agent + separate
|
|
696
|
+
gateway process, port ${gatewayPort} by default) is the actual enforcement boundary for that
|
|
697
|
+
specific bypass: \`guard.guardTool()\` in \`index.mjs\` is a client-side convenience, not a
|
|
698
|
+
boundary — it still runs its handler in-process regardless of where the decision came from. What
|
|
699
|
+
actually stops it is that \`bookFlight()\` itself only exists in \`./gateway\`, a process this one
|
|
700
|
+
cannot reach into, which independently re-verifies every request against this agent's own policy
|
|
701
|
+
bundle AND binds it to the actual body being executed. It does NOT track replay or cumulative
|
|
702
|
+
spend across calls — see \`./gateway/README.md\`'s "Beyond this minimal slice" section. Re-scaffold
|
|
703
|
+
with \`--no-gateway\` for the old single-process shape — it is NOT a separate enforcement boundary
|
|
704
|
+
at all; see its own generated README for why.`
|
|
701
705
|
: `**Without MetaMynd, you can be bypassed** — this is that case. This scaffold has no
|
|
702
706
|
separate gateway process (either \`--sandbox\`, which never provisions real credentials, or
|
|
703
707
|
\`--no-gateway\` was passed): \`guard.guardTool()\` wraps a tool in the SAME process as the check
|
|
@@ -837,8 +841,11 @@ function gatewayGitignore() {
|
|
|
837
841
|
function gatewayReadme(slug, scope, port) {
|
|
838
842
|
return `# ${slug}-gateway
|
|
839
843
|
|
|
840
|
-
**With MetaMynd, you can't
|
|
841
|
-
boundary** for \`${slug}\`'s tool(s) — not \`../index.mjs
|
|
844
|
+
**With MetaMynd, you can't call the tool directly and skip the check.** This process is why. It
|
|
845
|
+
is the **real enforcement boundary** for \`${slug}\`'s tool(s) — not \`../index.mjs\` — for that
|
|
846
|
+
specific bypass. See [Beyond this minimal slice](#beyond-this-minimal-slice) below for the two
|
|
847
|
+
things it does NOT yet close on its own: replaying a captured request, and spend adding up
|
|
848
|
+
across many separately-legal calls.
|
|
842
849
|
|
|
843
850
|
## Why this exists
|
|
844
851
|
|
|
@@ -883,10 +890,26 @@ add another protected route here rather than adding a local function back in \`i
|
|
|
883
890
|
|
|
884
891
|
## Beyond this minimal slice
|
|
885
892
|
|
|
886
|
-
This gateway
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
893
|
+
This gateway independently re-verifies a signed request AND binds it to the actual request body
|
|
894
|
+
(§9.3/§9.6 of the MAGP spec, plus payload binding — \`@metamynd/agentsafe-http-gateway\` ≥ 0.2.0).
|
|
895
|
+
That closes the specific bypass this scaffold exists to close: an agent (or anything able to call
|
|
896
|
+
its code) presenting one set of values while a different set actually executes.
|
|
897
|
+
|
|
898
|
+
Two things it deliberately does NOT close, named precisely rather than left implicit:
|
|
899
|
+
|
|
900
|
+
- **Replay.** \`verifyRequest()\` checks the signed request is fresh, not that it hasn't been used
|
|
901
|
+
before — a captured valid request can be resent within the freshness window. Single-use nonce
|
|
902
|
+
consumption is the stateful issuer gate's job, not this gateway's; this scaffold never calls it.
|
|
903
|
+
- **Cumulative spend.** Each call is checked against the per-transaction cap correctly, but the
|
|
904
|
+
mandate's TOTAL budget isn't tracked here — many separately-legal calls can still add up past
|
|
905
|
+
it. The real total is only enforced where holds are actually reserved: \`POST
|
|
906
|
+
/policy/mandate/authorize\` on the issuer.
|
|
907
|
+
|
|
908
|
+
Closing both means wiring the full authorize-before-execute flow — the agent calling that
|
|
909
|
+
stateful endpoint first, this gateway checking a decision bound to that specific authorization —
|
|
910
|
+
not just re-evaluating policy per request. See \`@metamynd/agentsafe-mcp-guard\`'s own README
|
|
911
|
+
(mutual DID handshake, x402 payment binding, commitment-bound capability tokens) and
|
|
912
|
+
\`demo/duffel-mcp-gateway\` in the AgentSafe repo for what that full pattern looks like.
|
|
890
913
|
`;
|
|
891
914
|
}
|
|
892
915
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-metamynd-agent",
|
|
3
|
-
"version": "0.7.
|
|
4
|
-
"description": "Scaffold a MetaMynd/AgentSafe-governed AI agent in one command — logs in, provisions the agent (identity + mandate + SOP + Standards) in a single call, writes agent.metamynd.json plus a runnable agent + separate tool-gateway process
|
|
3
|
+
"version": "0.7.2",
|
|
4
|
+
"description": "Scaffold a MetaMynd/AgentSafe-governed AI agent in one command — logs in, provisions the agent (identity + mandate + SOP + Standards) in a single call, writes agent.metamynd.json plus a runnable agent + separate tool-gateway process that closes the direct-call bypass. --harness scaffolds a free, local, zero-network governance harness instead.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-metamynd-agent": "index.mjs"
|