ข้ามไปยังเนื้อหา

แซนด์บ็อกซ์และความปลอดภัย

เอเจนต์อ่านไฟล์ รันคำสั่งเชลล์ และเรียก API ภายนอกในนามของคุณ ความล้มเหลวที่คุณกังวลนั้นแทบไม่เคยเกิดจากเจตนาร้าย — แต่เป็นเอเจนต์ที่อ่านเส้นทางผิดแล้วเขียนทับเช็กเอาต์ที่คุณกำลังทำงานอยู่ หรือตัวที่พุชสาขาที่คุณยังรีวิวไม่จบ คำถามที่ผลิตภัณฑ์ต้องตอบจึงไม่ใช่ “เอเจนต์เชื่อถือได้ไหม” แต่เป็น “ขอบเขตความเสียหายจะกว้างแค่ไหนเมื่อมันทำผิด”

Control Center ตอบคำถามนั้นเป็นชั้น ๆ และชั้นเหล่านั้นเป็นอิสระจากกันโดยเจตนา หากชั้นหนึ่งหายไป ชั้นอื่นยังคงอยู่ นั่นสำคัญ เพราะชั้นนอกสุด — แซนด์บ็อกซ์ของ OS — เป็นชั้นเดียวที่มีเงื่อนไข: มันขึ้นอยู่กับว่าโฮสต์มีแบ็กเอนด์ให้หรือไม่ และบน Windows ไม่มีโฮสต์ใดมี

มีห้าสิ่งที่คุมการรันของเอเจนต์บนทุกโฮสต์ ไม่ว่าจะมีแซนด์บ็อกซ์หรือไม่ ไม่มีสิ่งใดเป็นขอบเขตระดับเคอร์เนล แต่ทั้งหมดเป็นของจริง ที่ใดโฮสต์มีแบ็กเอนด์ แซนด์บ็อกซ์ของ OS จะวางอยู่เหนือสิ่งเหล่านี้ และหัวข้อ “แซนด์บ็อกซ์เพิ่มอะไรและหยุดตรงไหน” ด้านล่างอธิบายว่ามันเปลี่ยนอะไรไปบ้าง

worktree แบบ copy-on-write ของตัวเอง การสนทนาทุกครั้งจัดสรรเช็กเอาต์ของตัวเองสำหรับแต่ละรีโปที่เชื่อมไว้ โดยโคลนแบบ copy-on-write ผ่าน rift เนทีฟที่มาพร้อมระบบ แทนที่จะคัดลอกทีละไบต์ การแยกตัวจึงถูกพอที่จะเป็นค่าเริ่มต้น รีโปที่ลงทะเบียนซึ่งคุณเพิ่มเข้าเวิร์กสเปซไม่ใช่ไดเรกทอรีที่เอเจนต์ทำงานอยู่ — การสนทนาสองรายการที่แตะรีโปเดียวกันมองไม่เห็นการแก้ไขของกันและกัน และไม่มีรายใดกำลังแก้ไขเช็กเอาต์ของคุณ

ความละเอียดของมันควรพูดให้แม่น: worktree เป็นรายการต่อการสนทนา ไม่ใช่ต่อเอเจนต์ เอเจนต์สองตัวในการสนทนาเดียวกันได้ไดเรกทอรีทำงานแบบโอเวอร์เลย์ที่แยกจากกัน ซึ่ง ใช้ร่วมกัน repos/ ของการสนทนานั้น — นั่นแหละคือประเด็น เพราะมันกำลังร่วมมือกันในหนึ่งการเปลี่ยนแปลง — ขณะที่ไดเรกทอรีส่วนตัวของแต่ละเอเจนต์ยังแยกจากกัน copy-on-write เป็นแบ็กเอนด์เดียวในทุกที่ที่ rift ถูกส่งมาให้ใช้: ระบบไฟล์ที่ไม่สามารถ reflink ได้ หรือไดเรกทอรีข้อมูลที่อยู่คนละโวลุ่มกับรีโป จะทำให้การจัดสรรล้มเหลวแทนที่จะถอยกลับไปใช้วิธีอื่น Windows เป็นข้อยกเว้น — ที่นั่นไม่มีแบ็กเอนด์ copy-on-write ดังนั้น git worktree จึงเป็นแบ็กเอนด์ ไม่ใช่การถดถอยอย่างเงียบ ๆ

