דילוג לתוכן
תפריט
צריכים את זה?לאן סוכן יכול להגיע במחשב שלכםאיך זה עובדהשכבות שבין הסוכן למערכת שלכםהשוואהסביבות sandbox מובנות, Docker ומכונות וירטואליותהגדרהפותחים רק את מה שהמשימה צריכהאבטחהמודל האיומים והגבולות שלוהורדהקבצים בינאריים, checksums והערות גרסההתקנה
אבטחה

שכבה מועילה, עם גבולות ידועים

הכלי ai-jail נבנה לעצור טעויות של סוכן אמין ולהשאיר את הנזק בתוך הפרויקט: תיקיית הפרויקט היא רדיוס הפגיעה, ותיקיית הבית, המפתחות והרשת שלכם נשארים מחוץ לו. מדובר ב-sandbox ברמת התהליך שחולק איתכם את הקרנל, ולכן הוא לא גבול מול קוד עוין או תוקף נחוש, ולא מחליף מכונה וירטואלית חד-פעמית.

למי שחותם על האישור, ואחר כך למהנדס האבטחה.

מה הוא נבנה לעצור

גם סוכן אמין מקליד פקודה לא נכונה, מריץ סקריפט שמטפס מעל שורש הפרויקט, או מוטעה על ידי דף אינטרנט או חבילה. אלה הדברים שהוא מושיט אליהם יד אחר כך, ולא מוצא.

↔ החליקו לצדדים כדי לראות את התרשים המלא

ברירות המחדל. כל פריט שנמצא בחוץ נשאר שם עד שתפתחו אותו בעצמכם.

מחוץ להישג יד

  • תיקיית הבית שלכם ופרטי הגישה שבה. הסוכן מקבל תיקיית בית חדשה וריקה, כך ש-~/.ssh ו-~/.aws לא קיימים שם.
  • סודות ב-shell שלכם. הכלי ai-jail מצמצם את משתני הסביבה לרשימת היתרים קטנה, כך שטוקנים שיוצאו נשארים בחוץ. היוצא מן הכלל היחיד הוא מפתח ה-API של ה-harness שהופעל, למשל ANTHROPIC_API_KEY עבור Claude, שמועתק כברירת מחדל יחד עם ההתחברות שלו; --no-agent-state עוצר את זה.
  • הרשת. היא סגורה, עם שני חריגים שעוברים דרך הפרוקסי המסנן: רשימה קצרה של registries של חבילות כשה-toolchains דלוקים, ברירת המחדל ב-Linux, ועבור סוכן מוכר, ה-host של ה-API שלו, בשתי הפלטפורמות. hosts של טלמטריה נשארים סגורים. --no-network סוגר את שניהם.
  • הזיכרון המשותף של המארח, שרת התצוגה ולוח ההעתקה שלכם. הפלט של הסוכן עובר דרך מסנן שזורק sequences של טרמינל שנוגעים בלוח ההעתקה או מתשאלים את הטרמינל.
  • הקלדה לתוך הטרמינל שלכם. ב-Linux נחסמת הקריאה TIOCSTI שמזייפת הקשות, וב-macOS השליטה בטרמינל מוגבלת לטרמינל האחד שנוצר עבור ההרצה.
  • הכללים שלו עצמו. קובץ .ai-jail בתוך ריפוזיטורי נחשב לא אמין: הוא יכול להדק את ה-sandbox, ולעולם לא לפתוח אותו.
איך כל שכבה עושה את זה

איפה החומה נגמרת

הכלא והמערכת שלכם עומדים על אותו קרנל. באג בקרנל הזה, בדרייבר או ב-backend של ה-sandbox הוא דרך לעקוף את החומה, ו-ai-jail לא יכול לעשות שום דבר בעניין. מכונה וירטואלית מביאה קרנל משלה, ולכן היא גבול חזק יותר.

↔ החליקו לצדדים כדי לראות את התרשים המלא

כל sandbox חולק את הקרקע עם מה שהוא מגן עליו, ומכונה וירטואלית מביאה קרקע משלה.

