تخطَّ إلى المحتوى
kazma.
البحث في كاظمه والتوثيق
EN

الأمان والسلامة

نموذج سلامة كاظمه: ثلاثة مسارات تنفيذ HITL + سجلّ بوابات واحد، ومستويات أدوات بالرفض الافتراضي، وناقل فاشل-مغلق، وCSRF / الوكلاء الموثوقون، وتثبيت IP لـ SSRF، ومهارات HMAC، والتحصين. الثوابت: AGENTS.md §7، §26، §30–§32.

راجع أيضًا: أمان المستندات — استيعاب عدائي، وملفّا تعريف عزل العامل (process، الذي لا يحصر نظام الملفات ولا الشبكة، وملف container الموثَّق لكل مهمة)، وتسييج، ومسح برمجيات خبيثة، وخروج التحليل البعيد، ونموذج إخفاء بيانات لذكاء المستندات.


1. ثلاثة مسارات تنفيذ HITL + سجلّ واحد

Section titled “1. ثلاثة مسارات تنفيذ HITL + سجلّ واحد”

تملك كاظمه ثلاثة مسارات تنفيذ HITL مستقلة. يغطّي كلٌّ منها مسارًا مختلفًا لتشغيل الأدوات. وكسر أيٍّ منها يُنشئ فجوة أدوات خطيرة بلا مُراقِب. حقيقة القرار قطعة رابعة: سجلّ بوابات HITL (kazma-data/hitl_gates.db). وتبقى حقيقة التنفيذ في الـ checkpoint الخاص بـ LangGraph (أو SQLite لخط المعالجة). الأسطح تعرض؛ وهي لا تستنتج أبدًا «مُوافَق عليه» من صف غائب.

flowchart TB
    subgraph "Path A: Graph interrupt (single-agent chat)"
        A1[graph_tool_worker.tool_worker_node] -->|danger + hitl_config| A2[interrupt]
        A2 --> REG[hitl_gates.db CAS]
        REG -->|resume Command| A3[execute with _hitl_approved]
    end
    subgraph "Path B: Swarm bus (/swarm + IDE execute)"
        B1[LocalToolRegistry.execute] --> B2[SafetyMiddleware.check]
        B2 -->|register_gate| REG
        B2 --> B3[bus.request_approval]
        B3 -->|FanOut tri-state| B4[claim + settle]
    end
    subgraph "Path C: Pipeline checkpoints"
        C1[pipeline HITL step] --> C2[CheckpointManager]
        C2 --> REG
        C2 -->|approve_checkpoint| C4[resume_pipeline]
    end
المسارمكان وجودهسطح الموافقة
Aagent/graph_tool_worker.py (موصَّل من graph_builder.py)POST /api/approve/{thread_id} (routes_direct/misc.py) أو بوابة /hitl approve|deny
Bswarm/safety.py + tool_registry.pyأزرار محوّل الناقل (Telegram / Discord / Slack)
Cswarm/checkpoint_manager.pyPOST /api/swarm/tasks/{id}/approve

تتطلب قرارات /hitl في البوابة مشرفًا يملك خيط المحادثة المستهدف. تُحفظ الملكية في دليل الجلسات بصورة دائمة، مستقلة عن خبيئة التسليم لخمس دقائق، فتنجو الموافقات المصرّح بها من انتهاء الخبيئة وإعادة التشغيل. تُرفض الهوية المفقودة أو غير المطابقة قبل قراءة الرسم. ولا يستطيع أمر الموافقة إنشاء ملكية خيطه. عند ضبط KAZMA_GATEWAY_ADMINS تكون قائمته نافذة؛ وإلا تمنح قائمة المستخدمين المسموحين للمنصة صلاحية المشرف. تتيح القائمة الفارغة الدردشة دون منح أي صلاحية مشرف.

يتطلب تفعيل /yolo أو /unrestricted أو /long yolo مشرف بوابة أيضًا. تفحص المعالجات التفويض قبل التفعيل؛ وإضافة أسمائها إلى بوابة أوامر لاحقة تتركها بلا حماية. يبقى فحص الحالة وتعطيل YOLO متاحين دون منح صلاحيات جديدة. وتسري قيود YOLO الإنتاجية على المشرفين أيضًا.

ليست بوابات HITL إضافية:

  • خطافات الأدوات (agent/tool_hooks.py) — لا تستطيع الموافقة تلقائيًا على الخطر، ولا تخطّي الالتزام، ولا استبدال قائمة YAML. الخطاف المكسور يفشل مفتوحًا. KAZMA_TOOL_HOOKS=0.
  • وضع التخطيط — /plan on يزيل أدوات الكتابة/التنفيذ. و/plan go يعيدها؛ والخطر ما يزال يتطلّب موافقة.
  • توضيح/تأكيد الالتزام — ناقل المقاطعة نفسه، لكن بـ kind مختلف (أدناه).

حرِج: hitl_config في كل رسم بياني قابل للاستئناف

Section titled “حرِج: hitl_config في كل رسم بياني قابل للاستئناف”

لا تُفعَّل البوابة إلا عند تمرير hitl_config إلى build_supervisor_graph(). القارئ الحيّ: get_hitl_config(). المهلة الافتراضية في YAML هي 300 ثانية.

موقع البناءHITL؟ملاحظات
KazmaAgent._ensure_graph()✅مسار التشغيل؛ مع checkpointer كي يستطيع interrupt() الاستئناف
إعادة التجميع عند بدء التشغيل في app.py داخل _graph_holder✅SSE SoT — checkpointer + HITL. حذفه = بوابة ويب خاملة
KazmaAgent.get_streaming_graph()⚠️ auto_denyمُخزَّن مؤقتًا بدون checkpointer (متزامن). لا يستطيع مستهلكو نافذة الصوت/الإقلاع استئناف interrupt()، لذا الأدوات الخطيرة ترفض بدل خلق توقّف لا يمكن استئنافه

لا يوجد أي مصنع create_supervisor_graph(). لا تثبّت أرقام أسطر app.py.

