بکاندهای سندباکس
نمای کلی بکاندها
بخش با عنوان “نمای کلی بکاندها”| بکاند | مقدار | سکو | دسترسپذیری |
|---|---|---|---|
| VM محفظهای | microvm |
macOS، Linux، Windows (هایپروایزر microVM) | مشروط به بررسی روی زمان اجرای microVM؛ به ترمینالهای تعاملی اعمال میشود — پوسته درون یک ریگ اجرا میشود، نه روی میزبان |
| بومی | native |
macOS (Seatbelt)، Linux و WSL2 (bubblewrap) | هنگام بوت بررسی میشود؛ Linux اجرایی را که به ردهای نوشتن مبتنی بر الگوی نام فایل نیاز دارد رد میکند، چیزی که bubblewrap نمیتواند اعمال کند |
| بدون جداسازی | none |
همه | پیشفرض تجزیه، پیشفرض ترمینال، و آنچه در نبود بکاند یا با تنظیم --sandbox off به آن بازمیگردد |
SandboxBackend.fromName برای یک مقدار ذخیرهشدهٔ null یا ناشناخته none برمیگرداند. یک "docker" ذخیرهشده به native نگاشت میشود.
microvm تنها بکاندی است که مرز کرنل دارد — بار کاری واقعاً روی
میزبان اجرا نمیشود. هرگز در هیچ جهتی تنزل خاموش نیست: درخواست صریحش روی
میزبانی که نمیتواند VM بوت کند با شکستی پرصدا از کار میافتد («VM خواستم و
لپتاپم را گرفتم» همان تنزلی است که محفظه توان تحملش را ندارد)، و تنها یک
پیشفرض نامشخص است که به native تنزل میکند، با خطی در لاگ که همین را
میگوید. بکاند واقعی نشست به کلاینت گزارش میشود و برچسب میخورد، پس یک
ترمینال هرگز نمیتواند ادعا کند محفظهای است در حالی که روی میزبان اجرا
میشود. چرخهٔ عمر، ایمیجها و خروج خودِ VM در
مرجع ریگها پوشش داده شدهاند.
Windows سندباکس بومی ندارد. NativeSandboxAdapter.probe روی هر میزبانی که macOS یا Linux/WSL2 نباشد available: false برمیگرداند. بنابراین اعزام عامل روی Windows از none استفاده میکند. بکاند microvm جداگانه است: به بررسی زمان اجرای microVM مشروط است و به ترمینالهای تعاملی و ریگها اعمال میشود، نه به پیچیدن bash روی میزبان.
نتایج بررسی
بخش با عنوان “نتایج بررسی”بررسی همان چیزی است که اعمال را دروازهبندی میکند. یکبار، هنگام بوت سرور اجرا میشود.
| میزبان | available |
یادداشت / راهنما |
|---|---|---|
| macOS | true |
sandbox-exec (Seatbelt) — ایزولهسازی namespace، بدون مرز کرنل |
Linux یا WSL2 با bwrap و socat |
true |
bubblewrap — ایزولهسازی namespace، بدون مرز کرنل |
| Linux یا WSL2 که هر یک از این دو ابزار را ندارد | false |
requiresInstall: true، همراه با راهنمای نصب که بستههای غایب را نام میبرد |
| هر سکوی دیگر | false |
سندباکس بومی روی این سکو عرضه نمیشود |
سرور نتیجه را روی یک خط راهاندازی لاگ میکند: agent sandbox ON بههمراه یادداشت، no OS-native agent sandbox on this host بههمراه راهنما، یا agent sandbox DISABLED by --sandbox off. GET /healthz هیچ فیلد سندباکسی حمل نمیکند.
--sandbox / CC_SERVER_SANDBOX مقدار on (پیشفرض) یا off را میپذیرد. یک انصراف است، نه یک فعالسازی: on یعنی «هرگاه میزبان بکاندی عرضه کند بپیچ»، و هرگز یعنی «یکی را الزام کن».
بکاند بومی
بخش با عنوان “بکاند بومی”macOS: Seatbelt
بخش با عنوان “macOS: Seatbelt”از سازوکار سندباکس Seatbelt اپل استفاده میکند (همان سیستمی که App Sandbox در macOS به کار میبرد).
پروفایل تولیدشده بهطور پیشفرض مجاز است ((allow default)) و ردها را میتراشد، چون یک پروفایل کاملاً رد-بهطور-پیشفرض پوستهٔ تعاملی را غیرقابلاستفاده میکند — فراخوانیهای dyld، XPC و Mach برای برشمردن بیش از حد زیادند. پیامد عملی این است که عامل هنوز میتواند بیشتر میزبان را بخواند؛ checkoutهای ثبتشدهٔ شما با ردهای صریح نوشتن و تغییر نام محافظت میشوند، نه با نامرئیبودن.
- خواندن فایلسیستم: برای مسیرهای محرمانه (
~/.ssh،~/.aws،~/.gnupg،~/.config/gh،~/Library/Keychainsو بقیهٔ مجموعهٔ رد-خواندن) رد میشود - نوشتن فایلسیستم: به رد بازنشانی میشود، سپس اجازههای صریح برای زیرمسیرها، در حالی که مسیرهای الزاماً ردشده (فایلهای rc پوسته،
.git/hooks، پیکربندی Claude، checkoutهای محافظتشده) حتی درون ریشهٔ قابلنوشتن هم مسدود میمانند.file-write-unlinkروی هر مسیر ردشده و اجدادش رد میشود، پس یک تغییر نام نمیتواند از یک رد-نوشتن بگذرد - فرایند: ردهای
process-execبرای باینریهای همیشهخطرناک، بههمراه مسدودسازی اجرای هر چیزی از یک دایرکتوری قابلنوشتن - شبکه: محدود به پورتهای پروکسی درونفرایندی بههمراه DNS — loopback بهصورت یکسره مجاز نیست و سوکتهای Unix مجاز نیستند. پروکسیها فهرست مجاز دامنهٔ هر نشست را اعمال میکنند (به خروج شبکه نگاه کنید)
- پیکربندی: پروفایلها بهازای هر راهاندازی از
SandboxSpecتولید میشوند
پیشنیازها:
sandbox-exec(/usr/bin/sandbox-exec)، بخشی از هر نصب macOS — هیچ ابزار اضافهای لازم نیست
Linux: bubblewrap
بخش با عنوان “Linux: bubblewrap”از bubblewrap (bwrap) برای ساخت namespaceهای مانت و PID استفاده میکند.
- فایلسیستم: یک namespace مانت میسازد که در آن فقط مسیرهای bindشده دیده میشوند
- شبکه: در یک namespace شبکهٔ جداگانه اجرا میشود؛ ترافیک از طریق پلهای سوکت Unixی
socatبه پروکسیهای میزبان میرسد - فرایند: ایزولهسازی namespace PID
پیشنیازها:
- نصب
bubblewrapوsocat(روی Debian/Ubuntu:sudo apt-get install bubblewrap socat) - پشتیبانی کرنل از namespace (استاندارد در Linux مدرن)
Bubblewrap میتواند یک مسیر موجود را سایه بیندازد اما نمیتواند یک فایل
جدید .env، *.key یا *.pem را درون یک مانت bind قابلنوشتن ممنوع
کند. سیاست استاندارد اعزام این ردهای مبتنی بر الگوی نام فایل را الزام
میکند، پس اعزام بومی عامل در حال حاضر روی Linux/WSL2 حتی وقتی بررسی
bubblewrap را پیدا میکند هم بهصورت بسته شکست میخورد. با سیاستی
خاموشضعیفتر اجرا نمیشود. برای بازگرداندن اعزام بومی Linux به بکاندی نیاز
است که قواعد نام فایل را در زمان ساخت اعمال کند. خاموشکردن سندباکس یک
انصراف صریح و بدون محدودیت است، نه یک راهحل معادل.
بکاند بدون جداسازی
بخش با عنوان “بکاند بدون جداسازی”بدون سندباکس. فرایند مستقیماً روی میزبان با دسترسی فایلسیستم، شبکه و فرایند خود میزبان اجرا میشود. ACP و ابزار bash هارنس همچنان پاکسازی محیط و سیاست فرمان را میگیرند؛ Claude Code از NoSandboxAdapter محیط میزبان را به ارث میبرد. این همان چیزی است که اعزام عامل روی میزبانی بدون بکاند در دسترس یا با --sandbox off به آن برمیگردد، و پیشفرض ترمینال است وقتی کلاینت هیچ بکاندی را نام نمیبرد.
ترمینال میزبانیشده روی سرور
بخش با عنوان “ترمینال میزبانیشده روی سرور”ترمینال به قاعدهٔ خودش سندباکس میشود، نه با بررسی اعزام. defaultBackend در TerminalSessionService برابر none است و cc_server آن را بازنویسی نمیکند، پس یک نشست ترمینال پوستهٔ میزبان را اجرا میکند مگر اینکه کلاینت صراحتاً native را بخواهد — پنل ترمینال نسخهٔ رومیزی چنین نمیکند.
هنگامی که native درخواست شود، پوسته با یک پروفایل ثابت ترمینال از SandboxManager میپیچد: $HOME و دایرکتوری کاری نشست قابلنوشتناند، شبکه باز است و خواندن ~/.ssh، ~/.aws، ~/.gnupg، ~/.config/gh و ~/Library/Keychains رد میشود. توکن فقطخواندنی و دروازهٔ پوش اعمال نمیشوند — آن دغدغهٔ اعزام است. اگر پیچش پشتیبانی نشود، نشست شکست میخورد بهجای اینکه روی یک PTY پوستهٔ میزبان برچسب بومی را نمایش دهد.
خروج شبکه
بخش با عنوان “خروج شبکه”وقتی سندباکسی راهاندازی میشود، دسترسی شبکهٔ خروجی توسط پروکسیهای درونفرایندی اعمال میشود، نه با قواعد فایروال کرنل. روی میزبانی بدون بکاند در دسترس هیچکدام از اینها اعمال نمیشود و یک فرایند spawnشده دقیقاً همانطور که کاربر سرور دسترسی داشت به شبکه میرسد.
- زمان اجرای سندباکس یک پروکسی HTTP/HTTPS و یک پروکسی SOCKS5 روی
127.0.0.1درون فرایندcc_serverاجرا میکند، یک جفت بهازای هر نشست محدودشده (http_proxy.dart،socks_proxy.dart). اجراهای همزمان یک جفت را به اشتراک نمیگذارند. - فرایندهای سندباکسشده متغیرهای محیطی پروکسی را دریافت میکنند (
HTTP_PROXY/HTTPS_PROXY→ پروکسی HTTP،ALL_PROXY→ پروکسی SOCKS؛GIT_SSH_COMMANDمسیر git روی SSH را از پروکسی SOCKS میگذراند). روی Linux namespace شبکه جدا است، پس پروکسیها تنها راه بیروناند؛ روی macOS سندباکس loopback میزبان را به اشتراک میگذارد و مستقیم با آنها حرف میزند. - میزبان هدف هر اتصال با فهرست مجاز دامنهٔ نشست تطبیق داده میشود؛ هر چیز دیگری رد میشود. دو شکل وایلدکارد، هر کدام با دقیقاً یک
*: یک*.example.comپیشرو با هر زیردامنهای تطبیق مییابد (شاملa.b.example.com) اما نه با خود دامنهٔ ریشه؛ یکbedrock.*.amazonaws.comبا برچسب میانی دقیقاً با یک برچسب تطبیق مییابد (bedrock.us-east-1.amazonaws.com، نهbedrock.evil.attacker.amazonaws.com). - فهرست مجاز بهازای هر نشست از خط پایهٔ گزینششده حل میشود (
kBaselineAllowedDomains: ارائهدهندگان LLM، میزبانی Git، رجیستریهای بسته)، بههمراه دامنههای GitHub (kGithubDomains)، بهعلاوهٔSandboxSpec.egressAllowlist. مسیر اعزام هرگز ورودیهای اضافیegressAllowlistرا نمیفرستد، پس در عمل هر اجرا خط پایه بهعلاوهٔ GitHub را میگیرد. - یک فهرست رد ثابت (
kBaselineDeniedDomains: نقاط پایانی فرادادهٔ ابری، مقصدهای تلمتری) بر همهٔ مجوزها تقدم دارد. networkEnabled: falseهمچنان پروکسیهای هر نشست را شروع میکند، اما فهرست مجاز خالی است، پس هر اتصال خروجی رد میشود. اعزام این مقدار را در شروع اجرا از قاعدهٔ دسترسی به شبکه تعیین میکند: رد شبکه را خاموش میکند، اجازه و ابتدا بپرس آن را روشن نگه میدارند.
SandboxSpec
بخش با عنوان “SandboxSpec”specی که به SandboxPort.launch داده میشود:
| فیلد | نوع | توضیح |
|---|---|---|
sessionId |
String |
شناسهٔ پایدار نشست (معمولاً شناسهٔ فضا) |
workspaceId |
String |
شناسهٔ فضای کاری مالک |
agentId |
String? |
عاملی که در حال حاضر به سندباکس بسته شده، در صورت وجود |
bindMounts |
List<SandboxBindMount> |
مانتهای میزبان→مهمان؛ سندباکس فقط مسیرهای میزبانی را میبیند که اینجا فهرست شدهاند |
networkEnabled |
bool (پیشفرض true) |
در اعزام از قاعدهٔ خروج شبکه تعیین میشود (فقط وقتی به رد حل شود خاموش است). با خاموش بودن، پروکسیهای هر نشست همچنان شروع میشوند اما فهرست مجاز خالی است، پس هر اتصال خروجی رد میشود |
egressAllowlist |
List<String> (پیشفرض []) |
دامنههای خروج مجاز اضافی؛ وایلدکاردها پشتیبانی میشوند (*.example.com، بههمراه شکل میانی یکبرچسبی). اعزام هرگز این را پر نمیکند، پس یک اجرای پیچیده خط پایهٔ گزینششده بهعلاوهٔ دامنههای GitHub را میگیرد |
guestWorkdir |
String? |
دایرکتوری کاری پیشفرض درون سندباکس؛ فراخوانیهای تک exec میتوانند آن را بازنویسی کنند |
mode |
Mode (پیشفرض chat) |
قواعد نوشتن فایلسیستم را میتراشد: chat مانتهای bind را قابلنوشتن نگه میدارد؛ review، plan و orchestrate فقطخواندنیاند |
protectedPaths |
List<String> (پیشفرض []) |
مسیرهای میزبان که هرگز نباید درون سندباکس، در هیچ حالتی، قابلنوشتن باشند |
runnerStateDirs |
List<String> (پیشفرض []) |
دایرکتوریهای میزبان که رانر وضعیت خودش را در آنها نگه میدارد، در هر حالت قابلنوشتن (یک CLAUDE_CONFIG_DIR مدیریتشده با Control Center مورد کنونی است) |
execGrantRoots |
List<String> (پیشفرض []) |
درختهای دایرکتوری تأییدشدهٔ اپراتور که مسدودسازی exec دایرکتوری قابلنوشتن را روی macOS بازگشایی میکنند. Linux آنها را نادیده میگیرد — bwrap هیچ مسدودسازی execی روی $HOME برای بازگشایی ندارد |
protectedPaths نگهدارندهٔ checkoutهای اصلی مخزنهای ثبتشده است که بهازای هر اعزام از مخزنهای فضای کاری حل میشوند. عاملها منحصراً در worktreeهای کپی-در-نوشت هر گفتگو کار میکنند، پس اصلها هرگز نباید از درون سندباکس قابلنوشتن باشند — روی macOS، مجوز نوشتن یکسرهٔ $HOME در Seatbelt در غیر این صورت آنها را از طریق bash قابلنوشتن رها میکرد. آنها در هر حالت، از جمله chat، به مجموعهٔ رد-نوشتن رازها میپیوندند.
هر مسیر رد-خواندن و رد-نوشتن در هر دو صورت نوشتاریاش منتشر میشود: صورت تحتاللفظی و صورت حلشدهٔ symlink. کرنل یک قاعدهٔ رد را در برابر مسیر حلشده تطبیق میدهد، پس قاعدهای که در برابر یک مسیر symlinkدار نوشته شده باشد هرگز فعال نمیشود — و روی macOS این حالت رایج است نه نامتعارف، چون /tmp به /private/tmp و /var/folders/… به /private/var/folders/… حل میشود. ورودیهایی که * یا ? دارند بهعنوان glob در نظر گرفته میشوند و دستنخورده میمانند؛ مسیری که حل نمیشود همانطور که نوشته شده نگه داشته میشود.
SandboxBindMount
بخش با عنوان “SandboxBindMount”| فیلد | نوع | توضیح |
|---|---|---|
hostPath |
String |
مسیر مطلق روی میزبان |
guestPath |
String |
مسیر درون سندباکس (در سندباکس بومی برابر hostPath است؛ برای تقارن آداپتور نگه داشته شده) |
readOnly |
bool (پیشفرض false) |
در صورت true فقطخواندنی مانت میشود |
SandboxHandle
بخش با عنوان “SandboxHandle”بازگشتی از SandboxPort.launch:
| فیلد | نوع | توضیح |
|---|---|---|
sessionId |
String |
شناسهٔ نشست |
backend |
SandboxBackend |
کدام بکاند در حال اجراست |
state |
SandboxState |
وضعیت چرخهٔ عمر |
error |
Object? |
وقتی state برابر error باشد تنظیم میشود |
details |
Map<String, Object?> |
حسابداری خصوصی آداپتور (دایرکتوری کاری، PID، مسیر پروفایل و غیره) |
SandboxState
بخش با عنوان “SandboxState”| وضعیت | توضیح |
|---|---|
created |
spec ساخته شده اما VM هنوز راه نیفتاده است |
warm |
در حال اجرا و آماده برای اجرای فرمانها |
active |
در حال اجرای یک فرمان |
suspended |
متوقفشده / نقطهگذاریشده روی دیسک برای صرفهجویی در RAM |
destroyed |
برچیده شده؛ دستگیره دیگر معتبر نیست |
error |
راهاندازی شکست خورد — SandboxHandle.error را ببینید |
رویدادهای سندباکس
بخش با عنوان “رویدادهای سندباکس”| نوع رویداد | توضیح |
|---|---|
stdout |
خروجی استاندارد سندباکس |
stderr |
خطای استاندارد سندباکس |
exit |
فرایند سندباکس خارج شد (exitCode را حمل میکند) |
starting |
سندباکس در حال راهاندازی است |
ready |
سندباکس آماده پذیرش فراخوانیهای exec است |
killed |
فرایند توسط میزبان کشته شد (OOM، مهلت، توقف دستی) |
violation |
یک سیاست سندباکس نقض شد (یک SandboxViolation را حمل میکند) |
SandboxViolation
بخش با عنوان “SandboxViolation”| فیلد | نوع | توضیح |
|---|---|---|
action |
String |
فعل ردشده (مثلاً file-read*، network-outbound) |
target |
String |
مسیر یا میزبانی که هدف عملیات ردشده بود |
raw |
String? |
خط خام لاگ، مفید برای اشکالزدایی |
همچنین ببینید
بخش با عنوان “همچنین ببینید”- سندباکس و امنیت
- سیاستهای سندباکس
- گاردریلها
- CLI مربوط به cc_server: پرچم
--sandbox