מה זה אומר על הנתונים שלכם

  • סודות בתוך הפרויקט. קובץ .env בריפוזיטורי קריא, אלא אם מיסכתם אותו. כך ממסכים קבצים.
  • מיסוך מכסה רק נתיבים שקיימים כשה-sandbox עולה. קובץ סודות שנוצר מאוחר יותר, במהלך הסשן, לא מוסתר.
  • host מורשה זוכה לאמון מלא. מי שמתיר את github.com עם --allow-host נותן לסוכן לעשות push לכל ריפוזיטורי שם, לא רק לשלכם.
  • --network פותח את כל הרשת, ולכן כל מה שהסוכן יכול לקרוא, כולל הפרויקט שלכם, הוא יכול לשלוח החוצה.
  • הכלי ai-jail מעגן את ההתחברות של הסוכן עצמו כברירת מחדל, לקריאה וכתיבה, ולכן סוכן שהוטעה יכול להשתמש בה למשך ההרצה. הפרויקט מתעד את זה כפשרה לטובת הנוחות; --no-agent-state נותן הרצה ללא התחברות.
  • git בצד המארח סומך על .git/ של הפרויקט, שפתוח לכתיבה. תוכנית ששמה מופיע ב-.git/config, למשל ב-core.fsmonitor או ב-core.pager, או שהונחה ב-.git/hooks/, רצה בשמכם, מחוץ ל-sandbox, בפעם הבאה שפקודת git מתאימה רצה על המארח; ל-core.fsmonitor מספיק git status רגיל, גם כזה שהעורך שלכם מריץ ברקע, ושום דבר לא מופיע ב-git diff. --lockdown סוגר את זה בכך שהפרויקט הופך לקריאה בלבד, ו---map .git שומר את הריפוזיטורי לקריאה בלבד בהרצה רגילה, במחיר של commit מבפנים. אחרי סשן שהפתיע אתכם, קראו את .git/config ורשמו את התוכן של .git/hooks עם כלי קבצים רגילים לפני שאתם מריצים git על המארח, כי git config --list בעצמו מפעיל את ה-pager שהוגדר.
  • --mask ו---deny-path משנים רק את מה שה-sandbox רואה. כל מה שמחוץ ל-sandbox ופועל בשם הסוכן עדיין קורא את הקבצים האמיתיים: ה-daemon של Docker תחת --docker, שרת MCP שמגיעים אליו דרך socket ממופה, או שירות שמאחורי --forward-port.
למהנדס האבטחה
  • פגיעויות בקרנל ובדרייברים. כל תהליך שרץ ב-sandbox מדבר עם אותו קרנל כמו שאר המחשב שלכם.
  • באגים באמולטור הטרמינל שלכם, בעיקר עם --terminal-passthrough, שמכבה את מסנן הפלט.
  • פגמים ב-backend של ה-sandbox עצמו: bubblewrap, Landlock ו-seccomp ב-Linux, או sandbox-exec ב-macOS.
  • Landlock, הכללים של הקרנל עצמו, מגדר sockets אבסטרקטיים של Unix וסיגנלים רק בקרנלים 6.12 ומעלה, במאמץ מיטבי. קרנלים ישנים יותר נשארים רק עם כללי מערכת הקבצים והרשת, ולכן עם --x11, --network או --systemd-user ה-sockets האבסטרקטיים והסיגנלים של המארח נשארים נגישים.
  • ערוצי צד (side channels) וכמה סוגים של תקשורת בין-תהליכית.
  • יציאה מסוננת היא TCP בלבד. אין UDP, ולכן תוכנית שצריכה אותו לא עובדת, וגם לא יכולה להדליף דרכו.
  • DNS תחת --allow-host. ב-Linux, פתרון שמות בתוך ה-sandbox נכשל, ולכן אין ערוץ DNS החוצה. ב-macOS ה-resolver של המערכת לא מגודר, ולכן נשאר ערוץ DNS ברוחב פס נמוך, אותו פער ש-Anthropic מתעדת ב-sandbox-runtime שלה.
  • הפרוקסי רואה את ה-host, את הפורט ואת התזמון של כל חיבור. מה שעובר בפנים נשאר בין שני הקצוות. איך בנויה היציאה המסוננת.
  • פרטי גישה פנטום מעבירים את האמון אל ai-jail עצמו. עם --secret, בקשות אל ה-host שנקשר אליו עוברות דרך ai-jail בגלוי כדי שיוכל להכניס את המפתח האמיתי, והוא מצפין אותן מחדש בדרך החוצה. מנהרות לכל host אחר נשארות אטומות. זה מכסה רק לקוחות שיכולים לדבר HTTP רגיל עם הפרוקסי בשביל אותו host.
  • פרטי גישה שאתם מעבירים עם --github, --aws, --kube, --gcloud או --docker-config. קריאה בלבד מגינה על הקובץ מפני שינוי, לא על פרטי הגישה מפני שימוש: כל דבר בתוך ה-sandbox יכול לפעול בשמכם מול השירות הזה כל עוד הם בתוקף.
  • ב-macOS, הממשק sandbox-exec סומן על ידי Apple כ-deprecated ואינו שקול לבידוד שמתקבל ב-Linux. להבדלים ב-macOS.

