machine-bridge-mcp 2.0.0 → 3.0.0-beta.10
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 +109 -0
- package/CONTRIBUTING.md +20 -25
- package/README.md +21 -14
- package/SECURITY.md +147 -123
- package/browser-extension/manifest.json +3 -2
- package/browser-extension/service-worker.js +31 -12
- package/docs/ARCHITECTURE.md +27 -13
- package/docs/AUDIT.md +85 -2
- package/docs/CLIENTS.md +2 -2
- package/docs/ENGINEERING.md +9 -3
- package/docs/GETTING_STARTED.md +10 -9
- package/docs/LOCAL_AUTHORIZATION.md +115 -72
- package/docs/LOGGING.md +12 -3
- package/docs/MANAGED_JOBS.md +24 -29
- package/docs/MULTI_ACCOUNT.md +98 -37
- package/docs/OPERATIONS.md +33 -22
- package/docs/OVERVIEW.md +7 -7
- package/docs/PROJECT_STANDARDS.md +9 -5
- package/docs/RELEASING.md +171 -64
- package/docs/TESTING.md +19 -7
- package/docs/THREAT_MODEL.md +138 -67
- package/docs/TOOL_REFERENCE.md +2 -2
- package/docs/UPGRADING.md +102 -18
- package/native/macos/MachineBridgeTrustBroker.swift +233 -0
- package/package.json +36 -5
- package/scripts/candidate-runtime-store.mjs +38 -0
- package/scripts/check-plan.mjs +19 -0
- package/scripts/check-runner.mjs +4 -1
- package/scripts/commit-message-check.mjs +5 -2
- package/scripts/coverage-check.mjs +30 -2
- package/scripts/github-push.mjs +11 -0
- package/scripts/github-release.mjs +38 -7
- package/scripts/install-published-prerelease.mjs +167 -0
- package/scripts/local-release-acceptance.mjs +23 -12
- package/scripts/npm-publication-policy.mjs +16 -0
- package/scripts/prerelease-activation.mjs +79 -0
- package/scripts/privacy-check.mjs +7 -5
- package/scripts/promotion-digest.mjs +121 -0
- package/scripts/publish-npm.mjs +51 -0
- package/scripts/published-release.mjs +87 -0
- package/scripts/release-acceptance.mjs +30 -1
- package/scripts/release-candidate-manifest.mjs +40 -0
- package/scripts/release-channel.mjs +106 -0
- package/scripts/release-impact-check.mjs +12 -22
- package/scripts/release-soak.mjs +237 -0
- package/scripts/start-release-candidate.mjs +113 -7
- package/src/local/account-access.mjs +6 -0
- package/src/local/account-admin.mjs +34 -16
- package/src/local/agent-context.mjs +45 -42
- package/src/local/app-automation.mjs +9 -4
- package/src/local/authority-context.mjs +106 -0
- package/src/local/browser-bridge-http.mjs +4 -1
- package/src/local/browser-bridge.mjs +14 -9
- package/src/local/browser-broker-routes.mjs +4 -0
- package/src/local/browser-broker-server.mjs +5 -4
- package/src/local/browser-extension-identity.mjs +50 -0
- package/src/local/browser-extension-protocol.mjs +9 -4
- package/src/local/browser-operation-service.mjs +7 -0
- package/src/local/browser-pairing-http.mjs +36 -0
- package/src/local/browser-pairing-store.mjs +56 -47
- package/src/local/cli-account-admin.mjs +41 -7
- package/src/local/cli-activate.mjs +90 -0
- package/src/local/cli-approval.mjs +14 -58
- package/src/local/cli-local-admin.mjs +5 -15
- package/src/local/cli-options.mjs +11 -7
- package/src/local/cli-service.mjs +35 -5
- package/src/local/cli.mjs +112 -58
- package/src/local/daemon-process.mjs +6 -0
- package/src/local/delegated-process-sandbox.mjs +147 -0
- package/src/local/device-identity.mjs +157 -48
- package/src/local/device-root-provider.mjs +87 -0
- package/src/local/errors.mjs +25 -3
- package/src/local/git-service.mjs +16 -15
- package/src/local/job-runner.mjs +35 -27
- package/src/local/log.mjs +14 -1
- package/src/local/macos-trust-broker.mjs +320 -0
- package/src/local/managed-job-lock.mjs +18 -0
- package/src/local/managed-job-projection.mjs +9 -1
- package/src/local/managed-job-runner.mjs +13 -1
- package/src/local/managed-job-storage.mjs +2 -1
- package/src/local/managed-job-terminal.mjs +138 -0
- package/src/local/managed-jobs.mjs +88 -32
- package/src/local/operation-authorization.mjs +75 -239
- package/src/local/operation-risk.mjs +28 -0
- package/src/local/operation-state-lock.mjs +7 -86
- package/src/local/owner-state-lock.mjs +104 -0
- package/src/local/policy.mjs +19 -0
- package/src/local/process-execution.mjs +21 -9
- package/src/local/process-sessions.mjs +27 -17
- package/src/local/process-tracker.mjs +30 -6
- package/src/local/process-tree-ownership.mjs +59 -0
- package/src/local/process-tree.mjs +22 -18
- package/src/local/relay-connection.mjs +47 -35
- package/src/local/relay-diagnostics.mjs +65 -0
- package/src/local/remote-configuration.mjs +48 -0
- package/src/local/runtime-activation.mjs +141 -0
- package/src/local/runtime-diagnostics.mjs +21 -0
- package/src/local/runtime-relay.mjs +9 -8
- package/src/local/runtime-reporting.mjs +8 -3
- package/src/local/runtime-tool-handlers.mjs +8 -8
- package/src/local/runtime.mjs +73 -39
- package/src/local/secure-file.mjs +5 -1
- package/src/local/security-audit-log.mjs +204 -0
- package/src/local/service-convergence.mjs +17 -1
- package/src/local/service-ownership.mjs +17 -0
- package/src/local/service-restart-handoff.mjs +50 -0
- package/src/local/service-restart-scheduler.mjs +49 -0
- package/src/local/service-status.mjs +47 -0
- package/src/local/service.mjs +142 -43
- package/src/local/state-inventory.mjs +21 -3
- package/src/local/state.mjs +155 -17
- package/src/local/stdio.mjs +5 -0
- package/src/local/tool-executor.mjs +39 -6
- package/src/local/tool-result-boundary.mjs +51 -0
- package/src/local/tools.mjs +1 -0
- package/src/local/trusted-executable.mjs +53 -0
- package/src/local/trusted-git-executable.mjs +34 -0
- package/src/local/trusted-github-cli.mjs +24 -0
- package/src/local/windows-service.mjs +20 -0
- package/src/local/worker-deployment.mjs +3 -4
- package/src/local/worker-secret-file.mjs +2 -2
- package/src/local/workspace-file-service.mjs +34 -31
- package/src/shared/admin-auth.d.mts +2 -1
- package/src/shared/admin-auth.mjs +3 -3
- package/src/shared/device-session-auth.d.mts +20 -0
- package/src/shared/device-session-auth.mjs +51 -0
- package/src/shared/server-metadata.json +1 -1
- package/src/shared/tool-catalog.json +2 -2
- package/src/worker/account-admin.ts +23 -22
- package/src/worker/authority.ts +9 -2
- package/src/worker/daemon-auth.ts +45 -67
- package/src/worker/daemon-sockets.ts +12 -2
- package/src/worker/device-session-verifier.ts +129 -0
- package/src/worker/dpop.ts +151 -0
- package/src/worker/http.ts +47 -16
- package/src/worker/index.ts +53 -16
- package/src/worker/nonce-store.ts +1 -5
- package/src/worker/oauth-client-admin.ts +45 -0
- package/src/worker/oauth-controller.ts +55 -6
- package/src/worker/oauth-refresh-families.ts +21 -7
- package/src/worker/oauth-state.ts +6 -0
- package/src/worker/oauth-tokens.ts +28 -8
- package/src/worker/websocket-protocol.ts +8 -2
package/SECURITY.md
CHANGED
|
@@ -6,230 +6,254 @@ Security fixes are applied to the latest released version. Upgrade before report
|
|
|
6
6
|
|
|
7
7
|
## Reporting a vulnerability
|
|
8
8
|
|
|
9
|
-
Do not open a public issue for an undisclosed vulnerability. Use [GitHub private vulnerability reporting](https://github.com/YuLeiFuYun/machine-bridge-mcp/security/advisories/new)
|
|
9
|
+
Do not open a public issue for an undisclosed vulnerability. Use [GitHub private vulnerability reporting](https://github.com/YuLeiFuYun/machine-bridge-mcp/security/advisories/new). Include:
|
|
10
10
|
|
|
11
11
|
- affected version and operating system;
|
|
12
12
|
- remote or stdio transport;
|
|
13
|
-
- selected
|
|
13
|
+
- selected daemon policy and authenticated account role;
|
|
14
14
|
- minimal reproduction;
|
|
15
15
|
- expected and observed impact;
|
|
16
|
-
- whether credentials,
|
|
16
|
+
- whether credentials, files, process authority, browser/application state, or network access were exposed.
|
|
17
17
|
|
|
18
|
-
Do not include live account passwords,
|
|
18
|
+
Do not include live account passwords, OAuth tokens, Cloudflare credentials, private keys, browser material, or unrelated local files. Rotate any credential used in a reproduction.
|
|
19
19
|
|
|
20
20
|
## Repository and documentation privacy
|
|
21
21
|
|
|
22
|
-
Tests, examples, documentation, release notes, and package metadata are publication surfaces. Use
|
|
22
|
+
Tests, examples, documentation, release notes, and package metadata are publication surfaces. Use synthetic hostnames, aliases, usernames, paths, and project names.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Run:
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
```sh
|
|
27
|
+
npm run privacy:check
|
|
28
|
+
npm run privacy:history
|
|
29
|
+
```
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
Maintain private local identifiers in the ignored `.privacy-denylist`. Removing a value from the current branch does not remove it from Git history, caches, forks, or published packages. Rotate exposed credentials immediately.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
CodeQL and OpenSSF Scorecard are release gates. Exceptions must be exact, justified, time-bounded, and independently visible; rule-wide suppression is not accepted.
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
2. the installed package/source checkout and its dependencies;
|
|
36
|
-
3. for remote mode, the user's Cloudflare account and deployed Worker;
|
|
37
|
-
4. an MCP client explicitly authorized through OAuth or launched locally through trusted stdio configuration.
|
|
35
|
+
## Core trust model
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
The detailed model is in [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md).
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
Trusted components are:
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
1. the local OS account running Machine Bridge;
|
|
42
|
+
2. the installed package or source checkout and its dependencies;
|
|
43
|
+
3. the user's Cloudflare account and deployed Worker in remote mode;
|
|
44
|
+
4. the explicitly authorized MCP client;
|
|
45
|
+
5. the selected browser profile and extension installation when browser automation is enabled.
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
The Worker authenticates and filters remote requests. The local runtime owns filesystem, process, browser, application, resource, and job authority. Stdio bypasses the Worker and relies on local process and configuration trust.
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
## Effective remote authority
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
Remote authority is an intersection:
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
```text
|
|
54
|
+
daemon capability ceiling
|
|
55
|
+
∩ account role
|
|
56
|
+
∩ trusted OAuth client binding
|
|
57
|
+
∩ account version and refresh-token family
|
|
58
|
+
∩ object ownership
|
|
59
|
+
```
|
|
52
60
|
|
|
53
|
-
The
|
|
61
|
+
The roles are:
|
|
54
62
|
|
|
55
|
-
- `
|
|
56
|
-
- `
|
|
57
|
-
- `
|
|
58
|
-
- `
|
|
63
|
+
- `reviewer`: read-only selected-workspace access;
|
|
64
|
+
- `editor`: selected-workspace reads and deterministic file mutation;
|
|
65
|
+
- `operator`: workspace-confined mutation and direct process execution;
|
|
66
|
+
- `owner`: complete bridge authority within the daemon policy ceiling.
|
|
59
67
|
|
|
60
|
-
|
|
68
|
+
No approval ID, refresh token, reconnect, client registration, or legacy lease can expand a role. Out-of-role operations fail with `authorization_denied`.
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
The Worker filters the tool catalog, and the local runtime independently recomputes the role boundary before dispatch. Account disablement, role change, password rotation, account removal, client revocation, token-version rotation, and refresh-family replay invalidate the appropriate credentials.
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
An OAuth client is bound to one account, account version, and role after successful authorization. It cannot silently switch accounts. Use `machine-mcp account clients` to inspect clients and `machine-mcp account revoke-client CLIENT_ID` to revoke one client and its credentials.
|
|
65
73
|
|
|
66
|
-
##
|
|
74
|
+
## Profiles are capability sets, not sandboxes
|
|
67
75
|
|
|
68
|
-
|
|
76
|
+
The default `full` profile prioritizes owner automation over least privilege.
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
- `full` exposes all tools, unrestricted paths, absolute path output, shell execution, browser/application automation, managed jobs, and the complete parent environment.
|
|
79
|
+
- `agent` exposes workspace-confined mutation and direct process execution with an isolated environment.
|
|
80
|
+
- `edit` exposes reads and file mutation without process execution.
|
|
81
|
+
- `review` exposes read-only workspace, Git, and image tools.
|
|
71
82
|
|
|
72
|
-
|
|
83
|
+
A stored `full` label is canonical. Per-capability narrowing is represented as `custom`, not as a partially restricted `full`.
|
|
73
84
|
|
|
74
|
-
|
|
85
|
+
`run_process` avoids shell parsing but an invoked interpreter, package manager, compiler, test runner, or repository script can execute arbitrary code. `exec_command` additionally enables shell expansion.
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
Owner execution is not OS-sandboxed by Machine Bridge. Use a dedicated low-privilege account, container, or VM for mutually untrusted workloads.
|
|
77
88
|
|
|
78
|
-
|
|
89
|
+
## Delegated process isolation
|
|
79
90
|
|
|
80
|
-
|
|
91
|
+
An `operator` process must pass a behaviorally verified OS-sandbox boundary. Restricting only cwd and environment is insufficient because an ordinary same-user process can otherwise read the user's home, Machine Bridge state, Keychain, and desktop session.
|
|
81
92
|
|
|
82
|
-
The
|
|
93
|
+
The sandbox probe must demonstrate that the selected workspace is usable while protected roots remain unreadable. If the platform cannot demonstrate the negative boundary, delegated process execution fails closed.
|
|
83
94
|
|
|
84
|
-
|
|
95
|
+
The existence of `sandbox-exec`, a container binary, or another sandbox command is not treated as proof of isolation.
|
|
85
96
|
|
|
86
|
-
|
|
97
|
+
## Machine Bridge control plane
|
|
87
98
|
|
|
88
|
-
|
|
99
|
+
Generic path-based file, image, search, and patch tools cannot target Machine Bridge control-plane roots, including device-root metadata, account-management state, audit state, service metadata, locks, native broker artifacts, resources, and profile state. This denial also applies to `owner/full` and prevents accidental export through structured file APIs.
|
|
89
100
|
|
|
90
|
-
|
|
101
|
+
It is not an OS sandbox. `owner/full` shell or interpreter execution runs with the daemon OS user's ambient authority and can access same-user files outside Machine Bridge's path resolver. Protect mutually untrusted owner clients with a separate low-privilege OS account, VM, or container; do not describe the path check as protection from arbitrary owner code execution.
|
|
91
102
|
|
|
92
|
-
|
|
103
|
+
## Device identity and user presence
|
|
93
104
|
|
|
105
|
+
Remote daemon authentication uses a long-term device root and a root-certified ephemeral session.
|
|
94
106
|
|
|
95
|
-
|
|
107
|
+
The default provider on every platform, including macOS, is an owner-only portable P-256 root. Its private JWK is exportable by the daemon OS user and is reported as such in `server_info`. The root signs a 24-hour ephemeral session certificate at daemon startup; the ephemeral private key remains in memory and signs WebSocket preflight, Worker challenge, reconnect, and account-administration requests. Portable startup does not access Keychain and does not request user presence.
|
|
96
108
|
|
|
97
|
-
|
|
109
|
+
macOS can opt into a non-exportable Secure Enclave root only through `MBM_MACOS_TRUST_BROKER`. The configured executable must be an app-like broker signed by an Apple development or distribution identity with provisioning-profile-validated data-protection Keychain entitlements. Machine Bridge validates its canonical path, file mutability, strict code signature, signing identifier, Team ID, protocol responses, and a real create/delete Secure Enclave key probe before enrollment. The broker identity remains bound to the root and is revalidated before later use.
|
|
98
110
|
|
|
99
|
-
|
|
111
|
+
The prompt frequency is therefore:
|
|
100
112
|
|
|
101
|
-
|
|
113
|
+
- ordinary tool calls: none;
|
|
114
|
+
- portable-root daemon startup: none;
|
|
115
|
+
- provisioned Secure Enclave daemon startup: one user-presence operation;
|
|
116
|
+
- relay reconnect: none;
|
|
117
|
+
- independent local account administration: none with a portable root, or one with a provisioned Secure Enclave root;
|
|
118
|
+
- device-root rotation: one explicit operation, plus user presence only when the provisioned broker requires it.
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
The packaged Swift source and ad-hoc build are development/protocol fixtures. The production validator deliberately rejects them because ad-hoc code has no provisioning-profile-validated data-protection Keychain access group.
|
|
104
121
|
|
|
105
|
-
The
|
|
122
|
+
The broker path, signing identifier, Team ID, and capability are revalidated before use, but those checks cannot distinguish a malicious replacement signed by the same trusted Apple team and identifier. Install production brokers in a root-owned or otherwise daemon-user-non-writable location and protect the signing identity and update channel.
|
|
106
123
|
|
|
107
|
-
|
|
124
|
+
## Account administration
|
|
108
125
|
|
|
109
|
-
|
|
126
|
+
Version 3 has no long-lived `ACCOUNT_ADMIN_SECRET`. Account and OAuth-client administration uses P-256 requests signed by the root-certified ephemeral session. The signature binds:
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
- Worker origin;
|
|
129
|
+
- HTTP method and path;
|
|
130
|
+
- request-body hash;
|
|
131
|
+
- ephemeral key ID;
|
|
132
|
+
- timestamp;
|
|
133
|
+
- random nonce.
|
|
112
134
|
|
|
113
|
-
|
|
135
|
+
The Worker verifies the root certificate, session signature, bounded timestamp, body hash, and nonce replay state. Nonce capacity fails closed instead of evicting live replay markers.
|
|
114
136
|
|
|
115
|
-
|
|
137
|
+
Account passwords are generated 256-bit tokens. The Worker stores independent salted verifiers, not plaintext passwords. A generated password is printed once by the command that creates or rotates it.
|
|
116
138
|
|
|
117
|
-
|
|
139
|
+
## OAuth and DPoP
|
|
118
140
|
|
|
119
|
-
|
|
141
|
+
Remote mode uses authorization code flow with PKCE S256, exact redirect and resource binding, bounded dynamic client registration, short-lived access tokens, one-time rotating refresh tokens, family lifetime limits, and replay-family revocation.
|
|
120
142
|
|
|
121
|
-
|
|
143
|
+
Codes and tokens bind to client ID, account ID, account version, role, scope, resource, deployment token version, and refresh family.
|
|
122
144
|
|
|
123
|
-
|
|
145
|
+
Supported clients may use DPoP ES256. The Worker verifies proof method, target URL, timestamp, unique identifier, public-key thumbprint, access-token hash, and supported JWS header semantics. Verification alone does not consume global replay capacity: the Worker stores the `jti` replay marker only after the access token or OAuth grant, client, account, and resource are valid. A copied DPoP-bound token is insufficient without the client private key.
|
|
124
146
|
|
|
125
|
-
|
|
147
|
+
Bearer remains available for MCP hosts without DPoP. Bearer possession is therefore a residual risk until token expiry or revocation.
|
|
126
148
|
|
|
127
|
-
|
|
149
|
+
Authorization pages display the validated client name and redirect URI. Enter an account password only after initiating the connection and recognizing both values.
|
|
128
150
|
|
|
129
|
-
|
|
151
|
+
Public health and discovery endpoints do not expose workspace, daemon, account, or tool state.
|
|
130
152
|
|
|
131
|
-
|
|
153
|
+
## Agent instructions, skills, and registered commands
|
|
132
154
|
|
|
133
|
-
|
|
155
|
+
Built-in working agreements and bounded project facts are guidance, not a security boundary. Repository instructions, custom instruction files, script names, and skills are untrusted content and may attempt prompt injection.
|
|
134
156
|
|
|
135
|
-
|
|
157
|
+
Automatic project context does not inject package-script bodies, dependency values, source contents, or execute discovered commands. Skill loading inventories bounded text; scripts remain inert until a separate execution tool is invoked.
|
|
136
158
|
|
|
137
|
-
|
|
159
|
+
Registered commands use fixed argv execution, reject undeclared arguments, and enforce configured timeouts. They are not a trust upgrade: a repository-controlled script or executable can still run arbitrary code within the caller's effective authority.
|
|
138
160
|
|
|
139
|
-
##
|
|
161
|
+
## Browser and application automation
|
|
140
162
|
|
|
141
|
-
|
|
163
|
+
Only `owner` may control the existing browser profile, desktop applications, or export local data into them.
|
|
142
164
|
|
|
143
|
-
|
|
165
|
+
The browser broker:
|
|
144
166
|
|
|
145
|
-
|
|
167
|
+
- listens only on canonical loopback;
|
|
168
|
+
- validates `Host` and extension origin;
|
|
169
|
+
- uses owner-only pairing material;
|
|
170
|
+
- requires protocol, package version, and capability equality;
|
|
171
|
+
- does not let an invalid replacement displace a healthy connection;
|
|
172
|
+
- restricts DevTools use to fixed input commands;
|
|
173
|
+
- does not accept caller-supplied JavaScript, AppleScript, JXA, or arbitrary DevTools methods.
|
|
146
174
|
|
|
147
|
-
-
|
|
148
|
-
- stdin avoids process arguments and environment variables;
|
|
149
|
-
- environment injection can be visible to same-user process inspection and inherited child processes.
|
|
175
|
+
These controls do not make web content trustworthy. Pages may contain prompt injection, deceptive labels, hidden consequences, changing UI state, inaccessible cross-origin frames, or high-value authenticated sessions. Machine Bridge cannot prove the extension is loaded in an isolated profile.
|
|
150
176
|
|
|
151
|
-
|
|
177
|
+
After trusted input dispatch begins, an ambiguous failure is reported as unknown outcome and is not automatically replayed.
|
|
152
178
|
|
|
153
|
-
|
|
179
|
+
Local resources may be injected without returning their bytes through MCP, but the destination page or application still receives them. Screenshots and page source can themselves contain secrets.
|
|
154
180
|
|
|
155
|
-
|
|
181
|
+
## Filesystem and mutation integrity
|
|
156
182
|
|
|
157
|
-
|
|
183
|
+
Workspace-confined profiles canonicalize existing paths and write ancestors. Final symbolic-link writes are rejected. Patch add, update, delete, and move destinations are classified before mutation.
|
|
158
184
|
|
|
159
|
-
|
|
185
|
+
Writes use bounded same-directory staging and atomic replacement. Expected hashes and exact edits reduce stale overwrites. Patch transactions prevalidate all operations, serialize mutation, maintain backups, and roll back ordinary commit errors.
|
|
160
186
|
|
|
161
|
-
|
|
187
|
+
On systems without descriptor-relative traversal, a malicious same-user process can still race parent-directory replacement between validation and open. Machine Bridge does not claim protection from a hostile process with equivalent OS-user authority.
|
|
162
188
|
|
|
163
|
-
|
|
189
|
+
Sensitive and persistence targets are owner-only. Generic remote file tools cannot access Machine Bridge's own control-plane state.
|
|
164
190
|
|
|
165
|
-
##
|
|
191
|
+
## Processes and sessions
|
|
166
192
|
|
|
167
|
-
|
|
193
|
+
Direct processes use argv without shell parsing. Shell expansion is available only through the explicit shell tool.
|
|
168
194
|
|
|
169
|
-
|
|
195
|
+
Process counts, stdin, output, timeouts, retained sessions, and tool-call concurrency are bounded. Timeout, cancellation, disconnect, daemon replacement, and shutdown use process-tree termination with bounded graceful and forced phases.
|
|
170
196
|
|
|
171
|
-
|
|
197
|
+
Interactive process sessions die with runtime disconnect or replacement. Retained output sessions and process control are bound to account, account version, OAuth client, and refresh family.
|
|
172
198
|
|
|
173
|
-
|
|
199
|
+
The daemon does not enforce universal CPU, memory, disk, or network quotas. An authorized owner process can still exhaust host or external resources.
|
|
174
200
|
|
|
175
|
-
##
|
|
201
|
+
## Local resources and managed jobs
|
|
176
202
|
|
|
177
|
-
|
|
203
|
+
Registered resources store canonical paths and bounded metadata, not file contents. Private resource files require restrictive permissions on Unix-like systems unless explicitly overridden.
|
|
178
204
|
|
|
179
|
-
|
|
205
|
+
At job acceptance, referenced resources are reopened, bounded, hashed, and copied into a private runtime area. Changed or unavailable resources fail closed. Environment injection may be visible to same-user process inspection; private file-path substitution or stdin is generally safer.
|
|
180
206
|
|
|
181
|
-
|
|
207
|
+
Managed jobs are durability, not sandboxing. Only `owner` may create remote persistent plans. Long-lived jobs bind to account, account version, OAuth client, and refresh family.
|
|
182
208
|
|
|
183
|
-
|
|
209
|
+
`stage_job` is non-executing and cannot be promoted by a terminal approval command. `machine-mcp job approve` was removed. Execution requires trusted `start_job` authority or an explicit local `machine-mcp job submit PLAN.json` action.
|
|
184
210
|
|
|
185
|
-
|
|
211
|
+
Job output and state are bounded. `finally_steps` are best effort and must be idempotent because recovery may repeat them. Power loss, disk failure, revoked external credentials, or endpoint-security denial can prevent cleanup.
|
|
186
212
|
|
|
187
|
-
|
|
213
|
+
Use `capture_output: "discard"` whenever a process may echo credentials. Never put a secret directly in argv or ordinary JSON plan fields.
|
|
188
214
|
|
|
189
|
-
|
|
215
|
+
## State, locks, and rotation
|
|
190
216
|
|
|
191
|
-
|
|
217
|
+
State roots must be separate from workspaces. State and lock files are owner-only where supported, bounded, schema-validated, and atomically replaced. Process locks bind owner tokens to PID and process start time. Ambiguous or unreadable ownership fails closed.
|
|
192
218
|
|
|
193
|
-
|
|
219
|
+
Device-root migration is two-phase: a pending public root is deployed and health-verified before local promotion. `--daemon-only` refuses to activate an undeployed pending root.
|
|
194
220
|
|
|
195
|
-
|
|
221
|
+
Destructive state removal validates marker files, selected workspace, known layout, lock ownership, service state, and managed-job activity. Unresolved conditions retain state.
|
|
196
222
|
|
|
197
|
-
|
|
223
|
+
## Relay and denial of service
|
|
198
224
|
|
|
199
|
-
|
|
225
|
+
Only one verified daemon is active. Candidates have preflight, hello, readiness, and liveness deadlines. A candidate cannot displace the current daemon before authentication and end-to-end readiness.
|
|
200
226
|
|
|
201
|
-
|
|
227
|
+
Pending calls are bounded, socket-bound, request-bound, timed out, cancellable, and recoverable only for the same verified daemon instance during the documented reconnect grace period.
|
|
202
228
|
|
|
203
|
-
|
|
229
|
+
Request bodies, messages, traversals, files, output, OAuth stores, nonce stores, sessions, and failure identities are bounded. These controls do not replace Cloudflare MFA, WAF/rate limits, billing alerts, or external cost controls.
|
|
204
230
|
|
|
205
|
-
|
|
206
|
-
machine-mcp --workspace /narrow/project --profile review
|
|
207
|
-
```
|
|
231
|
+
## Logs, audit, and privacy
|
|
208
232
|
|
|
209
|
-
|
|
233
|
+
Operational logs omit tool arguments, command text, stdin, file/patch contents, form values, and outputs. Known credential forms, private-key material, embedded-credential URLs, user-home paths, email addresses, and control characters are recursively redacted as defense in depth.
|
|
210
234
|
|
|
211
|
-
|
|
212
|
-
machine-mcp --workspace /narrow/project --profile edit
|
|
213
|
-
```
|
|
235
|
+
The local security audit is a bounded SHA-256 hash chain. It records operation type, risk category, outcome, duration, byte counts, target digest, and salted principal references. It does not record commands, paths, contents, fields, or results.
|
|
214
236
|
|
|
215
|
-
|
|
237
|
+
No logging policy prevents data from being returned to an authorized client that explicitly invokes an enabled tool. Remote arguments and results necessarily traverse the user's Worker and MCP host.
|
|
216
238
|
|
|
217
|
-
|
|
218
|
-
- enable MFA on Cloudflare, GitHub, and npm accounts;
|
|
219
|
-
- do not configure broad CORS origins;
|
|
220
|
-
- keep the state root completely separate from every workspace; never point `--state-dir` at a project directory or one of its ancestors;
|
|
221
|
-
- treat an unreadable or malformed live lock as an incident to inspect, not a file to delete blindly;
|
|
222
|
-
- select `agent`, `edit`, or `review` instead of the default `full` when broad authority is unnecessary;
|
|
223
|
-
- inspect client names and OAuth redirect URIs;
|
|
224
|
-
- rotate one account password after a targeted disclosure, or rotate deployment secrets after a bridge-wide incident;
|
|
225
|
-
- inspect `status`, `doctor`, and service status;
|
|
226
|
-
- register credential files as local resources instead of reading them into a model conversation;
|
|
227
|
-
- use `capture_output: "discard"` for credential-consuming steps and idempotent finally steps for cleanup;
|
|
228
|
-
- remove the Worker and state when remote access is no longer needed;
|
|
229
|
-
- use external OS isolation for untrusted code.
|
|
239
|
+
## Hardening checklist
|
|
230
240
|
|
|
231
|
-
|
|
241
|
+
- Use `review` or `edit` when execution is unnecessary.
|
|
242
|
+
- Use a dedicated OS account, container, or VM for untrusted repositories, prompts, or clients.
|
|
243
|
+
- Enable MFA for Cloudflare, GitHub, npm, and Apple developer accounts.
|
|
244
|
+
- Keep the state root separate from every workspace.
|
|
245
|
+
- Inspect OAuth client names and redirect URIs.
|
|
246
|
+
- Inspect trusted clients and revoke stale records.
|
|
247
|
+
- Prefer DPoP-capable clients where available.
|
|
248
|
+
- Use the portable root unless a separately provisioned macOS trust broker has been installed and validated; never point `MBM_MACOS_TRUST_BROKER` at an ad-hoc or mutable executable.
|
|
249
|
+
- Register credentials as local resources instead of reading them into a model conversation.
|
|
250
|
+
- Use discard capture for credential-consuming jobs and idempotent finally steps.
|
|
251
|
+
- Inspect `status`, `doctor`, `server_info`, service state, delegated-sandbox status, and audit-chain health.
|
|
252
|
+
- Rotate an account password after targeted disclosure; revoke a client after client compromise; rotate the device root and global token version after bridge-wide compromise.
|
|
253
|
+
- Remove the Worker and local state when remote access is no longer required.
|
|
232
254
|
|
|
233
255
|
## Out of scope
|
|
234
256
|
|
|
235
|
-
|
|
257
|
+
Machine Bridge cannot make arbitrary local executables safe, identify all sensitive data, guarantee cleanup across every power/storage/security failure, override MCP-host or endpoint-security policy, neutralize prompt injection, protect against root or a fully compromised same-user account, or manufacture production signing and governance controls.
|
|
258
|
+
|
|
259
|
+
See [docs/AUDIT.md](docs/AUDIT.md) for historical findings and residual limitations.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Machine Bridge Browser",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0",
|
|
5
5
|
"description": "Connects the current Chromium browser profile to the local Machine Bridge runtime for user-authorized automation.",
|
|
6
6
|
"permissions": [
|
|
7
7
|
"tabs",
|
|
@@ -30,5 +30,6 @@
|
|
|
30
30
|
"action": {
|
|
31
31
|
"default_title": "Machine Bridge Browser"
|
|
32
32
|
},
|
|
33
|
-
"version_name": "
|
|
33
|
+
"version_name": "3.0.0-beta.10",
|
|
34
|
+
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxryYkpZhq8+VAQLHcGS9BAHQcyKX8RHGIpIwvtIVRU/rcOcE0bNdnM0aZJ/h6xWQsGDHlhvjT2+1aJaAn/9k8473BRWajzVXld961CdHYVFVHoce2hHiSJ0xydWrHMMZhAm0mN0UzjEpgZ0tMw209efcZHIvSwuxhteZMRy4kyiVjwFlOf5oXFCxRuCJnPj3AK9CmCf4XgEBuPIJ0TZmjGHOOdBvJmbCNnAWXYEo5/mf7MfCGhV4IJ1hNuhpoNQfOFKMUcw9/v/IpT62XpfXdGYTfGYCmCjC+gntK1spbkr2P4/2+sYMQtLpse71mpSNGXfcf3abU55Vpn+gncSxRQIDAQAB"
|
|
34
35
|
}
|