H-8: يجب ألا يُنشئ LocalToolRegistry.execute على مسار الويب/المحادثة بوابةً ثانية. تتجاوز ContextVars الخاصة بالرسم (_graph_hitl_gate_ctx / _hitl_approved_ctx) إعادة مطالبة الناقل. التوضيح/التأكيد القادمان من execute() يفشلان مغلقين («شغِّل من المحادثة»).


2. المسار A — بوابة الرسم البياني (محادثة الوكيل الواحد)

Section titled “2. المسار A — بوابة الرسم البياني (محادثة الوكيل الواحد)”

يعيش tool_worker_node في graph_tool_worker.py، وليس في graph_builder.py. عندما يُزوَّد hitl_config:

  1. لا تحصل على بطاقة أيُّ استدعاءٍ سيرفضه المضيف على أي حال: shell_exec ترفضه سياسة صدفة المضيف، أو أمر فارغ أو محرف صدفة خاص؛ أو أداة متصفح أو computer_use لا يستطيع هذا المضيف تشغيلها (safety/call_preflight.call_refusal). يتلقى النموذج خطأً عاديًا ويستمر الدور.
  2. يعمل authorize_effect الخاص بالالتزام أولًا (قد يعيد كتابة الوسائط أو يرفع بطاقة دلالية).
  3. تُختبَر كل أداة عبر requires_approval(name, hitl_config) (safety/hitl.py). الأدوات غير المصنَّفة تبقى خلف البوابة (TOOL_TIERS؛ رفض افتراضي F-04).
  4. تستدعي الأدوات الخطيرة interrupt() الخاص بـ LangGraph — فيُعلَّق الرسم البياني. ويُسجَّل صف في السجلّ (pending).
  5. عند الموافقة، يُحقَن _hitl_approved كي لا يعيد execute() مطالبة الناقل. والسجلّ يطالب ثم يسوّي.
  6. عند الرفض، يُعاد ToolResult مع is_error=True. تنتهي صلاحية الموافقة التي لا يجيب عنها أحد خلال approval_timeout_seconds: لا تُشغَّل الأداة، ويُبلَّغ النموذج بأن البطاقة أُغلقت وأن أحدًا لم يقرّر، وينتهي الدور بإجابة تقول ذلك.

إذا كان hitl_config خاطئ القيمة (falsy)، تتخطى جميع الأدوات هذه البوابة. لهذا يجب أن يمرّره كل موقع بناء قابل للاستئناف.

يرسم الويب من _serverGates / TurnDocument (chat.js). يُبقي close_turn الدور مفتوحًا ما دام صف pending موجودًا. وغياب الصف بوابة معلّقة غير مُسجَّلة (استرجاع)، وليس أبدًا ختم «مُوافَق عليه» مُستنتَجًا.

المصادقة: KAZMA_SECRET مقابل الجلسات المُبهَمة

Section titled “المصادقة: KAZMA_SECRET مقابل الجلسات المُبهَمة”

لا تعتمد أبدًا على KAZMA_SECRET القائم على الكوكيز لأمان تعدد المستخدمين. كوكي kazma-secret=<KAZMA_SECRET> هو السرّ المشترك الخام: سرقته = صلاحيات مدير حتى التدوير؛ لا جدول إبطال؛ ولا هوية لكل مستخدم.

استخدم جلسات مُبهَمة على جانب الخادم (kazma-session مُعرِّف عشوائي ← صف مُجزَّأ + انتهاء صلاحية). وأبقِ KAZMA_SECRET لمصادقة الترويسة بين الآلات. إن لم يُضبط، فقد يُعيد get_kazma_secret() سلسلة فارغة "" وتصبح نقاط نهاية الموافقة غير مُصدَّقة — اضبطه دائمًا خارج localhost.

خلف وكيل عكسي، عنوان النظير ليس اعتمادًا. اضبط KAZMA_TRUSTED_PROXIES. لا تُطِع X-Forwarded-* إلا من تلك العناوين. الوكيل غير المُعلَن يُطلق undeclared_proxy_detected() ويسحب ثقة النظير من العملية (AGENTS.md §26A). يجب أن يستخدم تحديد المعدل / خنق تسجيل الدخول auth.client_address(request)، لا request.client.host.

لا تطبع مخرجات أول تشغيل السر المولّد. يستطيع المشغّل المحلي فتح واجهة loopback؛ واضبط KAZMA_SECRET قويًا في .env الخاص بالتثبيت للحصول على اعتماد ثابت للآلة.

POST /api/approve/{thread_id} (kazma_ui/routes_direct/misc.py الدالة approve_tool) — وليس app.py. يطالب بصف السجلّ، ثم ينفّذ graph.ainvoke(Command(resume=…), config). عدم تطابق الملكية ← 403. لا يقبل WebSocket أي موافقة (يرفض approve_tool).

تبقى الأدوار المعلّقة في مخزن نقاط الحفظ. عند إقلاع المالك الحصري، يحجز boot_sweep() الصفوف التي انقطع حجزها أو استئنافها كأخطاء تنفيذ، مع حفظ القرار وصاحبه. ولا يمس الصفوف المعلّقة أبدًا؛ يجب أن تنجو البطاقة من إعادة التشغيل. لا يظهر الاستئناف الفاشل كموافقة، ولا يعيد فتح البطاقة نفسها. تحجز إيصالات أدوات الرسم الآثار المجهولة للفحص؛ ولا تجيز إعادة المحاولة التلقائية.


3. المسار B — بوابة ناقل السرب (/swarm + IDE)

Section titled “3. المسار B — بوابة ناقل السرب (/swarm + IDE)”

LocalToolRegistry.execute():

  1. يُخرج _hitl_approved.
  2. إن لم يكن مُوافَقًا عليه سلفًا، يستدعي get_safety().
  3. يجب أن يستدعي is_danger_tool(name) الدالة requires_approval() (H-9 — أرضية المستوى، لا قائمة أسماء يمكن أن تفتح البوابة بالإغفال).
  4. await safety.check(...). الرفض ← is_error=True.
  5. فشل-مغلق: أي استثناء في فحص السلامة ← حجب.

