دع الوكيل يُشغّل الكود دون أن يُدمّر جهازك
قبل أشهر قليلة، رأيت وكيلاً يقرر أن أنظف طريقة "لإعادة ضبط قاعدة بيانات الاختبار" هي تنفيذ rm -rf على مسار بناه من متغير تبيّن أنه فارغ. الأمر الذي اقترحه فعلاً كان rm -rf /$DIR، وكان $DIR لا شيء. اكتشفت الأمر لأنني كنت أعمل في الوضع الافتراضي وسألني أولاً. نقرت على "لا"، أصلحت السكريبت، وذهبت لأُعدّ القهوة بيدين ترتجفان قليلاً.
كان ذلك على حاسوبي الحقيقي. الجهاز ذاته الذي يحتوي على مفاتيح SSH الخاصة بي، وملف ~/.aws/credentials، ومفتاح Stripe المقيّد في ملف .env على بُعد مجلدين، والنسخة الوحيدة من مشروع جانبي لم أرفعه بعد. لم يكن الوكيل خبيثاً. كان مجرد مخطئ، كما يكون المطوّر المبتدئ السريع مخطئاً، إلا أنه يكتب 200 أمر في الدقيقة ولا يتعب أبداً ليتباطأ.
ما استغرق مني وقتاً طويلاً لاستيعابه: الخطر ليس في تمرّد الوكيل. بل في التقاطع المملّ بين أمر خاطئ واثق من نفسه، وبيانات اعتماد في متغير بيئي، واتصال شبكي يمكنه الوصول إلى الإنترنت المفتوح. لا تحتاج إلى شرير. تحتاج إلى حادث ومسار تسريب، ومعظم الإعدادات تشحن الاثنين معاً بشكل افتراضي.
الخلاصة: العزل طيف وليس مفتاحاً. أرخص طبقة هي نوافذ الأذونات الخاصة بالوكيل. أقواها هي microVM بنواتها الخاصة. للعمل اليومي على كود كتبته بنفسك، تحتاج إلى حمايات على مستوى نظام التشغيل مع بوابات أذونات. لأي شيء لم تكتبه أنت — مستودع عشوائي، سكريبت مُجمَّع، كود أنشأه وكيل آخر — تحتاج إلى حاجز حقيقي لا يمكن إقناع نظام التشغيل بتجاوزه. فيما يلي السلّم بأكمله وأين أقف فعلاً على كل درجة.
نموذج الحادث، لا نموذج الشرير
اعمل على نمذجة التهديد بصدق وستصبح الصورة أبسط. ثلاثة أشياء يمكن أن تسوء عندما يُشغّل الوكيل كوداً:
- يُدمّر الحالة المحلية. يحذف ملفات، يكتب فوق الشيء الخطأ، يُجبر على دفع التغييرات فوق فرعك.
- يقرأ سراً ويُرسله إلى مكان ما. يبحث في
~/.ssh، يجد رمزاً في متغير بيئي، يُرسله عبرcurlإلى نطاق ما. هذا هو ما يُقلّل الناس من شأنه. - يُشغّل كوداً لم تثق به قط. سكريبت post-install لإحدى التبعيات، حمولة مُولَّدة، مستودع استنسخته لـ"مجرد الاطلاع."
نوافذ الأذونات تعالج (1) وجزئياً (3). لا تفعل شيئاً تقريباً لـ(2)، لأنه بحلول وقت تشغيل الأمر، يكون السر قد دخل بيئة العملية بالفعل. لذا فالحل ليس "إيجاد الأداة الواحدة التي تحل كل شيء." بل: تراكم طبقة رخيصة توقف الدمار الأحمق، ثم إضافة حاجز حقيقي تحتها للحالات التي لا يكفي فيها الإقناع عبر نافذة الموافقة.
الدرجة الأولى: بوابات الأذونات الخاصة بالوكيل
وكلاء البرمجة تُشحن بالفعل مع نموذج أذونات، وهو أرخص احتواء لديك. Claude Code، على سبيل المثال، لديه أوضاع أذونات مختلفة: default (القراءات تعمل بحرية، وكل شيء آخر يطلب إذناً)، وacceptEdits (تعديلات الملفات وعدد من أوامر نظام الملفات مثل mkdir وmv وcp تُوافَق عليها تلقائياً داخل مجلد العمل)، وplan (بحث فقط، لا تعديلات)، وauto (نموذج مُصنِّف منفصل يراجع كل إجراء ويحجب التصعيد)، وdontAsk (تعمل الأدوات المعتمدة مسبقاً فقط، لـ CI المقيّد)، وbypassPermissions — علم --dangerously-skip-permissions الذي تصرّح عنه الوثائق بصراحة: "استخدم هذا الوضع فقط في بيئات معزولة مثل الحاويات أو الأجهزة الافتراضية أو حاويات التطوير بدون اتصال إنترنت."
هذه الأوضاع حقيقية ومفيدة، لكن افهم ما هي: قرار يُتخذ قبل تشغيل الأمر، استناداً إلى سلسلة الأمر، وفي وضع auto إلى حكم النموذج. هذه طبقة سياسة، لا جدار. يمكنها أن تُخطئ، والأمر الإبداعي يمكن أن يفعل أكثر مما يوحي به اسمه. أعتمد على وضع plan للاستكشاف وdefault لأي شيء يمس البنية التحتية، لكنني لا أعدّ أياً منهما حداً أمنياً للكود الذي لا أثق به. (كتبت عن خطافات Claude Code كحواجز حماية في مكان آخر — التحفظ نفسه: الخطاف سياسة مُطبَّقة في عمليتك، وليس عزلاً.)
الدرجة الثانية: حمايات على مستوى نظام التشغيل لا يستطيع النموذج الجدال معها
هذه هي الدرجة التي يتخطاها معظم المطوّرين الفرديين، وهي ذات أفضل نسبة جهد-أمان. الفكرة: دع نظام التشغيل يُطبّق حدوداً على نظام الملفات والشبكة لكل أمر shell وأبنائه، بصرف النظر عما قرر النموذج تشغيله.
Claude Code يُوفّر هذا كـأداة Bash محمية بصندوق رملي. على macOS يستخدم إطار Seatbelt المدمج — لا حاجة لتثبيت أي شيء. على Linux وWSL2 يستخدم bubblewrap لعزل نظام الملفات مع socat لتوجيه الحركة عبر وكيل. بشكل افتراضي، يمكن للأوامر المحمية الكتابة فقط في مجلد العمل ومجلد الجلسة المؤقت، والوصول إلى الشبكة مرفوض افتراضياً: "لا نطاقات مسموح بها مسبقاً. في المرة الأولى التي يحتاج فيها أمر ما إلى نطاق جديد، يطلب Claude Code الموافقة."
سبب تفوّق هذا على نافذة الأذون: تقول الوثائق بصراحة. "نظام التشغيل يُطبّق حد الصندوق الرملي على العملية الجارية، لذا فهو يُطبَّق بغض النظر عما اختار النموذج تشغيله وحتى لو فعل أمر مسموح به أكثر مما يوحي به اسمه." هذا هو الفرق بين السياسة والتطبيق.
تحفّظان يستحقان القراءة مرتين، كلاهما مأخوذ مباشرة من الوثائق. أولاً، سياسة القراءة الافتراضية لا تزال تسمح بقراءة ملفات بيانات الاعتماد — "هذا الافتراضي لا يزال يسمح بقراءة ملفات بيانات الاعتماد مثل ~/.aws/credentials و~/.ssh/." يجب عليك إضافتها بنفسك إلى denyRead. ثانياً، وكيل الشبكة يُطبّق قائمة السماح باسم المضيف و"لا يُنهي أو يُجري فحص TLS على حركة المرور الصادرة"، لذا فإن إذناً واسعاً مثل github.com يمكن أن يصبح مساراً للتسريب عبر domain fronting. الصندوق الرملي الفعّال، بكلماتهم، "يتطلب عزل نظام الملفات والشبكة معاً" — وسّع أحد الجانبين وقد تُبطل الآخر بصمت.
رأيي: شغّله، ارفض القراءة على مجلدات بيانات الاعتماد، واحتفظ بقائمة النطاقات المسموح بها ضيّقة. إنه مجاني ويوقف أكثر الحوادث شيوعاً. لكنه طبقة تصليب على جهازك الحقيقي، وليس غرفة نظيفة.
الدرجة الثالثة: الحاويات
الحاوية هي الخطوة التالية الواضحة، وللعمل الموثوق لكن الفوضوي فهي كافية. تُشغّل الوكيل داخل Docker، وتُثبّت مجلد المشروع فقط، وتُمرّر متغيرات البيئة التي يحتاجها المشروع فحسب، ونطاق الضرر هو الحاوية. احذف الحاوية، يختفي الضرر.
القيد الصادق هو ما كانت عليه الحاويات دائماً: تُشارك نواة المضيف. الحاوية هي مساحات أسماء وcgroups، وليست جهازاً منفصلاً. للكود الذي كتبته، هذا كافٍ تماماً — الخطر الواقعي هو حادث، وحدود مساحة الاسم تحتوي الحوادث جيداً. للكود غير الموثوق حقاً، استغلال النواة داخل الحاوية يصل إلى المضيف: فئة هجوم حقيقية وإن كانت نادرة. هناك خيار وسط أيضاً — gVisor من Google يعترض استدعاءات syscall للحاوية في نواة فضاء المستخدم قبل أن تصل إلى المضيف، مُقلّصاً سطح الهجوم دون الحاجة لجهاز افتراضي كامل. أقوى من حاوية عادية، وأضعف من افتراضية الأجهزة، مع تكلفة قياسية على الإدخال/الإخراج.
الإعداد العملي للحاوية لوكيل: حاوية تطوير تُشغّل الوكيل كمستخدم غير جذر، مع تثبيت المشروع ولا شيء آخر. تفصيل "غير الجذر" مهم — Claude Code يرفض البدء في وضع bypass-permissions كجذر، وإعداد حاوية التطوير موجود جزئياً لمنحك مستخدماً غير جذر حتى تكون التشغيلات المستقلة آمنة للترك دون مراقبة.
الدرجة الرابعة: microVMs، الجدار الحقيقي
حين تحتاج إلى تشغيل كود لا تثق به، المعيار الذهبي في 2026 هو microVM: جهاز افتراضي حقيقي بنواته الخاصة، يُقلَع في ميلي ثوانٍ، مع نموذج جهاز مُقلَّص إلى ما لا يكاد يُذكر. Firecracker، مدير الأجهزة الافتراضية مفتوح المصدر الذي بنته AWS لـLambda وFargate، هو ما يستخدمه الجميع. فلسفة التصميم بأكملها هي سطح هجوم صغير — يُقصي "الأجهزة غير الضرورية والوظائف الموجهة للضيف لتقليل بصمة الذاكرة وسطح هجوم كل microVM"، ويُقلع نواة مُصغَّرة بلا BIOS ولا نموذج جهاز كامل، ويُشغّل كل ضيف على افتراضية الأجهزة KVM.
الحجة الأمنية هيكلية: كل حمل عمل يحصل على نواته الخاصة على حاجز افتراضية الأجهزة، لذا فإن استغلال النواة داخل microVM واحدة لا يمكنه الوصول إلى المضيف أو VM مجاور. هذا هو الحاجز الذي لا تستطيع الحاوية منحك إياه، لأن الحاوية لا تملك نواتها الخاصة. كانت التكلفة في السابق وقت الإقلاع؛ أوقات الإقلاع ~125ms لـFirecracker أزالت معظمها.
على الأرجح لن ترغب في تشغيل Firecracker بنفسك. لهذا وُجدت الخدمات المُستضافة.
الدرجة الخامسة: خدمات الصندوق الرملي المُستضاف
إذا كانت عبارة "أعطِ الوكيل جهازاً ليس جهازي" تبدو صحيحة، فهذا هو الصندوق الرملي المُستضاف، وقد نضج هذا المجال كثيراً في العام الماضي.
Vercel Sandbox أصبح متاحاً للعموم في 30 يناير 2026 (الإعلان). يُشغّل كل صندوق في microVM من Firecracker بنظام ملفات وشبكة مستقلين، على Amazon Linux 2023، مع أوقات التشغيل node26/node24/node22/python3.13 والوصول إلى sudo. نقطة البيع لمشكلة تسريب الأسرار: الكود في الصندوق الرملي معزول عن بنيتك التحتية، لذا لا يمكنه الوصول إلى متغيرات البيئة أو اتصالات قاعدة البيانات أو موارد السحابة في مشروعك — هذا العزل هو المنتج نفسه، وليس إعداداً تحتاج أن تتذكر تشغيله. تتحكم فيه عبر SDK بـJS أو Python، أو واجهة سطر الأوامر. الاستمرارية (الحفظ التلقائي والاستئناف) مُفعَّلة افتراضياً منذ إصدار GA.
E2B هو الخيار الواضح الآخر، المُوجَّه مباشرةً لتشغيل الكود المُولَّد بالذكاء الاصطناعي. إنه مفتوح المصدر تحت Apache-2.0، ولديه SDKs بـPython وJavaScript، ويستخدم Dockerfile لـبناء قالب microVM (وليس لتشغيل حاوية)، وهو — الجزء الذي يُعجبني — قابل للاستضافة الذاتية عبر Terraform على AWS وGCP وAzure أو أجهزة Linux الخاصة بك. يمكنك البدء على سحابتهم ثم نقله إلى الداخل لاحقاً دون إعادة كتابة.
المقايضة هي المعتادة: الكمون، والتكلفة لكل تشغيل، وجولة الشبكة ذهاباً وإياباً بين وكيلك والكود. لأداة تُشغّل مقتطفات مُقدَّمة من مستخدمين أو مُولَّدة بوكيل، هذا ثمن عادل مقابل حد نواة نظيف وعزل تلقائي للأسرار. لتحرير مستودعك الخاص طوال اليوم، هو مبالغة والاحتكاك سيُضايقك.
ما أُشغّله فعلاً
هنا الإعداد الملموس، مُرتَّب وفق الحالتين اللتين تهمان.
لكودي الخاص، يوماً بيوم: Claude Code على جهازي الحقيقي، في وضع default أو plan، مع تفعيل الصندوق الرملي لنظام التشغيل. الإعداد غير القابل للتفاوض هو رفض القراءة على مجلدات بيانات الاعتماد والإبقاء على قائمة النطاقات المسموح بها قصيرة:
{
"sandbox": {
"enabled": true,
"filesystem": { "denyRead": ["~/.aws", "~/.ssh", "~/.config/gh"] },
"allowedDomains": ["registry.npmjs.org", "github.com"]
}
}
الأسرار تعيش في .env لا يستطيع مجلد عمل الوكيل قراءته، وأُزيل بيانات اعتماد الموفّر من العمليات الفرعية (CLAUDE_CODE_SUBPROCESS_ENV_SCRUB) حتى لا يستطيع curl طائش في سكريبت بناء التقاط مفتاح API الخاص بي من البيئة. هذا تصليب وليس جداراً، وأتعامل معه على هذا الأساس.
لأي شيء لم أكتبه أنا — مستودع أُدقّق فيه، كود مُولَّد، تبعية لا أثق بها، أو وكيل يعمل دون مراقبة طوال الليل — يذهب إلى microVM. عملياً هذا يعني صندوقاً رملياً مُستضافاً (Vercel Sandbox أو E2B) حتى تأتي حدود النواة وعزل الأسرار مجاناً، أو حاوية تطوير تُشغّل الوكيل كغير جذر مع bypassPermissions داخل الصندوق حيث لا شيء ثميناً يمكن إتلافه. القاعدة التي أتبعها: يجب أن تتناسب قوة الحاجز مع مقدار ثقتي بالكود، لا مع مدى ملاءمة الحاجز.
الخطأ الذي ارتكبته في البداية كان التعامل مع هذا باعتباره قراراً واحداً — "هل الصندوق الرملي مُفعَّل أم لا." إنه قراران. الكود الموثوق على جهازي يحتاج إلى حمايات رخيصة توقف الحوادث. الكود غير الموثوق يحتاج إلى جدار لا يمكن إقناع النموذج بتجاوزه. اختر الدرجة التي تتوافق مع الثقة، وارفض قراءة أسرارك في كلتا الحالتين، وستستطيع ترك الشيء يعمل دون مراقبة كل أمر — وهذا كان الهدف كله من توظيف الوكيل.