การจำกัดเส้นทางในเครื่องมือไฟล์ของฮาร์เนสในตัว เครื่องมือ read, write, edit, apply_patch, search, find และ search_files ของฮาร์เนสจะแปลงทุกเส้นทางเทียบกับไดเรกทอรีทำงานของการรันบวกกับรูทที่ใช้ร่วมกัน — ไดเรกทอรี repos/ ของการสนทนา ซึ่งเป็นที่อยู่ของ worktree ต่าง ๆ และไดเรกทอรีไฟล์แนบของสเปซเมื่อมีอยู่ — และปฏิเสธทุกอย่างที่ตกอยู่นอกนั้น เส้นทางแบบสัมบูรณ์จะถูกยอมรับก็ต่อเมื่อมันอยู่ข้างในอยู่แล้ว ซิมลิงก์ที่อยู่ภายใน worktree แล้วชี้ไปข้างนอกก็ถูกแปลงค่าและปฏิเสธเช่นกัน นี่คือเหตุผลที่เอเจนต์ write ไปยัง ~/.ssh ไม่ได้ แม้จะไม่มีแซนด์บ็อกซ์อยู่ในภาพเลย

พื้นผิวเครื่องมือของโหมด โหมดของการสนทนาเป็นตัวตัดสินว่าเครื่องมือใดถูกทำให้มีอยู่สำหรับการรันตั้งแต่แรก ในโหมดอ่านอย่างเดียว (plan, review, orchestrate) เครื่องมือที่เปลี่ยนแปลงสถานะไม่ได้อยู่ในรีจิสทรีเลย และนโยบายคำสั่งเชลล์ของโหมดเหล่านั้นปฏิเสธทุกคำสั่งที่เปลี่ยนแปลงสถานะโดยตรง — git commit, git push, npm install, docker และอื่น ๆ — แทนที่จะถามก่อนสำหรับคำสั่งเหล่านั้น เครื่องมือที่ไม่มีอยู่ย่อมเรียกใช้ไม่ได้ ซึ่งเป็นหลักประกันที่แข็งแรงกว่าเครื่องมือที่มีอยู่และถูกกั้นไว้

กฎคุมการกระทำแบบรวมศูนย์ เครื่องมือที่เปลี่ยนแปลงสถานะทุกตัวประกาศคลาสผลกระทบที่มันก่อได้ และเอนจินนโยบายแปลงแต่ละคลาสเป็น อนุญาต, ถามก่อน หรือ ปฏิเสธ ก่อนที่การเรียกจะรัน prompt ที่ไม่มีผู้อนุมัติเชื่อมต่ออยู่จะแปลงเป็น ปฏิเสธ — คำถามที่ไม่มีใครตอบได้ไม่เคยเป็นคำตอบว่าใช่ ดูกฎคุมสำหรับแบบจำลองการแปลงคำตัดสิน

ข้อมูลรับรองที่ผ่านนายหน้าและสภาพแวดล้อมที่ชำระล้างแล้ว ข้อมูลรับรองถูกสร้างขึ้นใหม่ต่อการเรียกใช้หนึ่งครั้ง และถูกเพิกถอนเมื่อการรันสิ้นสุด โทเคน GitHub ที่การรันถืออยู่อ่านได้แต่พุชไม่ได้ — ดู “การพุชผ่าน Control Center” ด้านล่าง ACP, bash ของฮาร์เนส และ Claude Code ภายใต้การห่อแบบเนทีฟจะได้สภาพแวดล้อมที่ตัดเวกเตอร์การแทรกผ่านตัวเชื่อมไดนามิกและตัวแปลคำสั่ง (LD_PRELOAD, DYLD_INSERT_LIBRARIES, NODE_OPTIONS, GIT_SSH_COMMAND และญาติ ๆ ของมัน) ออกก่อนที่โปรเซสจะเริ่ม Claude Code ผ่าน NoSandboxAdapter สืบทอดสภาพแวดล้อมของโฮสต์