swarm/safety.py — الصنف SafetyMiddleware (وليس SafetyGate / SafetyChecker).

الدالةالسلوك
check() (لامتزامنة)الأدوات الخطيرة: NullBus + allow_headless_danger=False ← رفض؛ وإلا bus.request_approval
check_sync()فشل-مغلق. لا يستطيع المسار المتزامن الانتظار على ناقل؛ يحجب إلا مع مخرج headless
is_danger_toolالتصنيف عبر requires_approval / TOOL_TIERS / ALWAYS_HITL_TOOLS

allow_headless_danger=False هو الافتراضي. تضبطه الاختبارات/التطوير على true. لا تفعل ذلك في الإنتاج.

قائمة الخطر: _EXTENDED_DANGER = list(CANONICAL_DANGER_TOOLS) — ليست مصدر حقيقة ثانيًا. أدوات spawn فقط إذا كانت على CANONICAL.

TelegramBusAdapter / DiscordBusAdapter / SlackBusAdapter. مُفرد على مستوى العملية get_message_bus().

توصيل التطبيق (app.py): اجمع كل منصة مُعدَّة. واحدة ← ذلك المحوّل. اثنتان أو أكثر ← FanOutBusAdapter. لا شيء ← NullBusAdapter (خطر فاشل-مغلق).

request_approval الخاص بـ FanOut ثلاثي الحالات (Wave 6 H-12): يُسوّي True؛ وFalse صوت حتى expected_voters أو الموعد النهائي. يجب ألا يقتل رفضُ Discord موافقةَ Telegram. هذا ليس claim_gate الخاص بالويب (أول مطالبة 200 / الثانية 409).

يتخطّى pytest المحوّلات الحقيقية (_skip_real_adapters).

يحلّ handle_callback() الخاص بكل محوّل زرّ المنصّة على الموافقة المشتركة. في Telegram: swarm_approve_<task_id> / swarm_reject_<task_id>؛ وفي Discord مكوّنات (components)؛ وفي Slack التفاعلات.


4. المسار C — نقاط حفظ خط المعالجة

Section titled “4. المسار C — نقاط حفظ خط المعالجة”

راجع تنسيق السرب ← نقاط حفظ خط المعالجة.

  • يُسجّل CheckpointManager.handle_pipeline_checkpoint أيضًا عبر _gate_register_pipeline.
  • رفض تلقائي عند انتهاء المهلة إذا كان checkpoint_timeout > 0.
  • الموافقة / الرفض تسوّيان صف السجلّ. T-2: يجب أن تُنهي المهلة المهمة وتُنفِّذ settle_gate.
  • يُعيد restore_paused_tasks() تسليح المهل بعد إعادة التشغيل.
  • نقاط النهاية: POST /api/swarm/tasks/{id}/approve / /reject.

مقاطعات التوضيح / التأكيد الدلالية (طبقة الالتزام)

Section titled “مقاطعات التوضيح / التأكيد الدلالية (طبقة الالتزام)”

ناقل HITL الموحَّد نفسه الذي يحمل موافقات الأدوات الخطيرة (البوابات A/B/C أعلاه) يحمل أيضًا نوعًا ثانيًا من المقاطعة: بطاقات توضيح/تأكيد دلالية تُنتجها طبقة الالتزام.

هذه ليست موافقات أدوات خطيرة — بل تُطلق عندما يكون قصد الوكيل غامضًا أو حرجًا قبل تعديل دائم، لا لأن الأداة خطيرة. مثال: يقول المستخدم “ذكّرني بالاجتماع” فيستدعي النموذج أداة الجدولة بتوقيت غامض. تُعيد بوابة الالتزام (authorize_effect) قيمة clarify، ويُعلَّق الرسم البياني عبر interrupt() بحمولة تحمل سؤالًا وقائمة خيارات (لكلٍّ منها slots_patch).

نوع المقاطعةمتى تُطلَقkind الحمولة
موافقة أداة خطيرةالأداة على قائمة الخطر (البوابات A/B/C)hitl_approval
توضيح دلاليالقصد غامض (مثلًا: وقت نسبي + حدث قريب)semantic_clarify
تأكيد دلاليفعل حرج يحتاج موافقة صريحةsemantic_confirm

تُعرَض على كل منصّة — الويب (المحادثة + الشريط الجانبي)، وTelegram، وDiscord، وSlack. تعرض كل بطاقة دلالية زرًا واحدًا لكل خيار؛ ويُعيَّن زرّا الموافقة/الرفض الحاليان إلى أفضل خيار / إلغاء (build_resume_value في commitment/resume.py). عند الاستئناف، يُطبَّق slots_patch الخاص بالخيار المختار على وسائط الأداة ويُستكمل الدور؛ والإلغاء نهائي.

خريطة القرار الكاملة (allow / clarify / confirm / deny + إعادة الكتابة عند السماح)، ومحلّلات الأفعال (التذكير، قائمة منع exec، المفاتيح المحمية في الإعداد، قائمة سماح الصادر)، ورموز النطاق، وبوابة تأكيد الروح، والأوضاع، ومفاتيح الإيقاف — موثَّقة في الدليل المخصَّص: طبقة الالتزام (الحلّ قبل الفعل).


5. قوائم الأدوات الخطيرة

Section titled “5. قوائم الأدوات الخطيرة”

يجب أن تبقى CANONICAL + YAML + الإعدادات مجموعة واحدة. و_EXTENDED_DANGER الخاص بالسرب نسخة من CANONICAL. وMCP قائم على الأنماط (غير معروف ← خطر). وTOOL_TIERS هي الأرضية لأي أداة مُسجَّلة.

5.1 المسار A (الرسم البياني) — kazma.yaml safety.hitl.require_approval_for

Section titled “5.1 المسار A (الرسم البياني) — kazma.yaml safety.hitl.require_approval_for”

الافتراضي (kazma.yaml تحت safety.hitl.require_approval_for، ويجب أن يطابق CANONICAL_DANGER_TOOLS): يشمل file_write، وfile_apply_patch، وfile_delete، وshell_exec، وcode_exec، وpython_exec، وcomputer_use، ومُغيّرات git/GitHub، والخزنة، والمُثبّتات، وإرسال/حذف البريد، وrequest_path_access، وx_post، وx_delete_post، وx_schedule_post، وx_cancel_scheduled_post. مُختبَر التكافؤ.

