@probelabs/visor 0.1.144 → 0.1.145
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/dist/config.d.ts.map +1 -1
- package/dist/docs/architecture.md +28 -0
- package/dist/docs/configuration.md +2 -0
- package/dist/docs/sandbox-engines.md +357 -0
- package/dist/docs/security.md +40 -0
- package/dist/generated/config-schema.d.ts +5 -0
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +9 -0
- package/dist/index.js +670 -162
- package/dist/output/traces/{run-2026-02-25T17-29-59-894Z.ndjson → run-2026-02-26T07-47-34-788Z.ndjson} +84 -84
- package/dist/{traces/run-2026-02-25T17-30-47-149Z.ndjson → output/traces/run-2026-02-26T07-48-25-935Z.ndjson} +1118 -1118
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/sandbox/bubblewrap-sandbox.d.ts +30 -0
- package/dist/sandbox/bubblewrap-sandbox.d.ts.map +1 -0
- package/dist/sandbox/index.d.ts +3 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/sandbox-manager.d.ts +3 -2
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox/seatbelt-sandbox.d.ts +36 -0
- package/dist/sandbox/seatbelt-sandbox.d.ts.map +1 -0
- package/dist/sandbox/types.d.ts +3 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sdk/{check-provider-registry-VTNNTMWC.mjs → check-provider-registry-HFPKHYTG.mjs} +3 -3
- package/dist/sdk/{check-provider-registry-WBEOZCGW.mjs → check-provider-registry-HK6M4PDQ.mjs} +6 -6
- package/dist/sdk/{check-provider-registry-GKLK3I2X.mjs → check-provider-registry-TG5G2TF3.mjs} +6 -6
- package/dist/sdk/{chunk-D3UC5KUJ.mjs → chunk-5FXGIBJQ.mjs} +467 -100
- package/dist/sdk/chunk-5FXGIBJQ.mjs.map +1 -0
- package/dist/sdk/{chunk-FG6THKK7.mjs → chunk-6XPTQBXL.mjs} +3 -3
- package/dist/sdk/{chunk-FG6THKK7.mjs.map → chunk-6XPTQBXL.mjs.map} +1 -1
- package/dist/sdk/{chunk-N7LW3Q5B.mjs → chunk-E6SMU2Z4.mjs} +467 -100
- package/dist/sdk/chunk-E6SMU2Z4.mjs.map +1 -0
- package/dist/sdk/{chunk-PXWWPPNF.mjs → chunk-GZMQPC6D.mjs} +459 -92
- package/dist/sdk/chunk-GZMQPC6D.mjs.map +1 -0
- package/dist/sdk/{chunk-CLQTOZKH.mjs → chunk-I42ZCVA5.mjs} +3 -3
- package/dist/sdk/chunk-K3M5YVEU.mjs +1502 -0
- package/dist/sdk/chunk-K3M5YVEU.mjs.map +1 -0
- package/dist/sdk/{chunk-PQWAAGUP.mjs → chunk-L3XPYQ6I.mjs} +2 -2
- package/dist/sdk/chunk-L6ABOJVL.mjs +739 -0
- package/dist/sdk/chunk-L6ABOJVL.mjs.map +1 -0
- package/dist/sdk/chunk-OM3WYVFI.mjs +443 -0
- package/dist/sdk/chunk-OM3WYVFI.mjs.map +1 -0
- package/dist/sdk/{chunk-AKCHIYWU.mjs → chunk-YOKAA4IU.mjs} +96 -63
- package/dist/sdk/chunk-YOKAA4IU.mjs.map +1 -0
- package/dist/sdk/{config-KOKJ3PYE.mjs → config-AAB2FL22.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-LWH3NQ2S.mjs → failure-condition-evaluator-O464EJMD.mjs} +3 -3
- package/dist/sdk/failure-condition-evaluator-V3EJGD55.mjs +17 -0
- package/dist/sdk/{github-frontend-UUASYGNV.mjs → github-frontend-MSX6Q2WL.mjs} +3 -3
- package/dist/sdk/github-frontend-PSGUGYHT.mjs +1356 -0
- package/dist/sdk/github-frontend-PSGUGYHT.mjs.map +1 -0
- package/dist/sdk/{host-LAF3NFPZ.mjs → host-5BJ25CUZ.mjs} +2 -2
- package/dist/sdk/host-BYIV4QJ3.mjs +63 -0
- package/dist/sdk/host-BYIV4QJ3.mjs.map +1 -0
- package/dist/sdk/{routing-LEUV6A4K.mjs → routing-AJNUTCH7.mjs} +4 -4
- package/dist/sdk/routing-RIHVCEIU.mjs +25 -0
- package/dist/sdk/{schedule-tool-handler-EYDCUGOB.mjs → schedule-tool-handler-4O2VKNG2.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-W7IB4MK3.mjs → schedule-tool-handler-BTLEDYAI.mjs} +3 -3
- package/dist/sdk/{schedule-tool-handler-7RGTKO24.mjs → schedule-tool-handler-R7PNPWWK.mjs} +6 -6
- package/dist/sdk/sdk.d.mts +3 -1
- package/dist/sdk/sdk.d.ts +3 -1
- package/dist/sdk/sdk.js +568 -168
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +5 -5
- package/dist/sdk/{trace-helpers-NNBQNFWZ.mjs → trace-helpers-OZTZBK6T.mjs} +2 -2
- package/dist/sdk/trace-helpers-QQSTZGDT.mjs +25 -0
- package/dist/sdk/{workflow-check-provider-WW5U6R2P.mjs → workflow-check-provider-3IIKJFM4.mjs} +3 -3
- package/dist/sdk/workflow-check-provider-3IIKJFM4.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-FLBIJQ4Z.mjs → workflow-check-provider-OM62QYHF.mjs} +6 -6
- package/dist/sdk/workflow-check-provider-OM62QYHF.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-2G2CEXFR.mjs → workflow-check-provider-RARO4N5E.mjs} +6 -6
- package/dist/sdk/workflow-check-provider-RARO4N5E.mjs.map +1 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/traces/{run-2026-02-25T17-29-59-894Z.ndjson → run-2026-02-26T07-47-34-788Z.ndjson} +84 -84
- package/dist/{output/traces/run-2026-02-25T17-30-47-149Z.ndjson → traces/run-2026-02-26T07-48-25-935Z.ndjson} +1118 -1118
- package/dist/utils/workspace-manager.d.ts +9 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/sdk/chunk-AKCHIYWU.mjs.map +0 -1
- package/dist/sdk/chunk-D3UC5KUJ.mjs.map +0 -1
- package/dist/sdk/chunk-N7LW3Q5B.mjs.map +0 -1
- package/dist/sdk/chunk-PXWWPPNF.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-GKLK3I2X.mjs.map → check-provider-registry-HFPKHYTG.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-VTNNTMWC.mjs.map → check-provider-registry-HK6M4PDQ.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-WBEOZCGW.mjs.map → check-provider-registry-TG5G2TF3.mjs.map} +0 -0
- /package/dist/sdk/{chunk-CLQTOZKH.mjs.map → chunk-I42ZCVA5.mjs.map} +0 -0
- /package/dist/sdk/{chunk-PQWAAGUP.mjs.map → chunk-L3XPYQ6I.mjs.map} +0 -0
- /package/dist/sdk/{config-KOKJ3PYE.mjs.map → config-AAB2FL22.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-LWH3NQ2S.mjs.map → failure-condition-evaluator-O464EJMD.mjs.map} +0 -0
- /package/dist/sdk/{routing-LEUV6A4K.mjs.map → failure-condition-evaluator-V3EJGD55.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-UUASYGNV.mjs.map → github-frontend-MSX6Q2WL.mjs.map} +0 -0
- /package/dist/sdk/{host-LAF3NFPZ.mjs.map → host-5BJ25CUZ.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-7RGTKO24.mjs.map → routing-AJNUTCH7.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-EYDCUGOB.mjs.map → routing-RIHVCEIU.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-W7IB4MK3.mjs.map → schedule-tool-handler-4O2VKNG2.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-NNBQNFWZ.mjs.map → schedule-tool-handler-BTLEDYAI.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-2G2CEXFR.mjs.map → schedule-tool-handler-R7PNPWWK.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-FLBIJQ4Z.mjs.map → trace-helpers-OZTZBK6T.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-WW5U6R2P.mjs.map → trace-helpers-QQSTZGDT.mjs.map} +0 -0
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/config.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EAGX,YAAY,EAIZ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,YAAY,EAS9C,CAAC;AAEX;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAgBrB;IACF,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,kBAAkB,CAAgE;IAC1F,OAAO,CAAC,mBAAmB,CAA2D;IAEtF;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAU5B;;OAEG;IACU,UAAU,CACrB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAwHvB;;;OAGG;IACU,oBAAoB,CAC/B,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,EACzB,OAAO,GAAE,iBAAiB,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GACrD,OAAO,CAAC,WAAW,CAAC;IAoDvB;;OAEG;IACU,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IA4CrF;;OAEG;YACW,qBAAqB;IAiBnC;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC;IAgBrD;;OAEG;IACI,wBAAwB,IAAI,WAAW,GAAG,IAAI;IA0FrD;;OAEG;IACH,OAAO,CAAC,eAAe;IAuBvB;;;OAGG;YACW,uBAAuB;IAiGrC;;OAEG;YACW,aAAa;IA6B3B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAgC/B;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,YAAY;IAqB9F;;OAEG;IACU,0BAA0B,IAAI,OAAO,CAAC;QACjD,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,oBAAoB,EAAE,oBAAoB,CAAC;KAC5C,CAAC;IA2BF;;;;OAIG;IACI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,UAAQ,GAAG,IAAI;IA4VzE;;OAEG;IACH,OAAO,CAAC,qBAAqB;
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/config.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EAGX,YAAY,EAIZ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,YAAY,EAS9C,CAAC;AAEX;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAgBrB;IACF,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,kBAAkB,CAAgE;IAC1F,OAAO,CAAC,mBAAmB,CAA2D;IAEtF;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAU5B;;OAEG;IACU,UAAU,CACrB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAwHvB;;;OAGG;IACU,oBAAoB,CAC/B,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,EACzB,OAAO,GAAE,iBAAiB,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GACrD,OAAO,CAAC,WAAW,CAAC;IAoDvB;;OAEG;IACU,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IA4CrF;;OAEG;YACW,qBAAqB;IAiBnC;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC;IAgBrD;;OAEG;IACI,wBAAwB,IAAI,WAAW,GAAG,IAAI;IA0FrD;;OAEG;IACH,OAAO,CAAC,eAAe;IAuBvB;;;OAGG;YACW,uBAAuB;IAiGrC;;OAEG;YACW,aAAa;IA6B3B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAgC/B;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,YAAY;IAqB9F;;OAEG;IACU,0BAA0B,IAAI,OAAO,CAAC;QACjD,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,oBAAoB,EAAE,oBAAoB,CAAC;KAC5C,CAAC;IA2BF;;;;OAIG;IACI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,UAAQ,GAAG,IAAI;IA4VzE;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsJ7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA8T3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmM5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA0DhC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAqG7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6DzB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA6EhC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA+B5B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CA6B1B"}
|
|
@@ -897,6 +897,20 @@ workspace:
|
|
|
897
897
|
|
|
898
898
|
This creates isolated directories for each execution, preventing cross-contamination.
|
|
899
899
|
|
|
900
|
+
### Process Sandbox Engines
|
|
901
|
+
|
|
902
|
+
Visor supports three sandbox engines for isolating command execution:
|
|
903
|
+
|
|
904
|
+
| Engine | Platform | Isolation Model |
|
|
905
|
+
|--------|----------|-----------------|
|
|
906
|
+
| **Docker** | Linux, macOS, Windows | Full container isolation |
|
|
907
|
+
| **Bubblewrap** | Linux only | Linux kernel namespaces (PID, mount, network) |
|
|
908
|
+
| **Seatbelt** | macOS only | macOS `sandbox-exec` with SBPL profiles |
|
|
909
|
+
|
|
910
|
+
All three implement the `SandboxInstance` interface and are routed through `SandboxManager`. Configure via the `sandboxes:` block and `sandbox:` default in `.visor.yaml`.
|
|
911
|
+
|
|
912
|
+
See [Sandbox Engines](./sandbox-engines.md) for complete documentation.
|
|
913
|
+
|
|
900
914
|
### Environment Variable Handling
|
|
901
915
|
|
|
902
916
|
Sensitive values can be passed via environment:
|
|
@@ -1045,6 +1059,8 @@ Currently, Visor does not cache AI responses between runs. For expensive operati
|
|
|
1045
1059
|
## Related Documentation
|
|
1046
1060
|
|
|
1047
1061
|
- [Configuration](./configuration.md) - Configuration file reference
|
|
1062
|
+
- [Sandbox Engines](./sandbox-engines.md) - Docker, Bubblewrap, and Seatbelt isolation
|
|
1063
|
+
- [Security](./security.md) - Security overview and best practices
|
|
1048
1064
|
- [Providers](./providers/) - Provider-specific documentation
|
|
1049
1065
|
- [Custom Tools](./custom-tools.md) - Creating custom tools
|
|
1050
1066
|
- [MCP Provider](./mcp-provider.md) - MCP integration details
|
|
@@ -1111,6 +1127,18 @@ src/
|
|
|
1111
1127
|
github/ # GitHub integration frontend
|
|
1112
1128
|
slack/ # Slack integration frontend
|
|
1113
1129
|
|
|
1130
|
+
sandbox/
|
|
1131
|
+
types.ts # SandboxInstance interface, SandboxConfig
|
|
1132
|
+
sandbox-manager.ts # Lifecycle management, engine routing
|
|
1133
|
+
docker-image-sandbox.ts # Docker image-based sandbox
|
|
1134
|
+
docker-compose-sandbox.ts # Docker Compose sandbox
|
|
1135
|
+
bubblewrap-sandbox.ts # Linux namespace isolation (bwrap)
|
|
1136
|
+
seatbelt-sandbox.ts # macOS sandbox-exec isolation
|
|
1137
|
+
check-runner.ts # Check execution in sandboxes
|
|
1138
|
+
env-filter.ts # Environment variable filtering
|
|
1139
|
+
cache-volume-manager.ts # Docker cache volumes
|
|
1140
|
+
sandbox-telemetry.ts # Telemetry for sandbox operations
|
|
1141
|
+
|
|
1114
1142
|
utils/
|
|
1115
1143
|
config-loader.ts # Remote config loading
|
|
1116
1144
|
config-merger.ts # Configuration merging
|
|
@@ -425,6 +425,8 @@ The following global configuration options are available and documented in detai
|
|
|
425
425
|
| `http_server` | HTTP server for receiving webhooks | [HTTP Integration](./http.md) |
|
|
426
426
|
| `memory` | Memory storage configuration | [Memory](./memory.md) |
|
|
427
427
|
| `output` | Output configuration (PR comments, file comments) | [Output Formats](./output-formats.md) |
|
|
428
|
+
| `sandbox` | Default sandbox name for all steps | [Sandbox Engines](./sandbox-engines.md) |
|
|
429
|
+
| `sandboxes` | Named sandbox definitions (Docker, Bubblewrap, Seatbelt) | [Sandbox Engines](./sandbox-engines.md) |
|
|
428
430
|
| `workspace` | Workspace isolation configuration | [Workspace Isolation RFC](./rfc/workspace-isolation.md) |
|
|
429
431
|
|
|
430
432
|
Example combining several options:
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# Sandbox Engines
|
|
2
|
+
|
|
3
|
+
Visor supports three sandbox engines for isolating command execution. Each engine provides different tradeoffs between isolation strength, platform support, and performance.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
| Engine | Platform | Startup Overhead | Dependencies | Isolation Model |
|
|
8
|
+
|--------|----------|-----------------|--------------|-----------------|
|
|
9
|
+
| **Docker** | Linux, macOS, Windows | ~500ms+ | Docker daemon | Full container |
|
|
10
|
+
| **Bubblewrap** | Linux only | ~5-50ms | `bwrap` binary | Linux namespaces |
|
|
11
|
+
| **Seatbelt** | macOS only | ~10-30ms | Built-in (`sandbox-exec`) | SBPL policy profiles |
|
|
12
|
+
|
|
13
|
+
All three engines implement the same `SandboxInstance` interface and are configured through the same `sandboxes:` config block. The `engine` field determines which backend handles execution.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
# .visor.yaml
|
|
19
|
+
sandboxes:
|
|
20
|
+
# Linux: use bubblewrap for lightweight isolation
|
|
21
|
+
bwrap:
|
|
22
|
+
engine: bubblewrap
|
|
23
|
+
network: true
|
|
24
|
+
|
|
25
|
+
# macOS: use seatbelt for native isolation
|
|
26
|
+
mac:
|
|
27
|
+
engine: seatbelt
|
|
28
|
+
network: true
|
|
29
|
+
|
|
30
|
+
# Any platform: use Docker for full container isolation
|
|
31
|
+
docker:
|
|
32
|
+
image: node:20-alpine
|
|
33
|
+
|
|
34
|
+
# Default all steps to a sandbox
|
|
35
|
+
sandbox: bwrap # or mac, or docker
|
|
36
|
+
|
|
37
|
+
steps:
|
|
38
|
+
lint:
|
|
39
|
+
type: command
|
|
40
|
+
exec: eslint src/
|
|
41
|
+
|
|
42
|
+
build:
|
|
43
|
+
type: command
|
|
44
|
+
sandbox: docker # Override: use Docker for this step
|
|
45
|
+
exec: npm run build
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
### Common Options
|
|
51
|
+
|
|
52
|
+
These options apply to all engine types:
|
|
53
|
+
|
|
54
|
+
| Field | Type | Default | Description |
|
|
55
|
+
|-------|------|---------|-------------|
|
|
56
|
+
| `engine` | `'docker' \| 'bubblewrap' \| 'seatbelt'` | `'docker'` | Sandbox engine backend |
|
|
57
|
+
| `network` | `boolean` | `true` | Enable/disable network access |
|
|
58
|
+
| `read_only` | `boolean` | `false` | Mount repository as read-only |
|
|
59
|
+
| `workdir` | `string` | `'/workspace'` | Working directory inside sandbox (Docker/Bubblewrap only) |
|
|
60
|
+
| `env_passthrough` | `string[]` | — | Glob patterns for host env vars to forward |
|
|
61
|
+
|
|
62
|
+
### Docker-Only Options
|
|
63
|
+
|
|
64
|
+
These fields are only valid when `engine` is `'docker'` (or omitted):
|
|
65
|
+
|
|
66
|
+
| Field | Type | Description |
|
|
67
|
+
|-------|------|-------------|
|
|
68
|
+
| `image` | `string` | Docker image (e.g., `node:20-alpine`) |
|
|
69
|
+
| `dockerfile` | `string` | Path to Dockerfile |
|
|
70
|
+
| `dockerfile_inline` | `string` | Inline Dockerfile content |
|
|
71
|
+
| `compose` | `string` | Path to docker-compose file |
|
|
72
|
+
| `service` | `string` | Service name within compose file |
|
|
73
|
+
| `resources` | `object` | Memory/CPU limits (`memory: '512m'`, `cpu: 1.0`) |
|
|
74
|
+
| `cache` | `object` | Cache volume configuration |
|
|
75
|
+
| `visor_path` | `string` | Where visor is mounted inside container |
|
|
76
|
+
|
|
77
|
+
Using Docker-only fields with `engine: bubblewrap` or `engine: seatbelt` produces a validation error.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Bubblewrap Engine
|
|
82
|
+
|
|
83
|
+
Bubblewrap (`bwrap`) provides lightweight process isolation using Linux kernel namespaces. It creates an isolated filesystem view, PID namespace, and optionally isolated network for each command execution.
|
|
84
|
+
|
|
85
|
+
### Requirements
|
|
86
|
+
|
|
87
|
+
- **Linux only** (uses kernel namespaces, which are not available on macOS/Windows)
|
|
88
|
+
- `bwrap` binary must be installed:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Debian / Ubuntu
|
|
92
|
+
apt install bubblewrap
|
|
93
|
+
|
|
94
|
+
# Fedora / RHEL / CentOS
|
|
95
|
+
dnf install bubblewrap
|
|
96
|
+
|
|
97
|
+
# Arch Linux
|
|
98
|
+
pacman -S bubblewrap
|
|
99
|
+
|
|
100
|
+
# Alpine
|
|
101
|
+
apk add bubblewrap
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### How It Works
|
|
105
|
+
|
|
106
|
+
Each `exec()` call spawns a fresh `bwrap` process with:
|
|
107
|
+
|
|
108
|
+
1. **Mount namespace**: Read-only system dirs (`/usr`, `/bin`, `/lib`, `/etc`) + writable workspace at `/workspace`
|
|
109
|
+
2. **PID namespace**: Sandboxed process cannot see host PIDs (`--unshare-pid`)
|
|
110
|
+
3. **Clean environment**: `--clearenv` strips all host env vars; only explicitly passed vars are visible (`--setenv`)
|
|
111
|
+
4. **Session isolation**: `--new-session` prevents terminal injection attacks
|
|
112
|
+
5. **Orphan cleanup**: `--die-with-parent` kills sandbox if parent dies
|
|
113
|
+
6. **Network isolation**: `--unshare-net` when `network: false`
|
|
114
|
+
|
|
115
|
+
### Configuration
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
sandboxes:
|
|
119
|
+
bwrap:
|
|
120
|
+
engine: bubblewrap
|
|
121
|
+
network: true # Allow network access (default: true)
|
|
122
|
+
read_only: false # Writable workspace (default: false)
|
|
123
|
+
workdir: /workspace # Working directory inside sandbox (default: /workspace)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Filesystem Layout Inside Sandbox
|
|
127
|
+
|
|
128
|
+
| Path | Access | Source |
|
|
129
|
+
|------|--------|--------|
|
|
130
|
+
| `/workspace` | Read-write (or read-only) | Host repository directory |
|
|
131
|
+
| `/usr`, `/bin`, `/lib` | Read-only | Host system directories |
|
|
132
|
+
| `/etc/resolv.conf`, `/etc/ssl` | Read-only | DNS and TLS certificates |
|
|
133
|
+
| `/tmp` | Read-write | Fresh tmpfs per execution |
|
|
134
|
+
| `/dev`, `/proc` | Minimal | Virtual filesystems |
|
|
135
|
+
| `~/.ssh`, `~/.aws`, `~/.config` | **Not mounted** | Inaccessible |
|
|
136
|
+
|
|
137
|
+
### Security Properties
|
|
138
|
+
|
|
139
|
+
| Property | Status |
|
|
140
|
+
|----------|--------|
|
|
141
|
+
| Filesystem isolation | Commands cannot access files outside allowed paths |
|
|
142
|
+
| Process isolation | PID namespace hides other processes |
|
|
143
|
+
| Environment isolation | `--clearenv` prevents credential theft |
|
|
144
|
+
| Terminal injection | `--new-session` prevents TIOCSTI attacks |
|
|
145
|
+
| Orphan cleanup | `--die-with-parent` ensures cleanup |
|
|
146
|
+
| Network isolation | Optional via `--unshare-net` |
|
|
147
|
+
| Resource limits | Not enforced (use cgroups separately) |
|
|
148
|
+
|
|
149
|
+
### CI/CD Notes
|
|
150
|
+
|
|
151
|
+
- Works in unprivileged CI runners (no Docker-in-Docker needed)
|
|
152
|
+
- May need `--cap-add SYS_ADMIN` or `--privileged` when running inside Docker containers
|
|
153
|
+
- On non-Linux platforms, `engine: bubblewrap` will fail at runtime with a clear error
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Seatbelt Engine
|
|
158
|
+
|
|
159
|
+
Seatbelt uses macOS's built-in `sandbox-exec` with dynamically-generated SBPL (Seatbelt Profile Language) profiles. Unlike bubblewrap, it does not create mount namespaces — commands see the real filesystem but are restricted by ACL-style policy rules.
|
|
160
|
+
|
|
161
|
+
### Requirements
|
|
162
|
+
|
|
163
|
+
- **macOS only** (`sandbox-exec` ships with macOS)
|
|
164
|
+
- No additional installation needed
|
|
165
|
+
|
|
166
|
+
### How It Works
|
|
167
|
+
|
|
168
|
+
Each `exec()` call:
|
|
169
|
+
|
|
170
|
+
1. **Generates an SBPL profile** with `(deny default)` base policy and explicit `(allow ...)` rules
|
|
171
|
+
2. **Runs** `sandbox-exec -p '<profile>' /usr/bin/env -i KEY=VAL ... /bin/sh -c '<command>'`
|
|
172
|
+
3. **Resolves symlinks** via `realpathSync` (macOS uses `/var` -> `/private/var`, `/tmp` -> `/private/tmp`)
|
|
173
|
+
4. **Cleans environment** using `env -i` (sandbox-exec inherits parent env, unlike bubblewrap's `--clearenv`)
|
|
174
|
+
|
|
175
|
+
### Configuration
|
|
176
|
+
|
|
177
|
+
```yaml
|
|
178
|
+
sandboxes:
|
|
179
|
+
mac:
|
|
180
|
+
engine: seatbelt
|
|
181
|
+
network: true # Allow network access (default: true)
|
|
182
|
+
read_only: false # Writable workspace (default: false)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Note: The `workdir` field is ignored for seatbelt — commands run from the real repository path (no mount remapping).
|
|
186
|
+
|
|
187
|
+
### SBPL Profile
|
|
188
|
+
|
|
189
|
+
The generated profile follows a deny-by-default model:
|
|
190
|
+
|
|
191
|
+
```scheme
|
|
192
|
+
(version 1)
|
|
193
|
+
(deny default)
|
|
194
|
+
|
|
195
|
+
;; Process execution
|
|
196
|
+
(allow process-exec)
|
|
197
|
+
(allow process-fork)
|
|
198
|
+
|
|
199
|
+
;; System paths (read-only)
|
|
200
|
+
(allow file-read*
|
|
201
|
+
(literal "/")
|
|
202
|
+
(subpath "/usr") (subpath "/bin") (subpath "/sbin")
|
|
203
|
+
(subpath "/Library") (subpath "/System")
|
|
204
|
+
(subpath "/private") (subpath "/var") (subpath "/etc")
|
|
205
|
+
(subpath "/dev") (subpath "/tmp"))
|
|
206
|
+
|
|
207
|
+
;; Temp and device writes
|
|
208
|
+
(allow file-write*
|
|
209
|
+
(subpath "/tmp") (subpath "/private/tmp") (subpath "/dev"))
|
|
210
|
+
|
|
211
|
+
;; xcrun cache (macOS Xcode tools)
|
|
212
|
+
(allow file-write* (regex #"/private/var/folders/.*/T/xcrun_db"))
|
|
213
|
+
|
|
214
|
+
;; Workspace access
|
|
215
|
+
(allow file-read* (subpath "/path/to/repo"))
|
|
216
|
+
(allow file-write* (subpath "/path/to/repo")) ;; omitted when read_only
|
|
217
|
+
|
|
218
|
+
;; Network (omitted when network: false)
|
|
219
|
+
(allow network*)
|
|
220
|
+
|
|
221
|
+
;; System operations
|
|
222
|
+
(allow sysctl-read)
|
|
223
|
+
(allow mach-lookup)
|
|
224
|
+
(allow signal)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Filesystem Access Inside Sandbox
|
|
228
|
+
|
|
229
|
+
| Path | Access | Notes |
|
|
230
|
+
|------|--------|-------|
|
|
231
|
+
| Repository directory | Read-write (or read-only) | Real filesystem path |
|
|
232
|
+
| `/usr`, `/bin`, `/Library`, `/System` | Read-only | System binaries and libraries |
|
|
233
|
+
| `/private`, `/var`, `/etc` | Read-only | System config (symlink-resolved) |
|
|
234
|
+
| `/tmp` | Read-write | Temporary files |
|
|
235
|
+
| `~/Documents`, `~/Desktop` | **Denied** | "Operation not permitted" |
|
|
236
|
+
| `~/.ssh`, `~/.aws`, `~/.claude` | **Denied** | "Operation not permitted" |
|
|
237
|
+
| `~/.gitconfig`, `~/.zsh_history` | **Denied** | "Operation not permitted" |
|
|
238
|
+
|
|
239
|
+
### Security Properties
|
|
240
|
+
|
|
241
|
+
| Property | Status |
|
|
242
|
+
|----------|--------|
|
|
243
|
+
| Filesystem isolation | ACL-style policy blocks access to unauthorized paths |
|
|
244
|
+
| Process isolation | Limited (no PID namespace) |
|
|
245
|
+
| Environment isolation | `env -i` strips inherited vars; only explicitly passed vars visible |
|
|
246
|
+
| Network isolation | Optional via omitting `(allow network*)` rule |
|
|
247
|
+
| Resource limits | Not enforced |
|
|
248
|
+
| Write protection | `read_only: true` omits file-write rules for workspace |
|
|
249
|
+
|
|
250
|
+
### Known Limitations
|
|
251
|
+
|
|
252
|
+
- **No mount namespaces**: Commands see real filesystem paths (no `/workspace` remapping)
|
|
253
|
+
- **Git worktrees**: If the repository is a git worktree, the `.git` file points outside the repo directory. Git commands may fail because the parent `.git` directory is not in the allowed paths. Standalone git repos work fine.
|
|
254
|
+
- **Deprecated API**: Apple has deprecated `sandbox-exec` but it remains functional on current macOS versions. There is no replacement API for command-line use.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Choosing an Engine
|
|
259
|
+
|
|
260
|
+
### Use Docker When
|
|
261
|
+
|
|
262
|
+
- You need custom runtimes, specific OS packages, or language versions
|
|
263
|
+
- Full container isolation is required
|
|
264
|
+
- Cross-platform consistency matters
|
|
265
|
+
- You need cache volumes for persistent caches (e.g., `node_modules`)
|
|
266
|
+
|
|
267
|
+
### Use Bubblewrap When
|
|
268
|
+
|
|
269
|
+
- Running on Linux and need fast, lightweight isolation
|
|
270
|
+
- CI runners don't have Docker available
|
|
271
|
+
- You're running many short-lived commands (the ~5-50ms overhead adds up much less than Docker's ~500ms)
|
|
272
|
+
- You need namespace-level isolation (PID, mount, network) without containers
|
|
273
|
+
|
|
274
|
+
### Use Seatbelt When
|
|
275
|
+
|
|
276
|
+
- Running on macOS (local development, macOS CI runners)
|
|
277
|
+
- You want filesystem and network restrictions without Docker
|
|
278
|
+
- You want near-zero setup (sandbox-exec is built into macOS)
|
|
279
|
+
|
|
280
|
+
### Mixing Engines
|
|
281
|
+
|
|
282
|
+
You can define multiple sandboxes with different engines and assign them per-step:
|
|
283
|
+
|
|
284
|
+
```yaml
|
|
285
|
+
sandboxes:
|
|
286
|
+
fast:
|
|
287
|
+
engine: bubblewrap # Quick commands
|
|
288
|
+
network: false
|
|
289
|
+
|
|
290
|
+
full:
|
|
291
|
+
image: node:20-alpine # Heavy builds
|
|
292
|
+
cache:
|
|
293
|
+
paths: [node_modules]
|
|
294
|
+
|
|
295
|
+
sandbox: fast # Default to bubblewrap
|
|
296
|
+
|
|
297
|
+
steps:
|
|
298
|
+
lint:
|
|
299
|
+
type: command
|
|
300
|
+
exec: eslint src/ # Uses bubblewrap (fast)
|
|
301
|
+
|
|
302
|
+
build:
|
|
303
|
+
type: command
|
|
304
|
+
sandbox: full # Uses Docker (full isolation)
|
|
305
|
+
exec: npm run build
|
|
306
|
+
|
|
307
|
+
test:
|
|
308
|
+
type: command
|
|
309
|
+
exec: npm test # Uses bubblewrap (fast)
|
|
310
|
+
read_only: true
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Credential Propagation
|
|
316
|
+
|
|
317
|
+
All sandbox engines work with Visor's credential propagation system. The `injectGitHubCredentials()` function from `src/github-auth.ts` passes authentication via environment variables:
|
|
318
|
+
|
|
319
|
+
- `GITHUB_TOKEN` / `GH_TOKEN` for `gh` CLI
|
|
320
|
+
- `GIT_CONFIG_COUNT` / `GIT_CONFIG_KEY_*` / `GIT_CONFIG_VALUE_*` for authenticated `git` HTTPS access
|
|
321
|
+
|
|
322
|
+
No temp files are written and no global git config is modified, so credentials work inside any sandbox engine without special handling.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Environment Variable Filtering
|
|
327
|
+
|
|
328
|
+
Before commands execute in any sandbox engine, environment variables pass through `filterEnvForSandbox()` from `src/sandbox/env-filter.ts`. This applies glob-based patterns from `env_passthrough` config and a built-in passthrough list (`PATH`, `HOME`, `USER`, `CI`, `NODE_ENV`, `LANG`).
|
|
329
|
+
|
|
330
|
+
Only filtered variables are passed into the sandbox:
|
|
331
|
+
- **Bubblewrap**: Via `--setenv KEY VALUE` args
|
|
332
|
+
- **Seatbelt**: Via `env -i KEY=VALUE` args
|
|
333
|
+
- **Docker**: Via `-e KEY=VALUE` args to `docker exec`
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Telemetry
|
|
338
|
+
|
|
339
|
+
All sandbox engines emit telemetry events:
|
|
340
|
+
|
|
341
|
+
| Event | Attributes |
|
|
342
|
+
|-------|-----------|
|
|
343
|
+
| `visor.sandbox.bwrap.exec` | `visor.sandbox.name`, `visor.sandbox.exit_code` |
|
|
344
|
+
| `visor.sandbox.seatbelt.exec` | `visor.sandbox.name`, `visor.sandbox.exit_code` |
|
|
345
|
+
| `visor.sandbox.docker.exec` | `visor.sandbox.name`, `visor.sandbox.exit_code` |
|
|
346
|
+
|
|
347
|
+
These integrate with Visor's OpenTelemetry tracing via `src/sandbox/sandbox-telemetry.ts`.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Related Documentation
|
|
352
|
+
|
|
353
|
+
- [Configuration](./configuration.md) - General configuration and `sandboxes:` block
|
|
354
|
+
- [Security](./security.md) - Security overview and best practices
|
|
355
|
+
- [Command Provider](./command-provider.md) - Command execution in sandboxes
|
|
356
|
+
- [GitHub Authentication](./github-auth.md) - Credential propagation into sandboxes
|
|
357
|
+
- [Architecture](./architecture.md) - System architecture overview
|
package/dist/docs/security.md
CHANGED
|
@@ -226,6 +226,45 @@ This protection is implemented in the configuration loader and applies to:
|
|
|
226
226
|
|
|
227
227
|
---
|
|
228
228
|
|
|
229
|
+
## Process Sandbox Engines
|
|
230
|
+
|
|
231
|
+
Visor supports three sandbox engines that isolate command execution from the host system:
|
|
232
|
+
|
|
233
|
+
| Engine | Platform | Isolation Model |
|
|
234
|
+
|--------|----------|-----------------|
|
|
235
|
+
| **Docker** | Linux, macOS, Windows | Full container isolation |
|
|
236
|
+
| **Bubblewrap** | Linux only | Linux kernel namespaces (PID, mount, network) |
|
|
237
|
+
| **Seatbelt** | macOS only | `sandbox-exec` with SBPL deny-by-default profiles |
|
|
238
|
+
|
|
239
|
+
### What Sandboxes Protect Against
|
|
240
|
+
|
|
241
|
+
- **Filesystem escape**: Commands cannot access files outside allowed paths (`~/.ssh`, `~/.aws`, `~/.config` are inaccessible)
|
|
242
|
+
- **Environment leakage**: All engines strip inherited environment variables; only explicitly passed vars are visible
|
|
243
|
+
- **Network exfiltration**: Optional network isolation (`network: false`) blocks all network access
|
|
244
|
+
- **Process visibility**: Bubblewrap uses PID namespaces to hide host processes
|
|
245
|
+
|
|
246
|
+
### What Sandboxes Do NOT Protect Against
|
|
247
|
+
|
|
248
|
+
- **CPU/Memory abuse**: No resource limits enforced by bubblewrap or seatbelt (use Docker `resources:` or external cgroups)
|
|
249
|
+
- **Kernel exploits**: Namespace escapes via kernel bugs (bubblewrap/seatbelt are not full VMs)
|
|
250
|
+
- **Network attacks**: When `network: true` (the default), sandboxed commands have full network access
|
|
251
|
+
|
|
252
|
+
### Credential Isolation in Sandboxes
|
|
253
|
+
|
|
254
|
+
| Resource | Without Sandbox | With Sandbox |
|
|
255
|
+
|----------|----------------|--------------|
|
|
256
|
+
| `~/.ssh/` | Accessible | Not mounted / denied |
|
|
257
|
+
| `~/.aws/` | Accessible | Not mounted / denied |
|
|
258
|
+
| `~/.gitconfig` | Accessible | Not mounted / denied (git auth via env vars) |
|
|
259
|
+
| `~/.config/gh/` | Accessible | Not mounted / denied |
|
|
260
|
+
| Host env vars | All inherited | Only explicitly passed vars |
|
|
261
|
+
|
|
262
|
+
GitHub credentials are propagated securely via environment variables (`GITHUB_TOKEN`, `GIT_CONFIG_COUNT`/`KEY`/`VALUE`), so authenticated git and `gh` CLI operations work inside any sandbox engine without exposing credential files.
|
|
263
|
+
|
|
264
|
+
See [Sandbox Engines](./sandbox-engines.md) for complete configuration and usage documentation.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
229
268
|
## Command Provider Security
|
|
230
269
|
|
|
231
270
|
The command provider executes shell commands with security safeguards.
|
|
@@ -465,6 +504,7 @@ See [Configuration](./configuration.md) for complete extends documentation.
|
|
|
465
504
|
|
|
466
505
|
## Related Documentation
|
|
467
506
|
|
|
507
|
+
- [Sandbox Engines](./sandbox-engines.md) - Process isolation with Docker, Bubblewrap, and Seatbelt
|
|
468
508
|
- [GitHub Authentication](./github-auth.md) - Token and GitHub App auth setup, credential propagation
|
|
469
509
|
- [AI Configuration](./ai-configuration.md) - AI provider security options
|
|
470
510
|
- [HTTP Integration](./http.md) - HTTP authentication and TLS
|
|
@@ -2202,6 +2202,11 @@ export declare const configSchema: {
|
|
|
2202
2202
|
readonly SandboxConfig: {
|
|
2203
2203
|
readonly type: "object";
|
|
2204
2204
|
readonly properties: {
|
|
2205
|
+
readonly engine: {
|
|
2206
|
+
readonly type: "string";
|
|
2207
|
+
readonly enum: readonly ["docker", "bubblewrap", "seatbelt"];
|
|
2208
|
+
readonly description: "Sandbox engine type: 'docker' (default), 'bubblewrap' (Linux namespaces), or 'seatbelt' (macOS sandbox-exec)";
|
|
2209
|
+
};
|
|
2205
2210
|
readonly image: {
|
|
2206
2211
|
readonly type: "string";
|
|
2207
2212
|
readonly description: "Docker image to use (e.g., \"node:20-alpine\")";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/generated/config-schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/generated/config-schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAw4Ff,CAAC;AACX,eAAe,YAAY,CAAC"}
|
|
@@ -2431,6 +2431,15 @@
|
|
|
2431
2431
|
"SandboxConfig": {
|
|
2432
2432
|
"type": "object",
|
|
2433
2433
|
"properties": {
|
|
2434
|
+
"engine": {
|
|
2435
|
+
"type": "string",
|
|
2436
|
+
"enum": [
|
|
2437
|
+
"docker",
|
|
2438
|
+
"bubblewrap",
|
|
2439
|
+
"seatbelt"
|
|
2440
|
+
],
|
|
2441
|
+
"description": "Sandbox engine type: 'docker' (default), 'bubblewrap' (Linux namespaces), or 'seatbelt' (macOS sandbox-exec)"
|
|
2442
|
+
},
|
|
2434
2443
|
"image": {
|
|
2435
2444
|
"type": "string",
|
|
2436
2445
|
"description": "Docker image to use (e.g., \"node:20-alpine\")"
|