From 0d27eb17fdb695d2f0f151c17169334966f7ad73 Mon Sep 17 00:00:00 2001 From: trim21 Date: Tue, 7 Jul 2026 12:42:42 +0800 Subject: [PATCH 1/5] feat(sandbox): add configurable writable paths option Add experimental.sandbox_writable_paths config option that allows users to specify additional filesystem paths the sandbox permits writes to. These paths are merged with the default writable paths when the sandbox is active. CLI: new config field + policy integration VS Code: list input UI in the Sandboxing settings tab --- .../src/components/settings/SandboxingTab.tsx | 90 ++++++++++++++++++- .../kilo-vscode/webview-ui/src/i18n/en.ts | 3 + .../webview-ui/src/types/messages/config.ts | 1 + packages/opencode/src/config/config.ts | 4 + .../opencode/src/kilocode/sandbox/policy.ts | 11 ++- 5 files changed, 105 insertions(+), 4 deletions(-) diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx index e67ec17c7aac..6e69d7b14d4c 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx @@ -1,16 +1,44 @@ -import { Component, createMemo } from "solid-js" +import { Component, For, createMemo, createSignal } from "solid-js" import { Card } from "@kilocode/kilo-ui/card" import { Switch } from "@kilocode/kilo-ui/switch" +import { TextField } from "@kilocode/kilo-ui/text-field" +import { Button } from "@kilocode/kilo-ui/button" +import { IconButton } from "@kilocode/kilo-ui/icon-button" import { useConfig } from "../../context/config" import { useLanguage } from "../../context/language" import SettingsRow from "./SettingsRow" const description = "sandbox-network-description" +const writablePathsDescription = "sandbox-writable-paths-description" const SandboxingTab: Component = () => { const { config, updateConfig } = useConfig() const language = useLanguage() const experimental = createMemo(() => config().experimental ?? {}) + const [newPath, setNewPath] = createSignal("") + + const writablePaths = () => experimental().sandbox_writable_paths ?? [] + + const addPath = () => { + const value = newPath().trim() + if (!value) return + const current = [...writablePaths()] + if (!current.includes(value)) { + current.push(value) + updateConfig({ + experimental: { ...experimental(), sandbox_writable_paths: current }, + }) + } + setNewPath("") + } + + const removePath = (index: number) => { + const current = [...writablePaths()] + current.splice(index, 1) + updateConfig({ + experimental: { ...experimental(), sandbox_writable_paths: current }, + }) + } return ( @@ -18,7 +46,6 @@ const SandboxingTab: Component = () => { title={language.t("settings.sandboxing.network.title")} description={language.t("settings.sandboxing.network.description")} descriptionId={description} - last > { {language.t("settings.sandboxing.network.title")} + + +
+
0 ? "1px solid var(--border-weak-base)" : "none", + }} + > +
+ setNewPath(val)} + onKeyDown={(e: KeyboardEvent) => { + if (e.key === "Enter") addPath() + }} + hideLabel + label={language.t("settings.sandboxing.writablePaths.title")} + /> +
+ +
+ + {(path, index) => ( +
+ + {path} + + removePath(index())} /> +
+ )} +
+
+
) } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/en.ts b/packages/kilo-vscode/webview-ui/src/i18n/en.ts index d4435bcf03fd..a15b69132729 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/en.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/en.ts @@ -1422,6 +1422,9 @@ export const dict = { "settings.sandboxing.network.title": "Restrict Network Access", "settings.sandboxing.network.description": "Block outbound network access from model-originated commands and HTTP tools. Local MCP servers and plugin hooks run outside this restriction. Provider and model inference traffic remains available.", + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP Timeout (ms)", "settings.experimental.mcpTimeout.description": "Timeout for MCP server requests in milliseconds", "settings.experimental.remote.title": "Remote Control", diff --git a/packages/kilo-vscode/webview-ui/src/types/messages/config.ts b/packages/kilo-vscode/webview-ui/src/types/messages/config.ts index 8ceed88a130d..cf7fefb2cfeb 100644 --- a/packages/kilo-vscode/webview-ui/src/types/messages/config.ts +++ b/packages/kilo-vscode/webview-ui/src/types/messages/config.ts @@ -48,6 +48,7 @@ export interface ExperimentalConfig { mcp_timeout?: number sandbox?: boolean sandbox_restrict_network?: boolean + sandbox_writable_paths?: string[] } export interface CommitMessageConfig { diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index be259ff3d9d4..eae0c08f1c49 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -418,6 +418,10 @@ export const Info = Schema.Struct({ description: "Restrict outbound network access for model-originated commands and first-party HTTP tools; local MCP servers and plugin hooks are not covered (default: true)", }), + sandbox_writable_paths: Schema.optional(Schema.mutable(Schema.Array(Schema.String))).annotate({ + description: + "Additional filesystem paths the sandbox allows writes to (e.g. ['/tmp', '/var/log']). These are merged with the default writable paths when the sandbox is active.", + }), // kilocode_change end mcp_timeout: Schema.optional(PositiveInt).annotate({ description: "Timeout in milliseconds for model context protocol (MCP) requests", diff --git a/packages/opencode/src/kilocode/sandbox/policy.ts b/packages/opencode/src/kilocode/sandbox/policy.ts index c02d66e5bc8d..ad0611db7296 100644 --- a/packages/opencode/src/kilocode/sandbox/policy.ts +++ b/packages/opencode/src/kilocode/sandbox/policy.ts @@ -92,7 +92,11 @@ function isolated(ctx: InstanceContext) { return linked(path.resolve(ctx.directory), path.resolve(ctx.worktree)) } -export function profile(ctx: InstanceContext, mode: Profile["network"]["mode"] = "deny"): Profile { +export function profile( + ctx: InstanceContext, + mode: Profile["network"]["mode"] = "deny", + extraWritable?: readonly string[], +): Profile { const project = isolated(ctx) ? [ctx.directory] : ctx.directory === ctx.worktree @@ -108,6 +112,7 @@ export function profile(ctx: InstanceContext, mode: Profile["network"]["mode"] = Global.Path.bin, Global.Path.log, Global.Path.repos, + ...(extraWritable ?? []), ].map(root) return { filesystem: { @@ -297,7 +302,9 @@ function execute(sessionID: SessionID, effect: Effect.Effect) const current = yield* snapshot(sessionID) const support = backendSupport({ mode: current.state.mode, allowedHosts: [] }) if (!current.state.enabled || !support.available) return yield* unrestricted(effect) - return yield* runSandbox(profile(yield* InstanceState.context, current.state.mode), effect) + const cfg = yield* (yield* Config.Service).get() + const extraWritable = cfg.experimental?.sandbox_writable_paths + return yield* runSandbox(profile(yield* InstanceState.context, current.state.mode, extraWritable), effect) }) } From 1fc36e2e83e911af25aab780082f0c07f8593889 Mon Sep 17 00:00:00 2001 From: trim21 Date: Tue, 7 Jul 2026 12:54:27 +0800 Subject: [PATCH 2/5] fix(i18n): translate sandbox writable paths for zh/zht and add keys to all locales --- packages/kilo-vscode/webview-ui/src/i18n/ar.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/br.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/bs.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/da.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/de.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/es.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/fr.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/it.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/ja.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/ko.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/nl.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/no.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/pl.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/ru.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/th.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/tr.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/uk.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/zh.ts | 4 ++++ packages/kilo-vscode/webview-ui/src/i18n/zht.ts | 4 ++++ 19 files changed, 76 insertions(+) diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ar.ts b/packages/kilo-vscode/webview-ui/src/i18n/ar.ts index a87c8ac9b6c9..62c7b7bce9cb 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ar.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ar.ts @@ -1411,6 +1411,10 @@ export const dict = { "settings.sandboxing.network.title": "تقييد الوصول إلى الشبكة", "settings.sandboxing.network.description": "احظر الوصول الصادر إلى الشبكة من الأوامر الصادرة عن النموذج وأدوات HTTP. تعمل خوادم MCP المحلية وخطافات المكونات الإضافية خارج هذا التقييد. تظل حركة مرور استدلال الموفّر والنموذج متاحة.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "مهلة MCP (مللي ثانية)", "settings.experimental.mcpTimeout.description": "مهلة طلبات خادم MCP بالمللي ثانية", "settings.experimental.remote.title": "التحكم Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/br.ts b/packages/kilo-vscode/webview-ui/src/i18n/br.ts index 5daf082020eb..531b64e51987 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/br.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/br.ts @@ -1447,6 +1447,10 @@ export const dict = { "settings.sandboxing.network.title": "Restringir acesso à rede", "settings.sandboxing.network.description": "Bloqueie o acesso de saída à rede para comandos originados pelo modelo e ferramentas HTTP. Servidores MCP locais e hooks de plugins são executados fora dessa restrição. O tráfego de inferência de provedores e modelos permanece disponível.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Tempo limite MCP (ms)", "settings.experimental.mcpTimeout.description": "Tempo limite para solicitações do servidor MCP em milissegundos", "settings.experimental.remote.title": "Controle Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/bs.ts b/packages/kilo-vscode/webview-ui/src/i18n/bs.ts index a5a894c7f0f9..08eac42dbb30 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/bs.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/bs.ts @@ -1443,6 +1443,10 @@ export const dict = { "settings.sandboxing.network.title": "Ograniči pristup mreži", "settings.sandboxing.network.description": "Blokiraj odlazni mrežni pristup za naredbe koje potiču od modela i HTTP alate. Lokalni MCP serveri i hookovi dodataka izvršavaju se izvan ovog ograničenja. Saobraćaj za inferenciju pružatelja i modela ostaje dostupan.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP istek vremena (ms)", "settings.experimental.mcpTimeout.description": "Istek vremena za MCP server zahtjeve u milisekundama", "settings.experimental.remote.title": "Remote kontrola", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/da.ts b/packages/kilo-vscode/webview-ui/src/i18n/da.ts index 14b21e2ab808..8084198a5c95 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/da.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/da.ts @@ -1437,6 +1437,10 @@ export const dict = { "settings.sandboxing.network.title": "Begræns netværksadgang", "settings.sandboxing.network.description": "Bloker udgående netværksadgang fra kommandoer, der stammer fra modellen, og HTTP-værktøjer. Lokale MCP-servere og plugin-hooks er ikke underlagt denne begrænsning. Inferenstrafik til udbydere og modeller er fortsat tilgængelig.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP-timeout (ms)", "settings.experimental.mcpTimeout.description": "Timeout for MCP-serveranmodninger i millisekunder", "settings.experimental.remote.title": "Remote-styring", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/de.ts b/packages/kilo-vscode/webview-ui/src/i18n/de.ts index 7c3ebe2962b6..e250600c9f93 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/de.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/de.ts @@ -1467,6 +1467,10 @@ export const dict = { "settings.sandboxing.network.title": "Netzwerkzugriff einschränken", "settings.sandboxing.network.description": "Blockiert den ausgehenden Netzwerkzugriff für vom Modell initiierte Befehle und HTTP-Tools. Lokale MCP-Server und Plugin-Hooks sind von dieser Einschränkung ausgenommen. Anbieter- und Modellinferenzdatenverkehr bleibt verfügbar.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP-Zeitlimit (ms)", "settings.experimental.mcpTimeout.description": "Zeitlimit für MCP-Server-Anfragen in Millisekunden", "settings.experimental.remote.title": "Remote-Steuerung", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/es.ts b/packages/kilo-vscode/webview-ui/src/i18n/es.ts index a5bf4b39bd0d..11a1c4eb7c98 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/es.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/es.ts @@ -1455,6 +1455,10 @@ export const dict = { "settings.sandboxing.network.title": "Restringir el acceso a la red", "settings.sandboxing.network.description": "Bloquea el acceso saliente a la red para los comandos iniciados por el modelo y las herramientas HTTP. Los servidores MCP locales y los hooks de plugins no están sujetos a esta restricción. El tráfico de proveedores y de inferencia de modelos sigue estando disponible.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Tiempo de espera MCP (ms)", "settings.experimental.mcpTimeout.description": "Tiempo de espera para solicitudes del servidor MCP en milisegundos", "settings.experimental.remote.title": "Control Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/fr.ts b/packages/kilo-vscode/webview-ui/src/i18n/fr.ts index e793315324c4..a5cbfe1fff02 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/fr.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/fr.ts @@ -1470,6 +1470,10 @@ export const dict = { "settings.sandboxing.network.title": "Restreindre l'accès au réseau", "settings.sandboxing.network.description": "Bloquer l'accès réseau sortant des commandes provenant du modèle et des outils HTTP. Les serveurs MCP locaux et les hooks de plugin ne sont pas soumis à cette restriction. Le trafic d'inférence des fournisseurs et des modèles reste disponible.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Délai MCP (ms)", "settings.experimental.mcpTimeout.description": "Délai des requêtes du serveur MCP en millisecondes", "settings.experimental.remote.title": "Contrôle Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/it.ts b/packages/kilo-vscode/webview-ui/src/i18n/it.ts index 5e1079426a45..0af26debd752 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/it.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/it.ts @@ -1229,6 +1229,10 @@ export const dict = { "settings.sandboxing.network.title": "Limita l'accesso alla rete", "settings.sandboxing.network.description": "Blocca l'accesso in uscita alla rete per i comandi avviati dal modello e gli strumenti HTTP. I server MCP locali e gli hook dei plugin operano al di fuori di questa restrizione. Il traffico verso i provider e per l'inferenza dei modelli rimane disponibile.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Timeout MCP (ms)", "settings.experimental.mcpTimeout.description": "Timeout per richieste server MCP in millisecondi", "settings.experimental.remote.title": "Controllo remoto", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ja.ts b/packages/kilo-vscode/webview-ui/src/i18n/ja.ts index 5483784d6102..480fc818ee05 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ja.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ja.ts @@ -1432,6 +1432,10 @@ export const dict = { "settings.sandboxing.network.title": "ネットワークアクセスを制限", "settings.sandboxing.network.description": "モデルから発行されたコマンドと HTTP ツールによる外部ネットワークアクセスをブロックします。ローカル MCP サーバーとプラグインフックは、この制限の対象外です。プロバイダーおよびモデルへの推論通信は引き続き利用できます。", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCPタイムアウト(ミリ秒)", "settings.experimental.mcpTimeout.description": "MCPサーバーリクエストのタイムアウト(ミリ秒)", "settings.experimental.remote.title": "Remote コントロール", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ko.ts b/packages/kilo-vscode/webview-ui/src/i18n/ko.ts index 1c68d5d743a1..592d78f9ff00 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ko.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ko.ts @@ -1424,6 +1424,10 @@ export const dict = { "settings.sandboxing.network.title": "네트워크 액세스 제한", "settings.sandboxing.network.description": "모델이 실행한 명령과 HTTP 도구의 아웃바운드 네트워크 액세스를 차단합니다. 로컬 MCP 서버와 플러그인 훅에는 이 제한이 적용되지 않습니다. 공급자 및 모델 추론 트래픽은 계속 사용할 수 있습니다.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP 타임아웃 (ms)", "settings.experimental.mcpTimeout.description": "MCP 서버 요청의 타임아웃 시간 (밀리초)", "settings.experimental.remote.title": "Remote 제어", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/nl.ts b/packages/kilo-vscode/webview-ui/src/i18n/nl.ts index 845b5d5a1629..2ad81ecb59ea 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/nl.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/nl.ts @@ -1441,6 +1441,10 @@ export const dict = { "settings.sandboxing.network.title": "Netwerktoegang beperken", "settings.sandboxing.network.description": "Blokkeer uitgaande netwerktoegang voor door het model geïnitieerde opdrachten en HTTP-tools. Lokale MCP-servers en plugin-hooks vallen buiten deze beperking. Netwerkverkeer voor providers en modelinferentie blijft beschikbaar.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP Timeout (ms)", "settings.experimental.mcpTimeout.description": "Timeout voor MCP-serververzoeken in milliseconden", "settings.experimental.remote.title": "Remote-bediening", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/no.ts b/packages/kilo-vscode/webview-ui/src/i18n/no.ts index 775d9dc7e6e0..a6fb9502cb86 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/no.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/no.ts @@ -1400,6 +1400,10 @@ export const dict = { "settings.sandboxing.network.title": "Begrens nettverkstilgang", "settings.sandboxing.network.description": "Blokker utgående nettverkstilgang fra kommandoer generert av modellen og HTTP-verktøy. Lokale MCP-servere og programtilleggskroker kjører utenfor denne begrensningen. Trafikk for leverandør- og modellinferens forblir tilgjengelig.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP-tidsavbrudd (ms)", "settings.experimental.mcpTimeout.description": "Tidsavbrudd for MCP-serverforespørsler i millisekunder", "settings.experimental.remote.title": "Remote-kontroll", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/pl.ts b/packages/kilo-vscode/webview-ui/src/i18n/pl.ts index d3fa876fb7b5..4c580f8b6888 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/pl.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/pl.ts @@ -1400,6 +1400,10 @@ export const dict = { "settings.sandboxing.network.title": "Ogranicz dostęp do sieci", "settings.sandboxing.network.description": "Blokuj wychodzący dostęp do sieci z poleceń pochodzących od modelu i narzędzi HTTP. Lokalne serwery MCP i hooki wtyczek nie podlegają temu ograniczeniu. Ruch do dostawców i modeli na potrzeby wnioskowania pozostaje dostępny.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Limit czasu MCP (ms)", "settings.experimental.mcpTimeout.description": "Limit czasu żądań serwera MCP w milisekundach", "settings.experimental.remote.title": "Sterowanie Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ru.ts b/packages/kilo-vscode/webview-ui/src/i18n/ru.ts index 6f616a81d8c7..f2abffcf8b17 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ru.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ru.ts @@ -1441,6 +1441,10 @@ export const dict = { "settings.sandboxing.network.title": "Ограничить доступ к сети", "settings.sandboxing.network.description": "Блокировать исходящий доступ к сети для команд, инициированных моделью, и HTTP-инструментов. Локальные серверы MCP и хуки плагинов не подпадают под это ограничение. Трафик к провайдерам и моделям для инференса остаётся доступным.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Таймаут MCP (мс)", "settings.experimental.mcpTimeout.description": "Таймаут запросов MCP-сервера в миллисекундах", "settings.experimental.remote.title": "Управление Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/th.ts b/packages/kilo-vscode/webview-ui/src/i18n/th.ts index e5ec7f48ed43..360857fba293 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/th.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/th.ts @@ -1420,6 +1420,10 @@ export const dict = { "settings.sandboxing.network.title": "จำกัดการเข้าถึงเครือข่าย", "settings.sandboxing.network.description": "บล็อกการเข้าถึงเครือข่ายขาออกจากคำสั่งที่มาจากโมเดลและเครื่องมือ HTTP เซิร์ฟเวอร์ MCP ภายในเครื่องและฮุกของปลั๊กอินทำงานอยู่นอกข้อจำกัดนี้ การรับส่งข้อมูลสำหรับการอนุมานของผู้ให้บริการและโมเดลยังคงใช้งานได้", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "หมดเวลา MCP (มิลลิวินาที)", "settings.experimental.mcpTimeout.description": "หมดเวลาสำหรับคำขอเซิร์ฟเวอร์ MCP เป็นมิลลิวินาที", "settings.experimental.remote.title": "การควบคุม Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/tr.ts b/packages/kilo-vscode/webview-ui/src/i18n/tr.ts index e57d018906be..9337af1b8205 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/tr.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/tr.ts @@ -1431,6 +1431,10 @@ export const dict = { "settings.sandboxing.network.title": "Ağ Erişimini Kısıtla", "settings.sandboxing.network.description": "Model tarafından başlatılan komutların ve HTTP araçlarının giden ağ erişimini engelleyin. Yerel MCP sunucuları ve eklenti kancaları bu kısıtlamanın dışında çalışır. Sağlayıcı ve model çıkarım trafiği kullanılabilir durumda kalır.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "MCP Zaman Aşımı (ms)", "settings.experimental.mcpTimeout.description": "MCP sunucu istekleri için milisaniye cinsinden zaman aşımı", "settings.experimental.remote.title": "Remote Kontrolü", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/uk.ts b/packages/kilo-vscode/webview-ui/src/i18n/uk.ts index 06c0f00dfa4b..bd849a94b464 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/uk.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/uk.ts @@ -1429,6 +1429,10 @@ export const dict = { "settings.sandboxing.network.title": "Обмежити доступ до мережі", "settings.sandboxing.network.description": "Блокуйте вихідний доступ до мережі для команд, ініційованих моделлю, та HTTP-інструментів. Локальні MCP-сервери й хуки плагінів працюють поза цим обмеженням. Трафік провайдерів та інференсу моделей залишається доступним.", + + "settings.sandboxing.writablePaths.title": "Additional Writable Paths", + "settings.sandboxing.writablePaths.description": + "Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.", "settings.experimental.mcpTimeout.title": "Тайм-аут MCP (мс)", "settings.experimental.mcpTimeout.description": "Тайм-аут у мілісекундах для запитів до MCP-сервера", "settings.experimental.remote.title": "Керування Remote", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/zh.ts b/packages/kilo-vscode/webview-ui/src/i18n/zh.ts index 3f0eafa95e2a..cf9dd5844e2e 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/zh.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/zh.ts @@ -1394,6 +1394,10 @@ export const dict = { "settings.sandboxing.network.title": "限制网络访问", "settings.sandboxing.network.description": "阻止模型发起的命令和 HTTP 工具进行出站网络访问。本地 MCP 服务器和插件钩子不受此限制。提供商和模型推理流量仍然可用。", + + "settings.sandboxing.writablePaths.title": "额外可写路径", + "settings.sandboxing.writablePaths.description": + "沙盒允许写入的额外文件系统路径(例如 /tmp、/var/log)。沙盒启用后,这些路径会与默认可写路径合并。", "settings.experimental.mcpTimeout.title": "MCP 超时(毫秒)", "settings.experimental.mcpTimeout.description": "MCP 服务器请求的超时时间(毫秒)", "settings.experimental.remote.title": "Remote 控制", diff --git a/packages/kilo-vscode/webview-ui/src/i18n/zht.ts b/packages/kilo-vscode/webview-ui/src/i18n/zht.ts index d50689f1f764..16e14f70e25c 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/zht.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/zht.ts @@ -1358,6 +1358,10 @@ export const dict = { "settings.sandboxing.network.title": "限制網路存取", "settings.sandboxing.network.description": "封鎖模型發起的命令和 HTTP 工具的對外網路存取。本機 MCP 伺服器和外掛程式鉤子不受此限制。供應商與模型推論流量仍然可用。", + + "settings.sandboxing.writablePaths.title": "額外可寫路徑", + "settings.sandboxing.writablePaths.description": + "沙盒允許寫入的額外檔案系統路徑(例如 /tmp、/var/log)。沙盒啟用後,這些路徑會與預設可寫路徑合併。", "settings.experimental.mcpTimeout.title": "MCP 逾時(毫秒)", "settings.experimental.mcpTimeout.description": "MCP 伺服器請求的逾時時間(毫秒)", "settings.experimental.remote.title": "Remote 控制", From 889e2f4358042250d87817b41d085a20a7c24a9b Mon Sep 17 00:00:00 2001 From: trim21 Date: Tue, 7 Jul 2026 12:58:44 +0800 Subject: [PATCH 3/5] style: fix prettier formatting for SandboxingTab --- .../webview-ui/src/components/settings/SandboxingTab.tsx | 3 +-- packages/kilo-vscode/webview-ui/src/i18n/ar.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/br.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/bs.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/da.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/de.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/es.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/fr.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/it.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/ja.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/ko.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/nl.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/no.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/pl.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/ru.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/th.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/tr.ts | 4 ++-- packages/kilo-vscode/webview-ui/src/i18n/uk.ts | 4 ++-- 18 files changed, 35 insertions(+), 36 deletions(-) diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx index 6e69d7b14d4c..74f6e656faab 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/SandboxingTab.tsx @@ -104,8 +104,7 @@ const SandboxingTab: Component = () => { "align-items": "center", "justify-content": "space-between", padding: "6px 0", - "border-bottom": - index() < writablePaths().length - 1 ? "1px solid var(--border-weak-base)" : "none", + "border-bottom": index() < writablePaths().length - 1 ? "1px solid var(--border-weak-base)" : "none", }} > Date: Tue, 7 Jul 2026 18:05:53 +0800 Subject: [PATCH 4/5] fix(sandbox): expand ~ in writable paths and restrict to global config only - Expand leading ~ to os.homedir() in execute() before passing paths to the sandbox profile, so ~/tmp resolves correctly. - Strip sandbox_writable_paths from project-scoped config overlays. A repo kilo.json must not be able to widen the sandbox beyond the user's global config intent. --- packages/opencode/src/config/config.ts | 6 ++++++ packages/opencode/src/kilocode/sandbox/policy.ts | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index eae0c08f1c49..f243357d38f0 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -759,6 +759,12 @@ export const layer = Layer.effect( // kilocode_change start const merge = Effect.fnUntraced(function* (source: string, next: Info, kind?: ConfigPlugin.Scope) { const scope = kind ?? (yield* pluginScopeForSource(source)) + // sandbox_writable_paths is a security-sensitive sandbox setting that must only come from + // global config. A project kilo.json can otherwise widen the sandbox beyond the user's intent. + if (scope === "local" && next.experimental?.sandbox_writable_paths) { + const { sandbox_writable_paths: _, ...rest } = next.experimental + next = { ...next, experimental: { ...next.experimental, ...rest, sandbox_writable_paths: undefined } } + } const scoped = KilocodeConfig.scopeIndexing(next, scope) result = mergeConfigConcatArrays(result, scoped) return yield* mergePluginOrigins(source, scoped.plugin, scope) diff --git a/packages/opencode/src/kilocode/sandbox/policy.ts b/packages/opencode/src/kilocode/sandbox/policy.ts index ad0611db7296..72fbb6654c5e 100644 --- a/packages/opencode/src/kilocode/sandbox/policy.ts +++ b/packages/opencode/src/kilocode/sandbox/policy.ts @@ -1,4 +1,5 @@ import { readFileSync, statSync } from "node:fs" +import os from "node:os" import path from "node:path" import { Effect, Semaphore } from "effect" import { Global } from "@opencode-ai/core/global" @@ -303,7 +304,8 @@ function execute(sessionID: SessionID, effect: Effect.Effect) const support = backendSupport({ mode: current.state.mode, allowedHosts: [] }) if (!current.state.enabled || !support.available) return yield* unrestricted(effect) const cfg = yield* (yield* Config.Service).get() - const extraWritable = cfg.experimental?.sandbox_writable_paths + const raw = cfg.experimental?.sandbox_writable_paths + const extraWritable = raw?.map((p) => (p.startsWith("~") ? path.join(os.homedir(), p.slice(1)) : p)) return yield* runSandbox(profile(yield* InstanceState.context, current.state.mode, extraWritable), effect) }) } From af6bbd8c9f48b0bf47e1ba4cf6f0f12476ba176b Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 7 Jul 2026 18:26:48 +0800 Subject: [PATCH 5/5] Update packages/opencode/src/config/config.ts Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com> --- packages/opencode/src/config/config.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index f243357d38f0..4b241d36919e 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -759,12 +759,9 @@ export const layer = Layer.effect( // kilocode_change start const merge = Effect.fnUntraced(function* (source: string, next: Info, kind?: ConfigPlugin.Scope) { const scope = kind ?? (yield* pluginScopeForSource(source)) - // sandbox_writable_paths is a security-sensitive sandbox setting that must only come from - // global config. A project kilo.json can otherwise widen the sandbox beyond the user's intent. - if (scope === "local" && next.experimental?.sandbox_writable_paths) { - const { sandbox_writable_paths: _, ...rest } = next.experimental - next = { ...next, experimental: { ...next.experimental, ...rest, sandbox_writable_paths: undefined } } - } + // sandbox_writable_paths is security-sensitive — only global config may set it. + // A project kilo.json must not widen the sandbox beyond the user's intent. + if (scope === "local") delete next.experimental?.sandbox_writable_paths const scoped = KilocodeConfig.scopeIndexing(next, scope) result = mergeConfigConcatArrays(result, scoped) return yield* mergePluginOrigins(source, scoped.plugin, scope)