HITL دائم (شروط استخدام X): تتطلّب ALWAYS_HITL_TOOLS (x_post، وx_delete_post، وx_schedule_post، وx_cancel_scheduled_post) موافقةً حتى عندما يتخطى YOLO أو الصلاحيات الدائمة أو تعطيل HITL الأدواتِ الخطيرةِ الأخرى. لا تعرض بطاقتها إلا موافقةً لمرة واحدة (Approve once / Deny؛ ولا “Approve for task” في تطبيقات المحادثة) وتسمّي الفعل العلني (“Publish to X — public, can’t be undone”، Post now). ويرفض مسار الموافقة إجابةَ tool أو yolo عليها برمز 409 one_time_only، وتبقى البطاقة معلّقة. ذلك مسار المحادثة/الوكيل. أما على الويب، فيعامل استوديو X (/x) و/api/scheduled/x نقرةَ المشغّل كالموافقة (يستدعيان publish_x_post / book_x_post / delete_x_post مباشرة — ولا يستخدمان أدوات المحادثة). الـ API الرسمي فقط — راجع ناشر X.

بوابة دائمة لكتابات git (2026-08): تتطلّب git commit وpush وmerge و rebase وreset وcheckout -- وrestore وclean وrm وأشباهها بطاقةَ موافقة على كل مسار تنفيذ — لا يستطيع YOLO الموافقة تلقائيًا على تعديلات المستودع (سوء قراءة القصد يجب أن يكلّف حوارًا، لا commit أبدًا؛ حادثة 2026-08-27). أما git القرائي (status/log/diff) فمعفى. كذلك صارت نوافذ YOLO افتراضيًا ساعة واحدة (كانت 4) — ويتجاوزها KAZMA_YOLO_TTL_SECONDS. راجع سجلّ المهام. تُزال النافذة المنتهية خلال 15 دقيقة سواء أُعيد فتح محادثتها أم لا، ويُعَدّ علمٌ من قبل أن يكون للنوافذ وقت انتهاء منتهيًا: حتى 2026-09-28 كان يُعمَل بمثل هذا العلم إلى الأبد، وقد كانت محادثة واحدة في التثبيت الحي قد تخطّت الموافقات بموجبه منذ يوليو.

الاحتياطي في الكود إن لم يُضبط: DEFAULT_DANGER_TOOLS = ["file_write", "file_delete", "shell_exec", "vault_retrieve", "vault_delete"] (safety/hitl.py:41). تحمي أدوات الخزنة استرجاع/حذف الأسرار.

حارس التضييق: أدوات الخطر الكانونية جزء دائم من القائمة الفعّالة — الأرضية مُفعَّلة افتراضيًا منذ تدقيق 2026-09-16 F-5 — فلا تستطيع الإعدادات/YAML التضييق دونها. يُلغي KAZMA_HITL_CANONICAL_FLOOR=0 ذلك، مع تحذير، ثم يتكرر تحذير الانحراف كل 15 دقيقة يسمّي الأدوات المتروكة.

5.2 المسار B (ناقل السرب) — _EXTENDED_DANGER

Section titled “5.2 المسار B (ناقل السرب) — _EXTENDED_DANGER”

_EXTENDED_DANGER = list(CANONICAL_DANGER_TOOLS) — نسخة مُجسَّدة لأن CANONICAL هي tuple. المحتويات نفسها. إضافة أداة خطيرة تعني CANONICAL وkazma.yaml (اختبارات التكافؤ تقارن المجموعات). أدوات spawn فقط إذا كانت على CANONICAL.

إضافة إلى _SENSITIVE_READS = ["sqlite_query", "file_search"] — مسموحة لكن مُسجَّلة.

mcp/manager.py:71-88 — مطابقة ديناميكية لأنماط الأسماء (أدوات MCP تُكتشَف وقت التشغيل):

  • خطر إذا وُجد أيٌّ من: write, delete, remove, exec, run, shell, bash, command, kill, terminate, install, deploy, upload, download, fetch, request, post, put, patch.
  • آمنة إذا وُجد أيٌّ من: read, list, search, get, info, status, check, describe, query, count, exists, help.
  • غير معروفة خلاف ذلك.

غير المعروف يُعدّ خطرًا افتراضيًا. يتطلّب UnifiedToolExecutor.execute() موافقة للحالتين معًا danger وunknown. لا تُضعِّف هذا أبدًا. الأدوات المحلية: ينتهي requires_approval() عند TOOL_TIERS — الأداة المُسجَّلة غير المصنَّفة تبقى خلف البوابة (F-04). أضف مستوى (read / write / danger) عند تسجيل أداة.


6. التكامل التشفيري (ما وراء HITL)

Section titled “6. التكامل التشفيري (ما وراء HITL)”

6.1 توقيع HMAC للمهارات (Hub)

Section titled “6.1 توقيع HMAC للمهارات (Hub)”

موثَّق في المهارات وMCP والأدوات ← التوقيع التشفيري. الملخّص:

  • يكتب kazma hub sign قيمتي checksum (SHA-256) وsignature (HMAC-SHA256 فوق الـ checksum، بمفتاح KAZMA_SECRET) في skill_manifest.yaml.
  • يتحقّق SkillLoader._load_module_from_file من كليهما عبر hmac.compare_digest (بوقت ثابت) ويرفض تحميل المهارات المُعبَث بها/غير الموقَّعة عند اشتراط التوقيع.

6.2 لا تفويض موقَّعًا بين الوكلاء

Section titled “6.2 لا تفويض موقَّعًا بين الوكلاء”

