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.
Security follow-up to ADR-0097 / #3017 (#3049), and the precondition for shipping
connector-mcpin 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 themetadata:reloadedreconcile 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
createMcpProviderFactorygains adeclarativeStdiopolicy, default deny:undefined/false→ a declarative stdio transport is rejected;string[]→ allowlist, matched againsttransport.commandby strict equality;true→ allow any command (explicit full trust).ConnectorMcpPluginplumbs the option through:new ConnectorMcpPlugin({ declarativeStdio: ['npx'] }).CONNECTOR_UPSTREAM_UNAVAILABLE(feat(connectors): degrade + retry declarative instances on unreachable upstream (#3017) #3049): a security rejection is not retryable-into-existence.httptransports stay unaffected (outbound HTTP is the same trust class as thehttpnode / rest connector).createMcpConnector/ plugin instance options): host code wrote that command — a different trust anchor than metadata.npx≈ allowing any package); real sandboxing / multi-tenant isolation remains the enterprise tier per ADR-0024 §4.truepassthrough, http unaffected, hand-wired path unaffected.Refs
docs/adr/0097-declarative-connector-instances.md), ADR-0024 §4 (trust model)provider-boundconnectors:materialized by generic executors) #2977 (ADR-0097 implementation)