← Dokumentasi

Policy & Sandbox

WorkMode, persetujuan, tool access policy, penjaga perintah shell, dan isolasi eksekusi adalah kontrol yang berbeda. Hard deny path jail, state milik runtime, dan bash guard tetap berlaku di atasnya.

Tiga sumbu kontrol

Sumbu · Nilai · Fungsi

WorkMode · DISCUSS / PLAN / BUILD (EXECUTE internal) · Membatasi cara agent bekerja. DISCUSS read-only; PLAN boleh membuat artefak rencana; BUILD tidak menambah ceiling. WorkMode hanya mempersempit akses.

PermissionMode · AUTO / ASK · Menentukan pengawasan manusia. AUTO menjalankan capability yang diotorisasi tanpa persetujuan rutin; ASK meminta persetujuan untuk aksi yang digate. Hard deny tetap berlaku.

Tool Access Policy · capability read-only, plan, allowlist, profil akses warisan · Menentukan capability yang tersedia. Nilai internal readonly, plan, allowlist, dan allow-all masih dipakai untuk kompatibilitas dan batas akses, bukan sebagai pilihan pengawasan.

PermissionMode internal masih berupa union kompatibilitas yang juga memuat profil akses warisan. Untuk pilihan mode, flag, dan kombinasi yang menghadap pengguna, lihat Memilih Mode dan CLI. Delegasi juga mewarisi batas parent; lihat Sub-Agents & Tasks.

Set terkait: INTERNAL_WRITE_TOOLS, FILE_WRITE_TOOLS, GATED_TOOLS (+ *.* MCP), NO_PROMPT_TOOLS. move_file/delete_file dijail di permission layer (berlaku semua mode termasuk --allow-all).

Bash-guard ternormalisasi

src/policy/bash-guard.ts: quote pemisah kata dibuang dan assignment sederhana disubstitusi sebelum pemeriksaan.

Dulu lolos · Sekarang

cat .e""nv · ditolak

X=.env; cat $X · ditolak

p=python3; $p -c 1 · ditolak

node --eval "1" · ditolak

env, set, export -p · ditolak

curl -F file=@~/.ssh/id_rsa · ditolak

echo x > ..\evil (redirect keluar workspace) · ditolak; target redirect di-resolve ke cwd sebelum lolos allowlist

echo x > "%TEMP%\evil" · ditolak; target berisi ekspansi %NAMA% tak bisa dipastikan aman secara statis

py -c …, python3.14 -c … · ditolak bersama varian launcher dan versi Python

type ..\..\windows\system32\config\sam, Get-Content .../ntds.dit · ditolak (hive Windows + `reg save · export hive + vssadmin create · delete shadow + ntdsutil; reg query, vssadmin list, system.txt` biasa tetap lolos)

write_file .minicode/<apa-pun> · ditolak fail-closed (kunci penuh segmen .minicode/; satu-satunya pengecualian restore .trash/ → workspace; skrip .minicode/hooks/ kini ikut terkunci — lihat Keamanan)

bash <(curl x) · ditolak

rm -rf .., rm --recursive --force /, rm -rf /; : · ditolak

command env, nice env, dkk. (wrapper) · deteksi env-dump ter-anchor ke awal · ditolak via stripCommandWrappers (buang wrapper berlapis)

Baca lewat hardlink menuju luar workspace · ditolak jika handle yang dibuka memiliki nlink > 1; pengecekan memakai fstat

type .e^nv, ty^pe .env (escape caret cmd.exe) · ditolak setelah caret dinormalisasi sebelum aturan nama/jail

type %USERPROFILE%\notes.txt · ditolak; argumen pembaca berpola %NAMA% tak bisa dipastikan aman

for /f %i in (.env) do @echo %i · ditolak; file set pada loop for /f ikut diperiksa

cat${IFS}.env, cat$IFS.env, cat${IFS:0:1}.env (audit 2026-11-12) · ditolak; $IFS adalah pemisah kata, dinormalisasi jadi spasi sebelum aturan nama

cat .?nv, cat .[e]nv · ditolak; glob ?/[] mengembang ke nama lain sama seperti *

cat .{env,}, cat {.env,x} · ditolak; brace expansion diekspansi sebelum pemeriksaan

cat$(printf ' ').env · ditolak; argumen pembaca berupa substitusi perintah tak bisa dipastikan statis