מתגים שפותחים את החומה

כל מה שמופיע כאן כבוי עד שתדליקו אותו, חוץ משני מתגים שדלוקים כברירת מחדל: --toolchains ב-Linux ו---agent-state בכל מקום. רובם נותנים לסוכן גישה אמיתית. איך מגדירים אותם מוסבר בעמוד ההגדרה.

הצגת כל המתגים וההשלכות
מתגמה כל דבר שרץ ב-sandbox יכול לעשות אחר כך
--networkלשלוח לכל מקום את כל מה שהוא יכול לקרוא, בלי הגבלה על התעבורה. ברירת המחדל מתירה רק את ה-host של ה-API של סוכן מוכר, וב-Linux גם את ה-registries של החבילות; --allow-host היא החלופה ההדוקה יותר.
--allow-hostלהגיע בדיוק ל-hosts שציינתם ולתת-הדומיינים שלהם, ב-TCP דרך פרוקסי מובנה. כל host ברשימה זוכה לאמון מלא. הרשימה שלכם מתווספת ל-host של ה-API של הסוכן; --no-network עם רשימה נותן לכם את הרשימה הזו בלבד.
--forward-portלהשתמש במלואו בשירות אחד שיושב על ה-loopback של המארח. כל מה ששרת ה-MCP, ה-socket של העורך או מסד הנתונים שבפורט הזה מקבלים, הסוכן יכול לבקש, בלי רשימת היתרים, בלי בדיקה ובלי רישום ביומן הביקורת. כל שאר הפורטים של המארח נשארים סגורים. רק ב-Linux, ונדחה יחד עם --network.
--toolchainsדלוק כברירת מחדל ב-Linux. להריץ את ה-toolchains שלכם: ~/.cargo/bin ו-~/.rustup לקריאה בלבד, cache של תלויות ששייך לכלא תחת ~/.local/share/ai-jail/cache/ ושורד בין הרצות, ויציאה מסוננת ל-registries של חבילות. ה-caches האמיתיים של המארח לעולם לא מעוגנים. כבוי תחת --lockdown ועם --no-toolchains.
--secretשום דבר חדש. הערך האמיתי של המפתח הזה אף פעם לא נכנס ל-sandbox: הסוכן רואה placeholder, והפרוקסי מחליף אותו בערך האמיתי רק בבקשות HTTP רגיל אל ה-host האחד שקשרתם אותו אליו. התהליך של ai-jail עצמו רואה את הבקשה הזאת בגלוי.
--audit-logשום דבר חדש. המתג הזה לא מחליש כלום: הוא כותב שורה אחת לכל הפעלה לקובץ במצב 0600 מחוץ ל-sandbox, כך שהסוכן אף פעם לא רואה אותו.
--dockerלפעול כ-root על המחשב שלכם דרך ה-daemon של Docker.
--kvmלפתוח את /dev/kvm, ממשק הווירטואליזציה של הקרנל, כדי ש-QEMU, Firecracker או האמולטור של Android ירוצו במהירות החומרה. בלינוקס בלבד. האורחים מקבלים רק את הרשת של ה-sandbox, ושום /dev/net/tun לא מועבר.
--x11להקליט הקשות מקלדת ולצלם חלונות X11 אחרים.
--systemd-userלבקש מה-user manager של systemd להריץ שירותים על המארח.
--inherit-envלקרוא את כל סביבת ה-shell שלכם, כולל הסודות. למפתחות API, --env-from-file מעביר קובץ אחד במקום זה.
--agent-stateדלוק כברירת מחדל. להשתמש בהתחברות השמורה של הסוכן, למשל ~/.claude של Claude או ~/.local/share/devin ו-~/.config/devin של Devin, מעוגנות לקריאה וכתיבה, ובנוסף מפתח ה-API שלו שמועתק מה-shell שלכם כשהוא מוגדר, כך שהוא עולה מחובר. כל מה שרץ ב-sandbox יכול להשתמש בפרטי הגישה האלה למשך ההרצה. --no-agent-state נותן הרצה מבודדת, ללא התחברות; כבוי תחת --lockdown.
--githubלפעול בשמכם ב-GitHub. תיקיית ההגדרות של gh מעוגנת לקריאה בלבד, וה-token הפעיל של github.com נקרא מה-keyring של המערכת במארח ומועבר כ-GH_TOKEN להרצה הזאת בלבד, אף פעם לא בשורת הפקודה או בדיסק. קריאה בלבד מגינה על הקובץ, וה-token ממשיך לעבוד כל עוד הוא בתוקף.
--awsלפעול בשמכם ב-AWS עם ~/.aws, מעוגן לקריאה בלבד.
--kubeלפעול בשמכם בכל cluster שב-~/.kube, מעוגן לקריאה בלבד.
--gcloudלפעול בשמכם ב-Google Cloud עם ~/.config/gcloud, מעוגן לקריאה בלבד.
--docker-configלהשתמש בהתחברויות שלכם ל-registries של קונטיינרים שב-~/.docker/config.json, מעוגן לקריאה בלבד.
--audioלהקליט ולנגן אודיו כל עוד המתג דלוק.
--no-private-homeלראות את תיקיית הבית האמיתית שלכם. זו חריגה רחבה, ועדיף למפות רק את הנתיב האחד שאתם צריכים.