เครื่องมือไฟล์ของฮาร์เนสทำงาน ในโปรเซสของเซิร์ฟเวอร์ ไม่ใช่ในโปรเซสลูก ดังนั้นไม่มีโปรไฟล์แซนด์บ็อกซ์ใดคุมมันได้ แม้จะถูกแนบไว้ก็ตาม — มีเพียง bash ที่ผ่านตัวรันคำสั่งที่อยู่ในแซนด์บ็อกซ์ การจำกัดของมันคือการตรวจเส้นทางที่อธิบายข้างต้น การตรวจนั้นจึงเป็นชิ้นส่วนที่รับน้ำหนักจริง ไม่ใช่แนวป้องกันชั้นที่สอง

เครื่องมือ bash เป็นอีกจุดที่ต้องพูดให้แม่น คำสั่งของมันถูกประเมินเทียบกับนโยบายคำสั่งของโหมด แล้วจึงสปอว์นด้วยสภาพแวดล้อมที่ชำระล้างแล้วและมี worktree เป็นไดเรกทอรีทำงาน ที่ใดมีแบ็กเอนด์ การสปอว์นนั้นจะถูกห่อ แซนด์บ็อกซ์จึงเป็นสิ่งที่หยุดคำสั่งเชลล์ไม่ให้เขียนนอก worktree; ที่ใดไม่มี — Windows หรือ Linux ที่ไม่มี bwrap และ socat — นโยบายคำสั่งเป็นสิ่งเดียวที่คั่นระหว่างคำสั่งกับส่วนที่เหลือของดิสก์ ในโหมด chat นโยบายจะปฏิเสธแบบเด็ดขาดรายการที่กำหนดตายตัวไว้ (การยกระดับสิทธิ์ การทำลายระบบและดิสก์ การหลบหนีออกจากคอนเทนเนอร์และเนมสเปซ) และถามก่อนกับการเปลี่ยนแปลงสถานะระยะไกล (git push, gh pr create, การเผยแพร่และการติดตั้งแพ็กเกจ) อะไรที่ไม่อยู่ในทั้งสองรายการจะรันได้ ไปป์ไลน์ การเชื่อมด้วยเชน และซับเชลล์จะถูกแยกวิเคราะห์ และประเมินแต่ละคำสั่งย่อยแยกกัน โดยคำตัดสินที่เข้มงวดที่สุดเป็นผู้ชนะ

Claude Code เมื่อใช้เป็นอะแดปเตอร์ คือกรณีที่แซนด์บ็อกซ์รับน้ำหนักมากที่สุด Control Center เรียกมันด้วย --dangerously-skip-permissions เพราะ claude -p แบบไม่โต้ตอบจะค้างอยู่ตลอดไปที่พรอมต์อนุมัติของตัวเอง การเรียกอ่าน เขียน และแก้ไขของมันเกิดขึ้นในโปรเซสของมันเอง และ Control Center ไม่เคยเห็นเลย การเรียก Bash ของมันไปถึงฮุกบนเซิร์ฟเวอร์ก่อนรัน ซึ่งจัดประเภทบรรทัดคำสั่งแล้วถามกฎที่ตรงกัน ส่วนเครื่องมือ mcp__* ที่ Control Center ให้บริการเองก็ผ่านด่านตามปกติ ที่ใดมีแบ็กเอนด์ การเรียกที่มองไม่เห็นเหล่านั้นก็ยังเกิดขึ้นภายในที่ห่อของแซนด์บ็อกซ์ OS จึงเป็นขอบเขตรอบ ๆ มัน ที่ใดไม่มี ก็ไม่มีอะไรเลย อะแดปเตอร์แต่ละตัวระบุเรื่องนี้ในเมทริกซ์การบังคับใช้ของมัน — ดูเมทริกซ์ความซื่อตรงของอะแดปเตอร์

ไม่มีแฟล็กสิทธิ์รายเอเจนต์ การที่เอเจนต์จะสร้างคอมมิต พุช เปิด pull request เขียนไปยังตัวติดตาม หรือเข้าถึงเครือข่ายได้หรือไม่ ถูกตัดสินโดยกฎคุม — อนุญาต ถามก่อน หรือปฏิเสธ — และกฎชุดเดียวกันใช้ได้ไม่ว่าอะแดปเตอร์ใดจะรันเอเจนต์

