@boardstate/server@1.2.0
·
28 commits
to main
since this release
Minor Changes
-
#53
a0feba7Thanks @100yenadmin! - M5 trust layer (M5b-2 + M5b-3, epic #37): the grant lifecycle for external MCP tools
and the server-enforced pending-action engine — closes #40 and #41.Grant lifecycle + both-direction anti-rug-pull (SPEC §17.1, #40)
installBrokerActions(@boardstate/server/node) registers each configured connector's
discovered tools as arequestedtools-only grant (explicitmethods: []/streams: [],
atoolsid snapshot, and a subset-scopedtoolsHash), mirroringinstallConnector's
request-on-install. An already-grantedgrant survives a restart; real manifest drift is
caught at invoke time.- Server-side anti-rug-pull: on every granted-tool call the live manifest hash is compared
to the storedtoolsHash; a mismatch re-pends the grant torequestedBEFORE any call
succeeds. - Agent-side anti-rug-pull:
reconcileReplaceApprovalnow forces agrantedgrant back to
requestedon ANYtools/toolsHashmutation (not just status flips) — closing the
red-team hole where an agent could append a tool id to a granted grant through
workspace.replaceor import. - Partial grants:
dashboard.capability.approvegains an optionaltoolssubset; the
decision applies to the intersection with the requested set and the granted subset gets
its OWN hash (McpBroker.hashToolSubset, injected ascapabilityToolsHash). - Approvals console: capability rows surface their requested tool ids for per-tool selection
(approve-all = one click); the core transform + lit renderer + strings render it.
Pending-action engine (SPEC §18, #41)
- In-memory pending-action registry.
dashboard.action.invokeAND-gates a call (granted at
invoke time + connector configured + hash unchanged): areadOnlygranted tool executes
directly; a mutation parks as aPendingActionRecordand returns{ pending: true, id, expiresAt }.dashboard.action.confirm/dashboard.action.denyare operator-only
(OPERATOR_ONLY_METHODS) — a networked client can directly execute onlyreadOnlytools. - TTL expiry (~5 min), single-shot terminal states (a replay of a terminal id errors),
server-side invoke rate limiting (prompt-gate discipline), an audit entry per invoke +
decision, and lifecycle broadcasts ondashboard.action.changed. confirmAndExecute(id)is exposed as the awaitable an agent-mediated call (M5c-1) blocks
on: it resolves with the tool result on confirm and rejects on deny/expiry.
The engine consumes the broker through the narrow structural
ActionBrokerinterface —
@boardstate/brokernever enters@boardstate/server(no dependency cycle); the real
McpBrokerfits it structurally. SPEC §17.1/§18 normative text filled where the schema
train (#39) left implementation-pending markers.
Patch Changes
c895241- Security: thedashboard_workspace_replaceagent tool now passes the structural
replace gate (reconcileReplaceApproval), so an agent can no longer self-grant a
capability by writingstatus: "granted"intocapabilitiesRegistry. Only
dashboard.capability.approve(operator-only) grants. The RPC replace path was
already gated; this closes the agent-tool path.- Updated dependencies [
b05c7cd,a0feba7]:- @boardstate/schema@1.2.0
- @boardstate/core@1.2.0