כשיש ספק, הוא מסרב לעלות

כלי sandbox שעולה בשקט במצב חלש ממה שביקשתם גרוע מכלי שעוצר עם שגיאה. במקרים האלה ai-jail עוצר.

  • קובץ הגדרות שקיים, אבל לא תקין או לא קריא.
  • קובץ .ai-jail של פרויקט שהוא symlink. כשהקובץ הגלובלי ~/.ai-jail הוא symlink, הולכים אחריו רק אם הוא מוביל לקובץ רגיל בבעלותכם, שאף אחד אחר לא יכול לכתוב אליו ושנמצא מחוץ לפרויקט.
  • הדגל --lockdown כש-Landlock, כללי מערכת הקבצים של הקרנל עצמו, חסר, חלקי או לא מצליח לחול. גם הצירוף --lockdown --no-landlock נדחה.
  • הדגל --allow-tcp-port. הממשק הזה לא מסוגל להגביל UDP, ולכן הדגל מתקבל לצורכי תאימות, ההפעלה נכשלת, והשגיאה מפנה אל --allow-host.
  • --network יחד עם --allow-host, או --browser עם --allow-host. השניים סותרים זה את זה, ולכן ai-jail מסרב לעלות.
  • --forward-port יחד עם --network, כשה-loopback של המארח כבר נגיש; מחוץ ל-Linux; ולפורט 0 או לפורט מתחת ל-1024, שה-sandbox לא יכול לקשור. ערך forward_ports בטבלת הבסיס של הקובץ הגלובלי נתקל בשני הראשונים בכל הפעלה של דפדפן ובכל הפעלה ב-macOS.
  • קובץ של --env-from-file שהוא symlink, שקריא לקבוצה שלו או לכולם, שבבעלות מישהו אחר או שנמצא בתוך הפרויקט.
  • ערך של BWRAP_BIN שמצביע על קובץ בינארי של bubblewrap שמישהו שאינו root יכול היה להחליף. הערך לא נלקח בחשבון ומודפסת אזהרה, ואם אין bubblewrap אמין ההפעלה נכשלת.
  • overlay שלא ניתן להקים: מקור חסר, יעד שחופף למיפוי אחר, או כשל באחסון. מגרסה 2.4 ההפעלה נעצרת במקום ליפול ל-bind רגיל של קריאה וכתיבה על הקבצים האמיתיים.