echo "rm -rf /", git commit -m "docs: sudo rm" · lolos (arah over-block); isi kutip milik echo/printf/grep/-m git adalah DATA, bukan perintah — kecuali memuat $(, backtick, atau $VAR yang tetap dieksekusi

Allowlist (bentuk perintah yang boleh; diperiksa SETELAH bash-guard). Dua daftar:

  • Narrow (--allowlist, task tak-terpercaya): git status/diff/log/branch/show, bun test/run/x tsc, npm/bun/pnpm/yarn install|add, npm run/exec/install/ci/test/start, node, npx, ls dir cat type head tail wc grep rg find which echo pwd. Tulis via shell (mkdir cp mv rm touch) ditahan — pakai write_file/edit yang ter-jail.
  • Developer (fallback tanpa sandbox OS — restrictBash; sesi trusted di mesin sendiri): narrow + runtime/interpreter luas (python/node/ruby/php/perl/lua/julia/elixir/groovy/scala/java/dotnet/swift/dart…), package manager (pip/pip3/uv/pipx/poetry/pipenv/gem/bundle/composer/cargo/go/nuget…), framework/bundler (vite/next/nuxt/webpack/esbuild/rollup…), test/lint/build (pytest/ruff/mypy/jest/vitest/eslint/tsc/mvn/gradle/dotnet/make/cmake/gcc…), DB CLI (psql/mysql/sqlite3/prisma…), container (docker/podman).

npm exec/npx/bun run/bun x tak boleh ekspansi shell ($, backtick) atau redirection. Runtime hanya menjalankan berkas skrip — eval inline (-e/--eval/-c/-r/--require) difilter guard lebih dulu untuk SEMUA interpreter (termasuk baru: lua -e, julia -e, …). Verba rilis-registry (npm publish, cargo publish/login, gem push, docker push, mvn deploy, dart pub publish, twine upload…) ditolak guard di SEMUA mode. Package manager menjalankan lifecycle script (postinstall/setup.py = kode arbitrer dari registry), jadi kedua daftar berstatus "trusted", bukan pengganti isolasi — isolasi sungguhan tetap --sandbox docker.

Ukur, bukan klaim — jalankan sendiri untuk angka terkini:

bun run gate:bash        # korpus manual pola serangan + perintah sah (0 bypass / 0 over-block = lulus)

Fuzz membangkitkan varian dari transformasi yang shell anggap setara (quote-split, indirection, wrapper, flag panjang, chaining); temuan terkunci sebagai regression test.

Batas jujur: analisis statis atas bahasa Turing-complete. $(curl …) dinamis tak bisa diselesaikan tanpa eksekusi — untuk itu sandbox OS ada.

Sandbox otomatis

Kondisi · Yang terjadi

bwrap (Linux) / seatbelt (macOS) tersedia · Bash di dalamnya, tanpa flag

Tidak tersedia (termasuk semua Windows) · Default turun ke restrictBash (allowlist developer, sesi trusted); tanpa pesan [sandbox] — pesan itu hanya muncul untuk request --sandbox eksplisit

--allow-all / --ask / --plan / --allowlist diberikan · Pilihan dihormati, tanpa peringatan

--sandbox none · Opt-out sadar; tanpa downgrade

--sandbox docker · Container ephemeral (--network none, 512m, 1 CPU, node:22-alpine)

--sandbox docker tapi daemon mati · TOLAK sebelum jalan (fail-closed) + cara opt-in fallback eksplisit; tidak pura-pura terisolasi

Container mendapat nama acak per-run. Saat batas waktu habis atau tool dibatalkan, runner meminta daemon menjalankan docker rm --force dengan timeout cleanup 5 detik sebelum menghentikan penunggu CLI. Output membedakan cleanup yang dikonfirmasi daemon dari yang tidak terkonfirmasi. Ini tidak membatalkan efek workspace yang sudah terjadi sebelum container dihentikan.

MINICODE_SANDBOX_STRICT=1 = tak pernah fallback host (redundan dengan default fail-closed untuk request eksplisit, tetap dihormati). MINICODE_SANDBOX_ALLOW_FALLBACK=1 = satu-satunya jalan fallback host yang sadar bila backend tak tersedia. MINICODE_SANDBOX_IMAGE ganti image (default node:22-alpine hanya bawa node). code_run selalu lewat sandbox runner dan menolak bila backend tak tersedia.

Lapisan lain

  • Path jail realpath-based + symlink realpath di permission layer; .env/.git/config/node_modules/hive Windows deny; .minicode/ terkunci penuh untuk tool tulis berdasarkan target NYATA (realpath best-effort isOwnedStateReal — junction/symlink internal ke .minicode/ ikut ditahan; kecuali restore .trash/ + skrip hooks/); bash-guard menahan PEMBUATAN link yang operannya sensitif/owned-state. Untuk pembacaan, safeOpenRead memeriksa boundary ulang setelah stat dan mencocokkan dev+ino dari handle yang terbuka; O_NOFOLLOW juga dipakai pada POSIX. Stress test symlink tetap skip bila host tidak memberi privilege membuat symlink.
  • Env scrub sanitizeSpawnEnv: strip kata-kunci kredensial dari merge final; GITHUB_WORKSPACE/GITHUB_REF/GOOGLE_CHROME_PATH/REDIS_HOST/AWS_REGION tetap ada, GITHUB_TOKEN/AWS_SECRET_ACCESS_KEY/DATABASE_URL tetap di-strip.
  • web_fetch/web_search: redirect manual 5 hop + resolve DNS tanpa cache per hop (anti-rebinding) + body 2 MB.
  • Secret scrubber: sk-, ghp_, AKIA, PEM, JWT, Bearer, api_key=... di-redact sebelum ke LLM (read_file/bash/grep) — tanpa whitelist kata.
  • Config/allowlist: atomic randomUUID tmp+rename + chmod 600. MCP serve curated tools + permission aktif.