لا شيء في كاظمه يوقّع العمل المُسلَّم من وكيل إلى آخر أو يشفّره. حزمة تفويض بين الوكلاء (توقيع Ed25519، واتفاقية مفاتيح X25519 + AES-256-GCM) لم توصَل بالمنتج قط: بقيت في archive/ وحُذفت في 2026-07-28. العمل بين عمّال السرب يوزّعه SwarmEngine ‏(kazma_core/swarm/)؛ وما يحميه موجود في هذه الصفحة — بوابة ناقل السرب، ورمز النطاق في طبقة الالتزام، وقوائم الأدوات الخطرة — لا توقيع الرسائل. وتذكر خارطة الطريق أن التفويض الموقَّع ليس في الكود.

نقطة النهاية POST /api/approve/{thread_id} محمية بجلسة / KAZMA_SECRET (secrets.compare_digest). يُحلِّل get_kazma_secret() البيئة ← KAZMA_AUTH_DISABLED ← تخطّي pytest ← security.secret في قاعدة البيانات ← توليد تلقائي. خارج localhost، اضبط KAZMA_SECRET دائمًا. KAZMA_AUTH_DISABLED لجهاز واحد: يرفضه حارس الإقلاع مع ربط بغير loopback أو خلف وكيل مُعلَن (KAZMA_TRUSTED_PROXIES: النفق على الجهاز نفسه يجعل ربط loopback علنيًا)، وما دام مضبوطًا يُجاب الطلب الذي جاء عبر وكيل بالرمز 503.


7. سلوكيات الفشل-المُغلق (الجرد)

Section titled “7. سلوكيات الفشل-المُغلق (الجرد)”
المكوّنسلوك الفشل-المُغلق
SafetyMiddleware.check_syncيحجب الأدوات الخطيرة عند غياب ناقل حقيقي + allow_headless_danger=False.
ToolRegistry.executeأي استثناء في فحص السلامة ← “blocked — SafetyMiddleware unavailable”.
classify_mcp_toolunknown ← يتطلّب موافقة.
SkillLoaderتوقيع مُعبَث به/مفقود ← SkillLoadError، دون تحميل.
Hub write APIغياب KAZMA_SECRET ← رفض جميع عمليات الكتابة.
استلام التفويضتوقيع مفقود/غير صالح ← رفض.
نقطة نهاية موافقة HITLموافقة بين مستخدمين ← 403؛ غياب KAZMA_SECRET ← راجع التحذير أدناه.

⚠ تحذير الإنتاج: إذا كان KAZMA_SECRET غير مضبوط، فقد يُعيد get_kazma_secret() سلسلة فارغة "" وتصبح نقاط نهاية الموافقة غير مُصدَّقة. اضبط KAZMA_SECRET دائمًا لأي نشر غير localhost. (لا يربط kazma serve على 0.0.0.0 إلا عند ضبط KAZMA_SECRET — هذا عن قصد.)


يُعلن kazma-security.yaml عن الوضعية عبر scanning، وdisclosure، وbug_bounty (معطَّل — لا برنامج مدفوع)، وhardening. لا يقرأ أي كود في كاظمه ذلك الملف (فُحص في 2026-09-27): إنه يوثّق برنامج الأمان للبشر، ولا شيء أدناه يعمل بسببه. يعرض قسم hardening فيه 8 فحوصات (secrets_in_logs، وinput_validation، وrbac_enforcement، وtls_required، وdependency_audit، وleast_privilege، وaudit_trail، وconfig_integrity). راجع الإعداد ← إعداد الأمان وSECURITY.md في الجذر. ويُعرِّف kazma-permissions.yaml قوائم السماح/المنع لأدوات MCP القائمة على الأقسام (أقسام ALMuhalab) مع قواعد عابرة للأقسام (require_explicit_approval، وmax_approval_duration_hours: 24، وaudit_all_access).

8.1 تقرير التحصين (security/hardening.py)

Section titled “8.1 تقرير التحصين (security/hardening.py)”

SecurityHardeningRunner تقرير مُشغَّل عند الطلب، لا بوابة. يشغّله GET /api/security/hardening فوق التثبيتة (المجلد الذي يعمل منه كاظمه، لا مجلد العمل الحالي) بوصفه تشخيصًا للقراءة فقط، ويعيد النتائج. يعمل كل فحص في خيط عامل، فيبقى الخادم يجيب. ويستغرق التشغيل الكامل نحو 10 ثوانٍ، معظمها في الاستعلام من OSV. لا يعمل عند بدء التشغيل، ولا تستدعيه أي صفحة بعد. المفتاحان run_on_startup / fail_on_critical في kazma-security.yaml غير مقروءين.

يقيس كل فحص الخاصية التي يحمل اسمها، بالجواب نفسه الذي يستعمله باقي كاظمه:

الفحصما يقرؤهالخطورة
check_no_hardcoded_secretsملفات المنتج في التثبيتة، كما يسردها مستودع git الخاص بها. تُستثنى الاختبارات والوثائق والمجلدات المولَّدة و.env. يحكم security/secret_scan.py على القيم: صيغ الجهات المُصدِرة (كتل المفاتيح الخاصة، وAWS، وGitHub، وSlack، وGoogle، وStripe، وOpenAI، وAnthropic، وTelegram، وJWT)، والقيم التي تبدو عشوائية مُسندة إلى أسماء بيانات اعتماد، وكلمات المرور داخل عناوين URL. لا تُحسب القيم البديلة والقوالب ومؤشرات الخزنة وأسماء متغيرات البيئة. تذكر النتائج الملف والسطر، لا القيمة أبدًا.critical
check_mcp_sandboxingخوادم MCP التي تحتفظ بسرّ كما كُتب لا بمؤشر إلى الخزنة (mcp_servers_store.servers_with_plaintext_secrets)، وحارس مساحة العمل لكل مهمة (KAZMA_MCP_SCOPE_GUARD).high
check_rbac_enforcementمن يصل إلى الواجهة البرمجية: جواب حارس الإقلاع (عنوان الربط، والوكيل المُعلَن، وKAZMA_AUTH_DISABLED / KAZMA_DEV_WS_BYPASS / KAZMA_DEMO_MODE)، إضافةً إلى KAZMA_SECRET مضبوط يدويًا أقصر من 20 حرفًا.high
check_dependency_vulnerabilitiesتنبيهات OSV للإصدارات المثبّتة فعلًا (8.2). فشل OSV يُفشل الفحص، ولا يُعرض أبدًا على أنه نظيف.critical
check_skill_manifest_validityالمهارات المدمجة، مفحوصة كما يحمّلها المُحمِّل: يُحلَّل ملف التعريف، وكل أداة يسمّيها موجودة. ومهارات الوكيل، مفحوصة كما يفحصها التفعيل: ملف SKILL.md صالح، وفحص السلامة الذي يطبّقه التفعيل (تفشل المهارة المعبوث بها؛ وتُعدّ المهارة غير الموقّعة).medium
check_encrypted_communicationsهل تصل حركة المرور من الأجهزة الأخرى عبر TLS. ينجح الفحص إن لم يكن الوصول ممكنًا إلا محليًا. وإن كان كاظمه مكشوفًا (ربط بغير loopback، أو وكيل مُعلَن)، فيجب أن يكون KAZMA_PUBLIC_URL عنوانًا بـ https://.high
check_audit_loggingسجلّ الموافقات (hitl_gates.db): أنه مُفعَّل (KAZMA_GATE_REGISTRY) ومقروء. تذكر الرسالة عدد القرارات التي يحتفظ بها.high
check_permission_escalationالاستدعاءات في شيفرة المنتج التي تشغّل صدفة (shell) أو تقيّم شيفرة: subprocess مع shell= صحيح أو مُقرَّر وقت التشغيل، وos.system، وos.popen، وsubprocess.getoutput، وcreate_subprocess_shell، وeval، وexec. تُحلّ الأسماء المستعارة للاستيراد. ويُطابَق كل استدعاء مع _REVIEWED_SITES، التي تسجّل سبب أمان الموضع. فيها اليوم مدخل واحد: خطافات الأدوات التي يكتبها المشغّل.critical

الفحص الذي لا يمكن تشغيله يُعرض فاشلًا مع سببه، وتعمل بقية الفحوص. حتى 2026-10-02 كانت أربعة فحوص تنجح لمجرد كلمة مفتاحية في أي مكان، وأربعة تفشل بنتائج غير صحيحة (ذاكرة حزم مؤقتة داخل التثبيتة، والحدود الدنيا للمتطلبات تُرسل إلى OSV، واسم ملف تعريف خاطئ). وأُزيلت fix_issues، التي كانت تكتب ملف .env داخل التثبيتة ولم يستدعها شيء.

8.2 مسح التبعيات (security/dependency_scanner.py)

Section titled “8.2 مسح التبعيات (security/dependency_scanner.py)”

تقرأ audit_installed() التوزيعات المثبّتة في البيئة (بأسماء PEP 503، وبلا وسوم الإصدار المحلية). وتسأل واجهة OSV المجمّعة عن كل (name, version) بعينه، متتبّعةً رموز الصفحات، ثم تقرأ ملخّص كل تنبيه والإصدار الذي يصلحه. يُدرج OSV معظم تنبيهات PyPI تحت معرّفين، معرّف GHSA ومعرّف PYSEC، يسمّي كل منهما الآخر اسمًا مستعارًا، فيعدّ التقرير كل تنبيه مرة واحدة. وإذا تعذّر الوصول إلى OSV رُفع DependencyQueryError. ولا يُخزَّن شيء مؤقتًا.

بعض التنبيهات لا إصدار يصلحها، ولا يمكن بلوغها من خلال استعمال كاظمه للحزمة. تسردها REVIEWED_ADVISORIES، ومع كل منها السبب والشيفرة التي ستجعلها قابلة للبلوغ: أربعة تنبيهات لـchromadb تخص خادم Chroma عبر HTTP (يضمّن كاظمه Chroma داخل عمليته ولا يشغّل خادم Chroma)، وتنبيه واحد لـaccelerate في load_checkpoint_in_model (لا يستدعيها كاظمه). يسمّيها التقرير «مُراجَعة»، لا «نظيفة» أبدًا، ويفشل اختبار إن بدأت شيفرة المنتج تستخدم خادم Chroma أو تلك الدالة.

الحدود الدنيا حدودٌ أمنية. يرفع pyproject.toml الحد الأدنى لإصدار الحزمة إلى الإصدار الذي يصلح التنبيه، بما في ذلك حزم يعمل عليها كاظمه دون أن يستوردها بالاسم (urllib3 وanyio وpyasn1، ولكل إضافة aiohttp وoauthlib وtorch وtransformers وsetuptools وvirtualenv). يثبّت kazma update بالإضافة (uv pip install -e)، فالحد الأدنى هو ما يجعله يرقّي تثبيتةً تحمل إصدارًا مصابًا؛ أما ملف القفل وحده فلا يغيّر إلا التثبيتات الجديدة. والنشر عبر git pull لا يثبّت شيئًا، لذا يقارن الخادم عند الإقلاع الحزم المثبّتة بما يعلنه هذا الإصدار (kazma_core/install_requirements.py: ملف pyproject.toml الخاص بالنسخة، لأن البيانات الوصفية المثبّتة تتقادم مع كل سحب). وحين تكون التثبيتة متأخرة، يسجّل تحذيرًا (WARNING) يسمّي كل حزمة، ويطلق تنبيه التشغيل install.requirements_unmet. ويثبّت kazma update --reinstall -y الحدود الدنيا الناقصة؛ وفي تثبيت يشرف عليه الحارس يوقف كاظمه عبر الحارس متى لم تبقَ دورة محادثة جارية، ثم يشغّله من جديد بعدها (تحديث كاظمه ← حين يقول الخادم إن حزمه متأخرة). ويعرض فحص التبعيات في التقرير القائمة نفسها، ويعمل دون OSV.

يشغّل GET /api/security/deps الدالة scan_skill_manifests() على المهارات المثبّتة من المركز. ويذكر لكل مهارة:

  • بيانات اعتماد مكتوبة في ملف التعريف (بالكاشف نفسه secret_scan)؛
  • command: يعمل عبر صدفة مع -c أو /c أو -Command؛
  • --privileged، أو شبكة المضيف، أو sudo، أو chmod 777، أو بتّات set-ID؛
  • تنبيهات OSV للإصدارات المثبّتة من متطلبات requirements.txt الخاصة بالمهارة. ويُسمّى المتطلَّب غير المثبّت.

