@synapsor/runner 1.0.0 → 1.1.1
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/CHANGELOG.md +37 -1
- package/README.md +45 -3
- package/THREAT_MODEL.md +35 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/local-ui.d.ts +3 -0
- package/dist/local-ui.d.ts.map +1 -1
- package/dist/runner.mjs +3935 -863
- package/docs/README.md +16 -3
- package/docs/capability-authoring.md +2 -1
- package/docs/current-scope.md +5 -1
- package/docs/dsl-reference.md +7 -0
- package/docs/http-mcp.md +4 -1
- package/docs/limitations.md +20 -6
- package/docs/migrating-to-synapsor-spec.md +21 -0
- package/docs/oss-vs-cloud.md +1 -1
- package/docs/production.md +50 -8
- package/docs/release-notes.md +19 -1
- package/docs/release-policy.md +21 -0
- package/docs/runner-config-reference.md +101 -3
- package/docs/running-a-runner-fleet.md +349 -0
- package/docs/security-boundary.md +7 -0
- package/examples/runner-fleet/Dockerfile +11 -0
- package/examples/runner-fleet/README.md +52 -0
- package/examples/runner-fleet/docker-compose.yml +76 -0
- package/examples/runner-fleet/mint-dev-token.mjs +19 -0
- package/examples/runner-fleet/seed/mysql.sql +20 -0
- package/examples/runner-fleet/seed/postgres.sql +73 -0
- package/examples/runner-fleet/synapsor.runner.json +105 -0
- package/fixtures/protocol/MANIFEST.json +1 -1
- package/package.json +3 -1
- package/schemas/change-set.v1.schema.json +2 -1
- package/schemas/synapsor.runner.schema.json +115 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 1.1.1 (prepared, not published)
|
|
4
|
+
|
|
5
|
+
### Resource Read Authorization
|
|
6
|
+
|
|
7
|
+
- Reauthorizes local MCP proposal, evidence, and replay reads against the
|
|
8
|
+
owning capability's trusted tenant and principal before returning content.
|
|
9
|
+
- Returns the same generic `RESOURCE_NOT_FOUND` result for missing resources,
|
|
10
|
+
cross-tenant access, cross-principal access, and incomplete legacy ownership
|
|
11
|
+
metadata so a leaked handle does not become bearer authority.
|
|
12
|
+
- Adds shared-store and Streamable HTTP regressions proving owner access still
|
|
13
|
+
works while cross-session resource reads fail closed.
|
|
14
|
+
- Stages only `@synapsor/runner@1.1.1`; canonical Spec and DSL remain `1.1.0`.
|
|
15
|
+
|
|
16
|
+
## 1.1.0
|
|
17
|
+
|
|
18
|
+
### Fleet Safety And Operations
|
|
19
|
+
|
|
20
|
+
- Fails closed when claim-authenticated HTTP serving resolves an
|
|
21
|
+
environment/static contract context, and fixes object-filtered activity so
|
|
22
|
+
unrelated receipts cannot enter results.
|
|
23
|
+
- Adds RS256/ES256 session and operator JWT verification with bounded JWKS or
|
|
24
|
+
public-PEM loading, plus verified operator attestations without bearer-token
|
|
25
|
+
persistence.
|
|
26
|
+
- Adds dependency-aware `/readyz`, separately protected `/metrics`, reusable
|
|
27
|
+
bounded Postgres/MySQL pools, and trusted tenant/capability fixed-window rate
|
|
28
|
+
limits that are atomic in shared runtime-store mode.
|
|
29
|
+
- Adds optional canonical `required_approvals` and DSL `REQUIRE n APPROVALS`,
|
|
30
|
+
distinct-reviewer enforcement, `n/N` progress, terminal rejection, and
|
|
31
|
+
policy-auto-approval deferral for multi-human quorum.
|
|
32
|
+
- Hardens shared Postgres migration startup, bounds the transient bridge with
|
|
33
|
+
`max_entries`, makes CLI/UI reviewers read the shared queue, and fixes nested
|
|
34
|
+
worker/apply bridge locking.
|
|
35
|
+
- Adds verified dead-letter list/show/requeue/discard, shared-ledger
|
|
36
|
+
backup/digest/restore, archive-before-retention, and a repeatable two-Runner
|
|
37
|
+
kill/recovery test over synthetic Postgres/MySQL.
|
|
38
|
+
- Stages `@synapsor/spec@1.1.0`, `@synapsor/dsl@1.1.0`, and
|
|
39
|
+
`@synapsor/runner@1.1.0`. Nothing is published by this change.
|
|
4
40
|
|
|
5
41
|
## 1.0.0
|
|
6
42
|
|
package/README.md
CHANGED
|
@@ -25,6 +25,19 @@ even if you never adopt Runner:
|
|
|
25
25
|
npx -y @synapsor/runner audit --example dangerous-db-mcp
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
Then point the same static review at your own exported tool manifest, remote
|
|
29
|
+
`tools/list` endpoint, or stdio MCP server:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx -y @synapsor/runner audit ./tools-list.json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The audit flags raw SQL, arbitrary table/column inputs, model-controlled tenant
|
|
36
|
+
or principal authority, model-facing approval/writeback tools, and missing
|
|
37
|
+
conflict or idempotency signals. It does not call business tools, and it is a
|
|
38
|
+
risk review rather than proof that a server is secure. See [MCP Database Risk
|
|
39
|
+
Review](docs/mcp-audit.md) for remote, stdio, JSON, and Markdown workflows.
|
|
40
|
+
|
|
28
41
|
Then see the proposal, approval boundary, evidence, and replay loop. It needs no
|
|
29
42
|
database, Docker, config file, MCP client, or Synapsor account:
|
|
30
43
|
|
|
@@ -65,6 +78,21 @@ approval or apply tools. A human or trusted operator approves outside MCP, then
|
|
|
65
78
|
Runner either performs one guarded row update or routes the approved proposal
|
|
66
79
|
to an app-owned executor.
|
|
67
80
|
|
|
81
|
+
The distinction is the complete boundary, not a read-only toggle or a generic
|
|
82
|
+
approve/reject prompt:
|
|
83
|
+
|
|
84
|
+
- reviewed contracts constrain tools, tenant context, visible and writable
|
|
85
|
+
columns, numeric bounds, transitions, and approval requirements;
|
|
86
|
+
- proposals separate model intent from commit authority, including aggregate
|
|
87
|
+
auto-approval ceilings where configured;
|
|
88
|
+
- evidence, query audit, idempotency receipts, and replay preserve what was
|
|
89
|
+
inspected, requested, approved, and applied.
|
|
90
|
+
|
|
91
|
+
Runner supports bounded production deployments when its documented database,
|
|
92
|
+
identity, ledger, backup, and operational controls are satisfied. It does not
|
|
93
|
+
make arbitrary agent code, raw SQL tools, host infrastructure, or
|
|
94
|
+
prompt-injection-prone clients safe by itself.
|
|
95
|
+
|
|
68
96
|
## Connect A Staging Database
|
|
69
97
|
|
|
70
98
|
Start with a staging or disposable database and a read-only credential. Keep
|
|
@@ -133,6 +161,9 @@ trust boundaries, covered threats, non-goals, and required operator controls.
|
|
|
133
161
|
- [Conformance fixtures](docs/conformance.md) prove trusted context, scoped
|
|
134
162
|
reads, kept-out fields, proposal boundaries, approval, receipts, and replay
|
|
135
163
|
behavior rather than only validating JSON shape.
|
|
164
|
+
- MCP proposal, evidence, and replay handles are references rather than bearer
|
|
165
|
+
authority: resource reads re-check the owning tenant and principal against
|
|
166
|
+
the current trusted session.
|
|
136
167
|
- `corepack pnpm test:live-apply` runs disposable Postgres and MySQL scenarios.
|
|
137
168
|
It proves source rows stay unchanged before approval, guarded writeback
|
|
138
169
|
applies once, idempotent retry does not duplicate the effect, and a stale row
|
|
@@ -162,6 +193,16 @@ remains the default. See
|
|
|
162
193
|
[Production](docs/production.md) and the
|
|
163
194
|
[Runner Config Reference](docs/runner-config-reference.md).
|
|
164
195
|
|
|
196
|
+
For a small multi-tenant fleet, bind every capability context to verified HTTP
|
|
197
|
+
claims, use `jwt_asymmetric` session auth, and share a bounded Postgres
|
|
198
|
+
`runtime_store`. Never assume a global `http_claims` setting overrides an
|
|
199
|
+
environment-bound contract context; Runner rejects that contradiction before
|
|
200
|
+
serving tools. Load balancers should use dependency-free `/healthz` for
|
|
201
|
+
liveness and `/readyz` for source/ledger/writeback readiness. The tested
|
|
202
|
+
two-Runner topology, pool/rate-limit budgets, metrics, backup/restore,
|
|
203
|
+
dead-letter, and rolling-upgrade rules are in
|
|
204
|
+
[Running A Small Runner Fleet](docs/running-a-runner-fleet.md).
|
|
205
|
+
|
|
165
206
|
## Packages
|
|
166
207
|
|
|
167
208
|
| Package | Purpose |
|
|
@@ -184,9 +225,10 @@ owner-only permissions, inspection commands, and retention.
|
|
|
184
225
|
|
|
185
226
|
## OSS And Cloud
|
|
186
227
|
|
|
187
|
-
Synapsor Runner works by itself for local
|
|
188
|
-
database remains the source of truth and Runner stores review
|
|
189
|
-
default local SQLite ledger or an opt-in shared Postgres
|
|
228
|
+
Synapsor Runner works by itself for local, single-node, and bounded small-fleet
|
|
229
|
+
deployments: your database remains the source of truth and Runner stores review
|
|
230
|
+
artifacts in the default local SQLite ledger or an opt-in shared Postgres
|
|
231
|
+
runtime store.
|
|
190
232
|
Synapsor Cloud adds a shared contract registry, immutable versions,
|
|
191
233
|
downloadable Runner bundles, and team activity, evidence, and approval
|
|
192
234
|
surfaces. See [OSS Runner vs Synapsor Cloud](docs/oss-vs-cloud.md) for the
|
package/THREAT_MODEL.md
CHANGED
|
@@ -10,7 +10,8 @@ It is not a general MCP security gateway, not a prompt-injection cure, not a rep
|
|
|
10
10
|
- Business rows targeted by model-facing workflows.
|
|
11
11
|
- Trusted tenant, principal, source, object, allowed-column, and version bindings.
|
|
12
12
|
- Proposal diffs, evidence bundles, query audit, approvals, writeback jobs, receipts, and replay records.
|
|
13
|
-
- Runner
|
|
13
|
+
- Runner/session/operator tokens, local SQLite state, and optional shared
|
|
14
|
+
Postgres proposal/evidence/replay ledger.
|
|
14
15
|
|
|
15
16
|
## Trust Boundaries
|
|
16
17
|
|
|
@@ -38,6 +39,12 @@ MCP client/model
|
|
|
38
39
|
|
|
39
40
|
The model-facing MCP tool call has request/proposal authority. The trusted runner has execution authority only for already-approved, scoped writeback jobs.
|
|
40
41
|
|
|
42
|
+
In small-fleet mode, a TLS load balancer sends signed sessions to stateless
|
|
43
|
+
Runner instances. Every effective capability context must bind tenant and
|
|
44
|
+
principal from verified claims. Shared-ledger mutations serialize under a
|
|
45
|
+
bounded Postgres advisory lock; source-side receipts remain the durable
|
|
46
|
+
idempotency boundary for effects.
|
|
47
|
+
|
|
41
48
|
## Covered Threats
|
|
42
49
|
|
|
43
50
|
- Model asks for arbitrary SQL: no generic SQL tool is exposed in the Synapsor path.
|
|
@@ -50,6 +57,20 @@ The model-facing MCP tool call has request/proposal authority. The trusted runne
|
|
|
50
57
|
- Over-broad update: only single-row `UPDATE` is supported and success requires exactly one affected row.
|
|
51
58
|
- Cloud credential leakage: database URLs and write credentials stay local and are not sent to Cloud.
|
|
52
59
|
- Model-callable approval: approval/commit tools are not exposed to MCP clients by default.
|
|
60
|
+
- Claims/environment confusion: an `http_claims` server fails before serving
|
|
61
|
+
if a capability resolves an environment/static contract context.
|
|
62
|
+
- Leaked local resource handle: proposal, evidence, and replay reads resolve
|
|
63
|
+
the owning capability context again and require the same trusted tenant and
|
|
64
|
+
principal; missing or mismatched ownership returns the same generic
|
|
65
|
+
`RESOURCE_NOT_FOUND` response.
|
|
66
|
+
- JWT algorithm/key confusion: networked sessions use an explicit RS256/ES256
|
|
67
|
+
allowlist, issuer/audience/time checks, `kid`, and bounded public-key/JWKS
|
|
68
|
+
loading.
|
|
69
|
+
- Fleet races: shared proposal creation, distinct reviewer decisions, worker
|
|
70
|
+
claims, and fixed-window rate buckets are serialized/atomic in one ledger
|
|
71
|
+
schema.
|
|
72
|
+
- Worker death around an effect: source receipts make retry before write safe
|
|
73
|
+
and recovery after commit return `already_applied` rather than duplicate.
|
|
53
74
|
|
|
54
75
|
## Not Covered
|
|
55
76
|
|
|
@@ -60,7 +81,12 @@ The model-facing MCP tool call has request/proposal authority. The trusted runne
|
|
|
60
81
|
- Sensitive data already returned to a model.
|
|
61
82
|
- Prompt injection itself.
|
|
62
83
|
- Business invariants not represented in the capability config, proposal, application handler, or database constraints.
|
|
63
|
-
-
|
|
84
|
+
- Generic multi-row business transactions, DDL, DELETE, INSERT, UPSERT, or
|
|
85
|
+
cross-database atomicity in the Runner direct-write path.
|
|
86
|
+
- A compromised IdP/JWKS host, ledger database, source database, TLS
|
|
87
|
+
terminator, or administrator-approved contract.
|
|
88
|
+
- Unbounded/high-throughput or multi-region ledger scale, compliance
|
|
89
|
+
certification, or production SLA.
|
|
64
90
|
|
|
65
91
|
## Required Operator Controls
|
|
66
92
|
|
|
@@ -71,6 +97,13 @@ The model-facing MCP tool call has request/proposal authority. The trusted runne
|
|
|
71
97
|
- Prefer version/timestamp conflict guards over weak row-hash fallback.
|
|
72
98
|
- Review proposal diffs and evidence before approval.
|
|
73
99
|
- Monitor conflict/failed receipt rates.
|
|
100
|
+
- Allowlist JWKS egress, keep `/metrics` separately authorized, budget source
|
|
101
|
+
pools across replicas, back up/verify the shared ledger, and retain the
|
|
102
|
+
configured `max_entries` safety bound.
|
|
103
|
+
- Use verified `signed_key` or `jwt_oidc` reviewers for production-like shared
|
|
104
|
+
queues; `dev_env` is unverified.
|
|
105
|
+
- Treat proposal/evidence/replay handles as identifiers, not authorization;
|
|
106
|
+
preserve verified per-session context on every networked resource read.
|
|
74
107
|
|
|
75
108
|
## Release Blockers
|
|
76
109
|
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAYA,OAAO,EAAoP,KAAK,WAAW,EAA0H,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAYA,OAAO,EAAoP,KAAK,WAAW,EAA0H,MAAM,6BAA6B,CAAC;AAwBza,OAAO,EAA6G,KAAK,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAE/L,OAAO,EAOL,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAC;AAmV3C,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4D1D;AA0FD,KAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,OAAO,CAAC,MAAM,CAAC,CA2TjB;AA+gFD,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/H"}
|
package/dist/local-ui.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Server } from "node:http";
|
|
2
|
+
import { ProposalStore } from "@synapsor-runner/proposal-store";
|
|
2
3
|
export type LocalUiOptions = {
|
|
3
4
|
configPath?: string;
|
|
4
5
|
storePath?: string;
|
|
@@ -8,7 +9,9 @@ export type LocalUiOptions = {
|
|
|
8
9
|
csrfToken?: string;
|
|
9
10
|
allowRemoteBind?: boolean;
|
|
10
11
|
tour?: boolean;
|
|
12
|
+
storeAccess?: LocalUiStoreAccess;
|
|
11
13
|
};
|
|
14
|
+
export type LocalUiStoreAccess = <T>(mode: "read" | "write", operation: string, callback: (store: ProposalStore) => T) => Promise<T>;
|
|
12
15
|
export type LocalUiServer = {
|
|
13
16
|
server: Server;
|
|
14
17
|
url: string;
|
package/dist/local-ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-ui.d.ts","sourceRoot":"","sources":["../src/local-ui.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"local-ui.d.ts","sourceRoot":"","sources":["../src/local-ui.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAIjG,OAAO,EAAE,aAAa,EAAgD,MAAM,iCAAiC,CAAC;AAI9G,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,GAAG,OAAO,EACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,CAAC,KAClC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEhB,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA+C7F"}
|