You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Security follow-up to ADR-0097 / #3017 (#3049), and the precondition for shipping connector-mcp in any default preset (see the companion default-preset issue).
Threat model
A declarative provider: 'mcp' instance may name a stdio transport:
Materialization spawns that command as a local child process (StdioClientTransport). Declarative entries arrive through metadata — including a Studio publish at runtime, which triggers the metadata:reloaded reconcile and materializes new instances on a live server (soft mode skips failures, not successes). Net: anyone who can publish metadata can execute arbitrary commands on the server.
Today the accidental barrier is that the host must consciously install @objectstack/connector-mcp. If the plugin becomes part of the default preset — which the ADR-0097 "expressible and executable as pure metadata" promise wants — that barrier disappears. The gate must become explicit policy instead.
Ask
createMcpProviderFactory gains a declarativeStdio policy, default deny:
undefined / false → a declarative stdio transport is rejected;
string[] → allowlist, matched against transport.command by strict equality;
true → allow any command (explicit full trust).
ConnectorMcpPlugin plumbs the option through: new ConnectorMcpPlugin({ declarativeStdio: ['npx'] }).
A policy violation is a configuration fault — plain throw (fatal at boot, skipped+logged on reload), with an actionable message telling the host exactly how to opt in. It must NOT be classified CONNECTOR_UPSTREAM_UNAVAILABLE (feat(connectors): degrade + retry declarative instances on unreachable upstream (#3017) #3049): a security rejection is not retryable-into-existence.
http transports stay unaffected (outbound HTTP is the same trust class as the http node / rest connector).
Hand-wired paths stay unaffected (createMcpConnector / plugin instance options): host code wrote that command — a different trust anchor than metadata.
Docs: ADR-0097 addendum (+ ADR-0024 §4 cross-ref). Be honest that a command allowlist is a coarse boundary (allowlisting npx ≈ allowing any package); real sandboxing / multi-tenant isolation remains the enterprise tier per ADR-0024 §4.
Activity
Merge origin/main (post #3049 squash) into the stdio-gate branch
feat(connector-mcp): policy-gate declarative stdio transports — defau…
narrow to showcase demo + dogfood proof — template preset waits for t…
feat(showcase): live provider:'mcp' declarative connector demo + CI-p…
docs(adr): ADR-0101 — MCP stdio principal admission (env API-key iden…