إذا فشل OSV يكون الجواب {"status": "error"}، لا قائمة فارغة أبدًا.

لا يُجدوَل أيٌّ من المسحين. قسم scanning في kazma-security.yaml (فاصل 24 ساعة، وauto_create_issues) غير مقروء. ما يعمل وفق جدول هو جدول GitHub: طلبات pull الأسبوعية من Dependabot لتحديث ملف القفل uv (.github/dependabot.yml؛ وحتى 2026-10-02 كان يراقب منظومة pip، التي لم تلمس uv.lock قط)، وبوابة bandit العالية (HIGH) في كل تشغيل CI. ويفشل أمر uv export --locked في CI وخطوة SBOM في الإصدار حين لا يعود uv.lock يطابق pyproject.toml.

8.3 تدفّق الإفصاح (security/disclosure.py)

Section titled “8.3 تدفّق الإفصاح (security/disclosure.py)”

يُفرِض SQLite ‏kazma-data/disclosure.db سلسلة الانتقال submitted → acknowledged → investigating → confirmed → patched → closed. يُولِّد publish_advisory() مُعرِّفًا داخليًا KAZMA-ADV-YYYY-… (ليس CVE من MITRE) مع قالب markdown، من حالتَي patched/closed فقط. يُوقِّع encrypt_report() حمولة JSON بتوقيع HMAC-SHA256 بمفتاح KAZMA_DISCLOSURE_KEY.

kazma-security.yaml: نافذة الاستجابة 48 ساعة، والتقييم 7 أيام، وsecurity_txt_url (ملف اتصال RFC 9116 — ليس مفتاح PGP)، والقنوات البريد + الإبلاغ الخاص على GitHub. bug_bounty.enabled: false (لا مكافأة مدفوعة). السياسة الكانونية: SECURITY.md في الجذر والإبلاغ عن الثغرات.

ما يُفرض الأمان وقت التشغيل موجود في الكود، لا في kazma-security.yaml: بوابات الموافقة (§7 من AGENTS.md)، وطبقة الالتزام، والخزنة، وفحوص SSRF/CSRF والسياج — لكلٍّ منها بوابته في tests/. ملف YAML إعلان.


  1. اضبط KAZMA_SECRET دائمًا للنشر غير المحلي. ولِّده عبر openssl rand -hex 32.
  2. شغّل خوادم MCP من نوع stdio داخل بيئة معزولة. ناقل stdio بلا مصادقة؛ يحصل الخادم على الأساسيات المسموح بها مع env الخاص به (تدقيق H-4)، ولا يحصل أبدًا على أسرار كاظمه، ويعمل بصلاحيات عملية كاظمه.
  3. فضِّل MCP من نوع SSE مع مصادقة bearer لأي خادم MCP بعيد.
  4. وقّع جميع المهارات (kazma hub sign) وأبقِ KAZMA_SECRET متّسقًا عبر التحميل — وإلا فشل التحقّق من التوقيع.
  5. أبقِ مسارات تنفيذ HITL الثلاثة + السجلّ مُفعَّلة. لا تمرّر hitl_config=None في رسم بياني إنتاجي قابل للاستئناف. ولا تُنشئ بوابة ويب ثانية من execute().
  6. لا تضبط allow_headless_danger=True في الإنتاج. إنه مخرج الاختبار/التطوير.
  7. اعمل بحساب المستخدم غير الجذري kazma في Docker (يقوم Dockerfile بذلك أصلًا).
  8. اربط على 127.0.0.1 ما لم يكن لديك وكيل عكسي + KAZMA_SECRET جاهزان.
  9. تعدد المشغّلين: اضبط قوائم سماح المنصات + KAZMA_GATEWAY_STRICT_ALLOWLIST=1 (2026-08-19) — افتراضيًا تعمل محوّلات Telegram/Discord/Slack بالسماح-للجميع توافقًا مع التثبيتات أحادية المشغّل؛ والوضع الصارم يفشل مغلقًا عند قائمة سماح فارغة.
  10. اترك KAZMA_HITL_CANONICAL_FLOOR غير مضبوط — الأرضية مُفعَّلة افتراضيًا، والقيمة 0 تسمح بتضييق قائمة موافقات أدوات الخطر دون المجموعة الكانونية.
  11. اضبط KAZMA_TRUSTED_PROXIES عندما تكون خلف nginx/Caddy/Docker. عنوان النظير 127.0.0.1 ليس اعتمادًا.
  12. لا تثبّت الكشط عبر proxy=. تستخدم القفزات المباشرة PinHostAsyncTransport؛ وإحباط النظير الخاص يعمل دائمًا.
  13. إذا وصلت خوادم MCP، فوافق على كل استدعاء أو سمِّ الأداة في KAZMA_MCP_SAFE_ALLOWLIST. الخادم هو من يقدّم اسم الأداة. ما تزال get_file وread_env وget_ssh_key وlist_env_vars تُصنَّف safe، وهذه التسمية لا تتخطى البوابة. read_env هي التي يجب التفكير فيها: غابت env عمدًا عن قائمة سماح shell_exec تحديدًا كي لا تتحوّل موافقة واحدة إلى تفريغ للاعتمادات. KAZMA_PRODUCTION=1 لا يسمح بهذه الأسماء.

الرفض الافتراضي، وCSRF، وSSRF (2026-08-29 / Wave 8)

Section titled “الرفض الافتراضي، وCSRF، وSSRF (2026-08-29 / Wave 8)”

هذه تجلس بجانب HITL، لا داخله.