איך הפרויקט נבדק

מתחזק אחד מנהל את הפרויקט בגלוי. בהמשך מפורט מה נבדק ומה לא.

23
בדיקות אינטגרציה של בריחה מה-sandbox, שמנסות לכתוב אל /usr, לקרוא את ~/.ssh, לקרוא ל-ptrace ול-bpf, ומצפות להיכשל
959
בדיקות יחידה בעץ המקור בגרסה 2.9.0
0
בקשות רשת בזמן ההפעלה. בדיקת העדכונים היא opt-in, דרך --update-check

תיקוני אבטחה אחרונים

  • 2.9.0: --x11 לבדו מעביר X11 פנימה. קודם, בלי --display, הוא לא עשה כלום, בשקט.
  • 2.9.0: השמירה האוטומטית כבר לא כותבת לקובץ הפרויקט הפעלות יזומות שהטעינה הלא אמינה דוחה אחר כך, ולכן קובץ שנשמר לא מציג אזהרה בהרצה הבאה.
  • 2.9.0: macOS: Codex עולה שוב תחת Seatbelt עם shim פרטי של ps במקום ה-ps ה-setuid של המארח.
  • 2.8.0: macOS: פרופיל ה-seatbelt שומר על ההתחברות של Claude Code ב-Keychain ומתיר את ה-socket של הבקרה של Codex, כך ששניהם עולים כשהם מחוברים.
  • 2.8.0: בקשות למיקום הסמן מ-launcher נענות על ידי הטרמינל הווירטואלי, כך ש-launchers כבר לא נתקעים.
  • 2.6.2: --lockdown תמיד מבודד את ה-network namespace, גם עם --network. קודם, הצמד הסותר הזה השאיר את ה-namespace משותף.
  • 2.6.2: הערכים של --env ו---env-from-file כבר לא יושבים בשורת הפקודה של ה-launcher, שבה כל תהליך שרץ בשמכם יכול היה לקרוא אותם. הם עוברים דרך קובץ בזיכרון.
  • 2.4.0: מטא-דאטה של worktree בריפוזיטורי כבר לא יכול לעגן תיקייה שרירותית במארח לקריאה וכתיבה.
  • 2.4.0: רשומה כפולה בסביבה כבר לא מכניסה את הערך האמיתי של מפתח --secret לתוך ה-sandbox.
  • 2.4.0: פקודת דפדפן בקובץ .ai-jail לא אמין של פרויקט כבר לא מבטלת lockdown.
  • 2.4.0: TIOCSTI מושווה כפי שהקרנל קורא אותו, ב-32 ביט, כך שגרסה עם ביט גבוה כבר לא עוברת את seccomp.
  • 2.4.0: Landlock מגדר sockets אבסטרקטיים של Unix וסיגנלים בקרנלים 6.12 ומעלה.
  • 2.4.0: macOS: הגישה לטרמינל מוגבלת לטרמינלים של ההרצה הזאת, ולא לכל /dev/ttys*.
  • 2.4.0: macOS: נתיבים עם --mask נדחים גם לכתיבה, ולא רק לקריאה.
  • 2.4.0: מסנן הפלט כבר לא קורס על ESC כפול, שיכול היה להגניב דרכו כתיבה ללוח ההעתקה.
  • 2.4.0: פתחי הבדיקה של הפרוקסי לא נכללים יותר ב-builds של release.