การพุชคือการกระทำที่ต้องยืนหยัดได้แม้เอเจนต์จะพยายามหลบเลี่ยงกฎ มันจึงถูกบังคับใช้ด้วยสิ่งที่เอเจนต์ถืออยู่ ไม่ใช่ด้วยสิ่งที่มันรัน เมื่อกำหนดค่า GitHub App ไว้ การรันใน worktree ของ GitHub จะได้โทเคนการติดตั้งที่จำกัดเฉพาะรีโปเดียว ซึ่งอ่านเนื้อหาและทำงานกับ pull request ได้ แต่พุชไม่ได้ การตั้งค่า git ของการรันจะเขียนทุก URL พุชของ GitHub (https://github.com/, git@github.com:, ssh://git@github.com/) ใหม่ให้ชี้ไปยัง เกตเวย์การรันเอเจนต์ — เอนด์พอยต์ลูปแบ็กบน cc_server เกตเวย์อ่านว่าการพุชอัปเดต ref ใดบ้าง ถามกฎ พุชไปยังรีโมต — กฎที่จำกัดตามสาขา เช่น “ปฏิเสธการพุชไป main” จึงมีผลด้วย — แล้วจึงส่งการพุชต่อไปยัง GitHub ด้วยโทเคนเขียนที่มันสร้างขึ้นเพื่อการนี้และไม่เคยมอบให้เอเจนต์ การพุชที่ถูกปฏิเสธจะปรากฏในเอาต์พุตของ git เอง:

! [remote rejected] main -> main (Control Center policy: …)

เกตเวย์ส่งต่อการพุชไปยังรีโปของ worktree เองหรือรีโป GitHub ที่ลิงก์กับเวิร์กสเปซเท่านั้น การ fetch ไปถึง GitHub โดยตรงด้วยโทเคนแบบอ่านอย่างเดียว

คำสั่งเชลล์อื่น ๆ เจอด่านที่อ่อนกว่า เครื่องมือ bash ของฮาร์เนส และเครื่องมือ Bash ของ Claude Code ผ่านฮุก จะจัดประเภทแต่ละบรรทัดคำสั่งและถามกฎที่มันเข้าข่าย: git commit, merge, rebase, cherry-pick, revert และ am เข้าข่าย สร้างคอมมิต; gh pr create เข้าข่าย เปิด pull request; gh pr merge, review, comment และ close เข้าข่าย เผยแพร่รีวิวหรือรวม; gh issue create, edit, comment และ close เข้าข่าย เขียนไปยังตัวติดตามภายนอก; การติดตั้งแพ็กเกจเข้าข่าย ติดตั้งแพ็กเกจ; และ curl กับ wget เข้าข่าย เข้าถึงเครือข่าย วิธีนี้จับรูปแบบทั่วไปของการกระทำได้ แต่เอเจนต์ที่ตั้งใจซ่อนมัน (eval, ไฟล์สคริปต์, การเรียก API โดยตรง) ก็ทำได้ การพุชไม่ได้พึ่งสิ่งนี้

ไม่มีคีย์ API ของตั๋วงานใดถูกใส่ลงในแซนด์บ็อกซ์ เอเจนต์เขียนตั๋วงานผ่านเครื่องมือ MCP ของ Control Center ซึ่งถามกฎ เขียนไปยังตัวติดตามภายนอก

กฎ เข้าถึงเครือข่าย ถูกอ่านครั้งเดียวตอนเริ่มรัน เครือข่ายของแซนด์บ็อกซ์มีแค่เปิดหรือปิด ดังนั้นปฏิเสธจะปิดมัน ส่วนอนุญาตและถามก่อนจะคงไว้ให้เปิด; เครื่องมือ web_fetch และ web_search ของฮาร์เนสยังถามทุกครั้งที่เรียก ข้อมูลรับรองถูกเพิกถอนเมื่อการรันรื้อถอน รวมถึงโทเคนเขียนทุกตัวที่เกตเวย์สร้างขึ้น แฮนเดิลจึงไม่อายุยืนกว่าการรัน

อีนัม SandboxBackend มีสามค่า — native (Seatbelt บน macOS, bubblewrap บน Linux และ WSL2), none และ microvm การห่อคำสั่งของเอเจนต์ใช้เพียงสองค่าแรก: microvm เป็นแบ็กเอนด์แบบ VM ปิดล้อมสำหรับเทอร์มินัลแบบโต้ตอบและริก ไม่ใช่การอัปเกรดการห่อ bash อย่างเงียบ ๆ การเข้าใจรูปร่างของแบบเนทีฟอธิบายว่าคุณได้อะไรเมื่อมีมันแนบอยู่ และสิ่งที่มันไม่เคยจะให้คุณได้เลย

cc_server ตรวจสอบโฮสต์ครั้งเดียวตอนบูต และที่ใดแบ็กเอนด์ตอบรับ มันจะป้อนทั้งสองรอยต่อที่เส้นทางการสั่งงานมี เพราะทรานสปอร์ตไม่ได้ใช้รอยต่อร่วมกัน ตัวแรก (SandboxPort) ห่อ Claude Code CLI ตัวที่สอง (SandboxManager) ห่ออะแดปเตอร์ ACP และเครื่องมือ bash ของฮาร์เนสในตัว การป้อนเพียงรอยต่อเดียวจะปล่อยให้ตัวอื่นสปอว์นแบบไม่ถูกห่อ ซึ่งเป็นสิ่งที่เคยเกิดขึ้น บนโฮสต์ที่ไม่มีแบ็กเอนด์ หรือภายใต้ --sandbox off พวกมันทั้งหมดสปอว์นแบบไม่ถูกห่อ และเซิร์ฟเวอร์จะบอกว่าคุณอยู่กรณีใดบนบรรทัดเริ่มต้นของมัน ACP และ bash ของฮาร์เนสยังคงชำระล้างสภาพแวดล้อม; Claude Code ผ่าน NoSandboxAdapter สืบทอดสภาพแวดล้อมของโฮสต์

มีพื้นผิวหนึ่งที่จงใจเลือกไม่ใช้: เทอร์มินัลที่โฮสต์บนเซิร์ฟเวอร์รับอาร์กิวเมนต์แบ็กเอนด์ต่อเซสชัน และ cc_server สร้างมันโดยปริยายเป็นเชลล์ของโฮสต์ เทอร์มินัลที่คุณเปิดจากแอปจึงรันโดยไม่มีแซนด์บ็อกซ์ เว้นแต่ไคลเอนต์จะระบุ native อย่างชัดเจน นั่นคือเชลล์จริงบนโฮสต์ของเซิร์ฟเวอร์ ไม่ใช่การรันของเอเจนต์

บน Linux bubblewrap สร้างเมานต์เนมสเปซ เอเจนต์จึงเห็นเฉพาะสิ่งที่ถูกผูกเข้าไปเท่านั้น บน macOS sandbox-exec ใช้โปรไฟล์ Seatbelt ที่ ผ่อนปรนโดยค่าเริ่มต้น — โปรไฟล์ที่ปฏิเสธโดยค่าเริ่มต้นทั้งหมดจะทำให้เชลล์แบบโต้ตอบใช้ไม่ได้ เพราะจำนวนการเรียก dyld, XPC และ Mach ที่ต้องแจกแจงนั้นทำได้ไม่จริง โปรไฟล์ของ macOS จึงเริ่มจาก (allow default) แล้วเจาะออกเป็นข้อปฏิเสธต่าง ๆ: การอ่านเส้นทางลับ, นโยบายการเขียนที่รีเซ็ตเป็นปฏิเสธโดยมีข้อยกเว้นแบบอนุญาตที่ระบุชัดเจนวางทับ, การบล็อก unlink บนทุกเส้นทางที่ถูกปฏิเสธและบรรพบุรุษของมัน เพื่อไม่ให้การเปลี่ยนชื่อข้ามข้อปฏิเสธการเขียนได้, การปฏิเสธ exec สำหรับไบนารีที่อันตรายเสมอและสำหรับอะไรก็ตามที่ถูกคัดลอกเข้าไปในไดเรกทอรีที่เขียนได้ และจำกัดเครือข่ายไว้ที่พอร์ตพร็อกซีลูปแบ็กบวก DNS

ผลในทางปฏิบัติ: บน Linux มุมมองระบบไฟล์ของเอเจนต์ถูกทำให้แคบลง; บน macOS เอเจนต์ยังคง อ่าน ส่วนใหญ่ของโฮสต์ได้ และเช็กเอาต์ที่ลงทะเบียนไว้ของคุณได้รับการปกป้องด้วยข้อปฏิเสธการเขียนและการเปลี่ยนชื่อที่ระบุชัดเจน แทนที่จะด้วยการมองไม่เห็น ทั้งสองเป็นการแยกตัวระดับเนมสเปซ ไม่ใช่ขอบเขตความปลอดภัยระดับเคอร์เนล — แบ็กเอนด์บอกเช่นนั้นในบันทึกความสามารถของตัวเอง

ชุดการเมานต์แบบผูกคือจุดที่ขอบเขตระหว่างเอเจนต์ถูกวาดขึ้น การสั่งงานแบบโอเวอร์เลย์ (Claude Code และ ACP) เมานต์ได้ถึงสี่เส้นทาง ซึ่งแปลงต่อการรัน: ไดเรกทอรีทำงานแบบโอเวอร์เลย์ของเอเจนต์แบบอ่าน-เขียน, ไดเรกทอรีการกำหนดค่าของเอเจนต์แบบอ่านอย่างเดียว, ไดเรกทอรี repos/ ที่ใช้ร่วมกันของการสนทนาแบบอ่าน-เขียนเมื่อมีอยู่ และไดเรกทอรีไฟล์แนบของสเปซแบบอ่านอย่างเดียวเมื่อมีอยู่ ไดเรกทอรีของเอเจนต์พี่น้องไม่เคยถูกเมานต์ การห่อ bash ของฮาร์เนสแคบกว่า: มันเมานต์แบบผูกเฉพาะไดเรกทอรีทำงานของการรัน นี่คือรูปร่างเดียวกับการตรวจเส้นทางในโปรเซสของฮาร์เนสที่บังคับใช้ในซอฟต์แวร์ ทั้งสองจึงสอดคล้องกัน — แต่มีเพียงการตรวจเส้นทางเท่านั้นที่ครอบคลุมเครื่องมือไฟล์ของฮาร์เนสเอง ซึ่งไม่เคยไปถึงเมานต์เนมสเปซเลย

เช็กเอาต์ที่ลงทะเบียนไว้ของคุณเข้าร่วมชุดปฏิเสธการเขียนบนนั้นอีกชั้น ในทุกโหมดและบนทั้งสามเส้นทางที่ถูกห่อ (Claude Code, ACP, bash ของฮาร์เนส) และแต่ละกฎถูกปล่อยออกมาทั้งในรูปตามตัวอักษรและรูปที่แปลงซิมลิงก์แล้ว รูปที่สองไม่ใช่เรื่องเล่น ๆ: เคอร์เนลจับคู่กฎปฏิเสธกับเส้นทางที่แปลงค่าแล้ว และ macOS ทำให้การแปลงค่าเป็นกรณีปกติมากกว่ากรณีพิเศษ — /tmp จริง ๆ คือ /private/tmp, /var/folders/… จริง ๆ คือ /private/var/folders/… — เช็กเอาต์ที่เข้าถึงผ่านทางใดทางหนึ่งจึงเขียนได้ ทั้งที่โปรไฟล์ดูเหมือนห้ามไว้

เครือข่ายภายใต้แซนด์บ็อกซ์คือรายการที่อนุญาตระดับ โดเมน ต่อเซสชัน ซึ่งบังคับใช้ด้วยพร็อกซีลูปแบ็กในโปรเซส การเชื่อมต่อขาออกถูกปฏิเสธโดยค่าเริ่มต้น: เมื่อเครือข่ายปิดอยู่ พร็อกซียังคงเริ่มทำงานแต่รายการที่อนุญาตของมันว่างเปล่า ทุกการเชื่อมต่อขาออกจึงถูกปฏิเสธ เมื่อเปิดอยู่ ตัวแปลงจะสร้างรายการที่อนุญาตจากฐานที่คัดสรรไว้ — ผู้ให้บริการ API ของ LLM, โฮสติ้ง git, รีจิสทรีแพ็กเกจ, แค็ตตาล็อกโมเดล — บวกโดเมน GitHub และจับคู่โฮสต์เป้าหมายของการเชื่อมต่อทุกครั้งกับรายการนั้น ไวลด์การ์ดใช้ได้ (*.example.com จับคู่ซับโดเมน ไม่ใช่โดเมนหลัก) รายการที่ถูกปฏิเสธเสมอซึ่งแยกต่างหากจะชนะรายการที่อนุญาต และครอบคลุมปลายทางเมทาดาทาของคลาวด์และจุดรับส่งเทเลเมตรี สิ่งที่ ไม่ กำหนดค่าได้คือตัวรายการเอง: สเปกพกฟิลด์ egressAllowlist สำหรับโดเมนเพิ่มเติม แต่ไม่มีอะไรในเส้นทางการสั่งงานเติมค่านั้น ในทางปฏิบัติการรันทุกครั้งจึงได้ฐานบวก GitHub และไม่มีอะไรอีก

การปฏิเสธบน macOS สังเกตได้: ตัวมอนิเตอร์ดึงล็อกระบบเพื่อหาการปฏิเสธของ Sandbox กรองสัญญาณรบกวนที่รู้จัก ลบรายการซ้ำจากพายุการลองซ้ำ และเปิดเผยแต่ละครั้งเป็น SandboxViolation ที่ระบุว่าพยายามทำอะไรและอะไรถูกบล็อก บน Linux เส้นทางการห่อจะแยกวิเคราะห์ stderr เพื่อหา EPERM, Operation not permitted และ Permission denied แล้วปล่อยเหตุการณ์ชนิดเดียวกัน — ไม่มีการดึงล็อกระบบ สิ่งเหล่านี้มาถึงบนสตรีมเหตุการณ์ของการรันเอง การเรียกซิสคอลที่ถูกปฏิเสธจึงปรากฏในทรานสคริปต์ ไม่ใช่แค่ในล็อก เทเลเมตรีนี้มีอยู่เฉพาะขณะที่แซนด์บ็อกซ์แบบเนทีฟกำลังห่อโปรเซสจริง ๆ — บนโฮสต์ที่ไม่มีแบ็กเอนด์ไม่มีอะไรให้สังเกต มันยังไม่เกี่ยวข้องกับกฎคุม: การละเมิดมาจากซิสคอลที่ถูกปฏิเสธ ไม่เคยมาจากการค้นหากฎ

แซนด์บ็อกซ์ไม่มีเส้นทางการอนุมัติ มันเรียกใช้ ดำเนินการ ปล่อยเหตุการณ์ และรื้อถอน; ไม่มีที่ไหนในนั้นให้มนุษย์ตอบคำถาม เมื่อคุณเห็นการยืนยันในสเปซ — อนุมัติการพุชนี้, อนุมัติการลบนี้ — มันถูกยกโดยเอนจินกฎคุม (หรือนโยบายคำสั่งของฮาร์เนส) ก่อน ที่การกระทำจะไปถึงรันไทม์เลย

ลำดับนี้เป็นเจตนา การอนุมัติที่เกิดหลังซิสคอลจะเป็นบันทึกการตรวจสอบ ไม่ใช่ด่านกั้น มันยังเป็นเหตุผลที่กฎแบบปิดเมื่อล้มเหลว (fail-closed) อยู่ในกฎคุม: เมื่อไม่มีผู้อนุมัติเชื่อมต่ออยู่ คำตัดสินถูกทำก่อนอะไรจะรัน และมันคือการปฏิเสธ

รันการวินิจฉัยเอเจนต์ เป็นที่เดียวที่ระบุว่าอะไรตรวจสอบด้วยมือได้