القاعدةالمكان
الأداة غير المصنَّفة تبقى خلف البوابةrequires_approval() ← TOOL_TIERS (الرفض يفوز)
السماح لثنائي ليس سماحًا لما يشغّله_EXEC_CAPABLE_ARGS الخاص بـ shell_exec (find -exec، وgit -c، …)
إخفاء الأسرار تعاوديsettings.mask_deep() — القوائم وسلاسل JSON أيضًا
كلمة المرور داخل URL سرّتُخفى بالقيمة عند كل مخرج (security/url_credentials.py)، مهما كان اسم الإعداد؛ وعناوين URL للذاكرة الخلفية التي تحوي كلمة مرور تذهب إلى الخزنة
CSRFcsrf.py: طلب غير GET على /api/* مع Origin/Referer غير متطابق ← 403. استخدم request.url.hostname (لا .host في Starlette)
/health/details حسّاسL-1؛ وتبقى /health/live و/health/ready عامّتين
تثبيت IP لـ SSRFيُعيد validate_url عناوين IP عامة؛ وPinHostAsyncTransport عند غياب الوكيل؛ وassert_peer_public بعد كل قفزة
الأخطاءsafe_error / validation_error في API؛ لا تفاصيل داخلية في هياكل 4xx/5xx
مخرجات الأدوات المُسيَّجةالصفحات المجلوبة / البحث / موارد MCP تمرّ عبر fence_untrusted — راجع القسم 10

CI: tests/test_audit_2026_08_29_regressions.py، وtests/test_audit_wave8.py، وtest_every_registered_tool_has_a_tier.


10. سياج التوجيه — ما يوقفه، مُقاسًا

Section titled “10. سياج التوجيه — ما يوقفه، مُقاسًا”

النص غير الموثوق — صفحات الويب المجلوبة، ومقتطفات البحث، ونتائج أدوات MCP وهياكل الموارد — يُغلَّف قبل أن يراه النموذج. نقطة الدخول الإنتاجية هي fence_untrusted(content, *, source, is_error=False) في kazma_core/safety/prompt_fence.py؛ وformat_untrusted_block هي الدالة الداخلية التي يستدعيها.

الثقة تأتي من المستدعي، لا من المحتوى أبدًا. is_error=True هي طريقة المستدعي لقول “هذه السلسلة رسالة فشلي أنا، لا نص طرف ثالث”، وهي الطريقة الوحيدة لتخطّي السياج. هذا ليس تفضيلًا أسلوبيًا: فقد حلّ العلم محل فحص كان يستنشق content.startswith("Error:")، ولأن كل مستدعي يمرّر نصًا يتحكم به المهاجم، كان مهاجم يبدأ حمولته بتلك الأحرف الست يوصلها إلى النموذج بلا سياج. قرار الثقة المُستخرَج من المحتوى هو قرار ثقة يكتبه المهاجم.

وفشل التسييج نفسه يفشل مغلقًا — إذا رمى السياج استثناءً، يحصل المستدعي على نص بديل يسمّي المصدر وعدد الأحرف المحجوبة، لا النص الخام.

نص المستندات تسيّجه منصة المستندات نفسها، باستخدام format_untrusted_block (بالمصادر document وdocument_attachment و document_knowledge)؛ انظر أمان المستندات.

نجاح الهجوماتُّخذ إجراء وفق الحمولة
بلا دفاع18.1%24.1%
تسليط الضوء (محدِّد من 4 أحرف، من الأدبيات)11.6%18.6%
سياج كاظمه10.4%14.8%

996 تشغيلًا لكل شرط على AgentDojo، معيار عام لم تكتبه كاظمه، وكل شرط قيس أربع مرات. يتفوّق السياج على انعدام الدفاع بفارق حاسم (p < 0.001) ولا يمكن تمييزه عن محدِّد من أربعة أحرف (p = 0.39).

كلا النصفين من ذلك مهم. تسييج مخرجات الأدوات غير الموثوقة يعمل. وهو أيضًا ليس حيث تكمن ميزة كاظمه، والصفحة أدناه تقول ذلك بدل أن تتركك تكتشفه بنفسك.

  • حقن التوجيه: الأرقام — القياس الكامل، والحمولات التي ما زالت تصيب، وإعادة الإنتاج التي يمكنك تشغيلها مجانًا بلا مفتاح API.
  • نموذج التهديد — ما يوقفه كل حدّ، وبصراحة، ما لا يوقفه. الموافقة رضا، لا احتواء.
  • الفجوات المعروفة — نقاط ضعف مفتوحة، مؤرَّخة. بينها واحدة تمسّ افتراضات هذه الصفحة نفسها: اسم الأداة الذي يقدّمه خادم MCP نفسه ما يزال يصنّف read_env آمنة، وتلك التسمية ليست موافقة. يعمل الاستدعاء عندما توافق عليه، أو عندما يكون ذلك الاسم على KAZMA_MCP_SAFE_ALLOWLIST. وضع الإنتاج لا يغلقها.

يقلّل السياج نجاح الهجوم. لا يلغيه، ولن يكون أي رقم صادق هنا 0% أبدًا.


  • اسم الصنف: سلامة السرب هي SafetyMiddleware، وليست SafetyGate/SafetyChecker.
  • نقطة نهاية الموافقة: approve_tool في routes_direct/misc.py، وليست في app.py.
  • لا تثبّت أرقام الأسطر. tool_worker_node هو graph_tool_worker.py؛ وSSE SoT هي إعادة تجميع app.py، لا get_streaming_graph() (ذلك المسار بلا checkpointer مع auto_deny).
  • FanOut، لا Telegram فقط. منصات متعددة ← FanOutBusAdapter ثلاثي الحالات.
  • _EXTENDED_DANGER هي CANONICAL، لا قائمة خاصة أطول. ويبقى classify_mcp_tool الخاص بـ MCP قائمًا على الأنماط (غير معروف ← خطر).
  • “مستويات الثقة” غير موجودة كميزة منتج — راية الـHub المنطقية certified، والإعداد trust: trusted لخادم MCP الذي يتخطى بطاقة الموافقة لأدواته (ويُرفض في الإنتاج ما لم يكن KAZMA_MCP_TRUSTED_IN_PROD=1).
  • MCP من نوع stdio بلا مصادقة. اعزل وفق ذلك.
  • تدقيق الربط: AUDIT_DEEP_2026-09-01_EXEC.md.