איך נוצרת גרסה

  • תגיות הגרסה חתומות, וה-CI מאמת כל אחת מהן מול טביעת אצבע של מפתח שמקובעת בריפוזיטורי.
  • כל GitHub Action מקובע ל-SHA של commit, וה-actions מוגבלים לרשימת היתרים.
  • ה-builds משתמשים ב-toolchain מקובע של Rust ובתלויות עם --locked.
  • הקבצים הבינאריים של macOS חתומים ועברו notarization של Apple.
  • לכל ארכיון מצורף checksum מסוג SHA-256, ושלב הפרסום בודק אותם שוב.

מה עדיין חסר, לפי מסמך הגרסאות

  • סודות החתימה והפרסום עדיין שמורים ברמת הריפוזיטורי, וצריכים לעבור לסביבות ה-release.
  • עדיין אין ruleset שמחייב חתימה על כל תגית v*.
  • האפשרות immutable releases לא מופעלת.
  • הפרסום ל-crates.io עדיין נעשה עם טוקן. מעבר ל-trusted publishing מתוכנן.
  • עם מתחזק יחיד, אין בודק שני לשינויים או לגרסאות.

לקובץ RELEASE_SECURITY.md

דיווח על פגיעות

אל תפתחו issue ציבורי. השתמשו בדיווח הפרטי על פגיעויות של GitHub, צרפו את שלבי השחזור ואת הגרסאות המושפעות, והשאירו זמן לתיאום התיקון.

שאלות נפוצות

הסוכן יכול לפרוץ החוצה?
ברירות המחדל נבנו ונבדקו כדי לחסום את הדרכים הרגילות שסוכן טועה הולך בהן: קבצים, סביבה, רשת ו-IPC של המארח. הן לא נבנו לעמוד מול תוקף נחוש: משהו שמנסה באופן פעיל לברוח יכול להשתמש בבאג בקרנל, בדרייבר, בטרמינל או ב-backend של ה-sandbox, ולכן קוד עוין שייך למכונה וירטואלית חד-פעמית.
בטוח להריץ כשהרשת דלוקה?
זה בטוח יותר מלהריץ את הסוכן חשוף, כי המפתחות ותיקיית הבית שלכם עדיין לא נמצאים שם ואין מה לשלוח. עם --network, כל מה שהסוכן יכול לקרוא הוא יכול גם לשלוח, ו-ai-jail לא נבנה כדי לעצור תוקף נחוש שמנסה לעשות את זה. דרך הביניים היא --allow-host: הסוכן מגיע רק ל-hosts שציינתם, וכל אחד מהם זוכה לאמון מלא. מסכו קודם את הסודות שבתוך הפרויקט. כך ממסכים אותם.
הוא עבר ביקורת?
בגלוי. הפרויקט ערך ביקורת על עצמו לפני גרסה 1.0, ובספטמבר 2026 פורסמו בריפוזיטורי שתי ביקורות קוד בלתי תלויות של גרסה 2.3.0; גרסה 2.4.0 סגרה את שני ה-advisories שהן הניבו. אף חברה חיצונית לא ערכה ביקורת על הכלי. הקוד פתוח ברישיון GPL 3.0, ודיווחים פרטיים על פגיעויות יתקבלו בברכה.

שימו את הסוכן מאחורי סורגים

כל ai-jail הוא קובץ בינארי אחד, בלי daemon ובלי root. מוסיפים מילה אחת לפני הפקודה שאתם מריצים ממילא.

terminal
brew tap akitaonrails/tap && brew install ai-jailai-jail claude