الانتقال إلى المحتوى الرئيسي
بعض استدعاءات الأدوات بالغة العواقب للسماح بها عمياءً ومفيدة جداً لحظرها صراحةً — كتابة في قاعدة بيانات إنتاج، حوالة مالية، *.delete على بيانات حقيقية. لتلك تريد شخصاً في الحلقة: علّق الاستدعاء، دع إنساناً ينظر، ثم امضِ فقط عند نعم. ذلك بالضبط ما يفعله حكم pending_approval. تغطي هذه الصفحة تدفّق موافقة الوكيل بالإنسان في الحلقة من البداية إلى النهاية: كيف يبرز استدعاء مُعلَّق، وكيف يحلّه مراجِع من وحدة التحكم أو webhook، وكيف يعيد الوكيل تقديم الاستدعاء المعتمد. لمكان جلوس الحكم في قواعد القواعد، انظر قواعد جدار الحماية؛ ولنموذج السياسة حوله، انظر نظرة عامة على جدار الحماية.

1. كيف يبدو استدعاء مُعلَّق

عندما تُحَل قاعدة إلى pending_approval، يـضع المحرك سجل موافقة في الطابور والاستدعاء لا يصل إلى الأداة. يعيد الترحيل HTTP 400 بـ error.code firewall_approval_pending؛ ومعرّف الموافقة الذي سيستطلعه الوكيل محمول في error.message القابل للقراءة:
{
  "error": {
    "code": "firewall_approval_pending",
    "message": "tool \"db.write\" held for approval (…) — resolve approval 507f1f77bcf86cd799439011 and retry with header X-OrcaRouter-Firewall-Approval"
  }
}
الـ error.metadata المهيكل (عند وجوده) يحمل تفصيل سبب الحكم — reason_code، factors، risk_score — وليس معرّف الموافقة. حلّل المعرّف من الرسالة، أو احصل عليه من مساعد SDK أدناه. التعليق فوري — لا يوجد استطلاع طويل مضمّن يحجب طلبك. يستعيد الوكيل المعرّف، ويُركَن الاستدعاء على جانب الخادم في حالة pending، ويحدث الحل خارج النطاق.
استدعاء مُعلَّق يُسجَّل كحدث جدار حماية بحكم pending_approval، فهو قابل للتصفية في سجل الأحداث جنباً إلى جنب مع أحداث deny — يمكنك دائماً رؤية ما عُلِّق و، عبر سجل الموافقة، ما حُلَّ.

2. مثال ملموس واحد

ألّف قاعدة تعلّق أي كتابة إلى اتصال إنتاج لإنسان:
{
  "label": "hold prod db writes",
  "tool_name_glob": "db.write",
  "verdict": "pending_approval",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.connection\",\"op\":\"eq\",\"value\":\"prod\"}]}"
}
الآن دورة الحياة:
1

الوكيل يستدعي الأداة

يصدر الوكيل db.write مقابل prod. تطابق القاعدة، يعلّق المحرك الاستدعاء، ويعيد الترحيل 400 firewall_approval_pending بـ approval_id.
2

إنسان (أو نظامك) يراجع

يحلّ مراجِع الموافقة — في وحدة التحكم أو عبر استدعاء webhook موقَّع (انظر §3).
3

الوكيل يستطلع حتى الحل

يستطلع الوكيل معرّف الموافقة حتى لا تعود حالته pending (انظر §4).
4

الوكيل يعيد التقديم بترويسة الموافقة

عند approved، يعيد الوكيل إصدار نفس الاستدعاء بالضبط مرة واحدة، حاملاً ترويسة X-OrcaRouter-Firewall-Approval أحادية الاستخدام. يطالب المحرك بالموافقة ويدع ذلك الاستدعاء الواحد يمر.

3. حل موافقة

هناك طريقتان لتحويل موافقة pending إلى approved أو rejected. كلاهما يتشارك ضمان أول قرار يفوز — أول حل يهبط يُطبَّق ذرّياً، وأي حل لاحق (أو مكرَّر) هو عملية عديمة الأثر تكرارياً تعيد 200.
تبويب Approvals يسرد التعليقات المُعلَّقة الأقدم أولاً، كل منها باسم الأداة وسطر “عُلِّق لأن…” يسمّي السياسة وعبارة القاعدة التي أُطلقت. (وسائط الاستدعاء الخام لا تُخزَّن على سجل الموافقة — فقط اسم الأداة، والأصل، وتجزئة وسائط — فيقرّر المراجِع من الأداة بالإضافة إلى العبارة المطابقة.) يحلّ مراجِع واحدة بـ:
PATCH /api/workspace/firewall/approvals/:id
{ "decision": "approved", "reason": "verified change ticket #4821" }
decision يجب أن يكون approved أو rejected. هذا المسار UserAuth (جلسة وحدة تحكم المراجِع) ومحكوم بـ Developer+ — هوية مراجِعك هي التفويض، فلا سر مشترك متورّط. تُكتَب الحلول إلى سجل تدقيق مساحة العمل.
لربط الموافقات بنظام خارجي (موافقة Slack، تدفّق عمل تذاكر)، اضبط سر webhook موافقة لمساحة العمل، ثم أرسل POST بالقرار عائداً:
POST /api/v1/firewall/approvals/:id/callback
{ "decision": "approved", "reason": "auto-approved by change-control bot" }
يُصادَق على الاستدعاء بـ HMAC-SHA256: اضبط ترويسة X-Orca-Signature: sha256=<hex> على HMAC لـ <approval_id>\n<raw_body> بمفتاح سر webhook موافقة مساحة عملك. المعرّف جزء من المادة الموقَّعة، فتوقيع ملتقَط لا يمكن إعادة تشغيله مقابل موافقة مختلفة. بدون سر مضبوط، يُرفض الحل المدفوع بالاستدعاء — احلل عبر PATCH في وحدة التحكم بدلاً من ذلك.
ضبط مسار رفض webhook موافقة هو الافتراضي الآمن للتشغيلات غير المراقَبة: إذا لم يحلّ أي إنسان تعليقاً، يبقى الاستدعاء مركوناً ببساطة ويستمر الوكيل في الاستطلاع. استدعاء مُعلَّق لا يصبح أبداً allow صامتاً.

4. استطلع، ثم أعد التقديم

جانب الوكيل حلقة استطلاع متبوعة بإعادة تقديم واحدة. استطلع حالة الموافقة برمز ضمن نطاق بوابة جدار الحماية:
GET /api/v1/firewall/approvals/:id
هذا المسار يتطلب رمزاً بـ نطاق بوابة جدار الحماية (نفس مفتاح البوابة المخصص المستخدم لـ /evaluate وبوابة MCP)؛ مفتاح ترحيل عادي يحصل على 403. يعيد وثيقة الموافقة — انتظر حتى تكون state بـ approved أو rejected بدلاً من pending. معرّف عبر مساحات عمل أو مجهول يعيد 404، دون الكشف أبداً لمستأجر آخر أنه موجود. أعد التقديم بمجرد أن تكون الحالة approved: أعد إصدار نفس استدعاء الأداة، حاملاً معرّف الموافقة في ترويسة أحادية الاستخدام:
X-OrcaRouter-Firewall-Approval: 507f1f77bcf86cd799439011
يـطالب المحرك ذرّياً بالموافقة — أحادية الاستخدام. أول إعادة تقديم تحملها تُسمَح تلك المرة الواحدة؛ إعادة تشغيل نفس الترويسة تجد الموافقة مستهلَكة بالفعل وتُـعلَّق مجدداً، لا تُسمَح. موافقة rejected لا يمكن المطالبة بها أبداً، فيجب أن يعامل الوكيل الرفض كـ deny نهائي ويختار مساراً آخر.
مساعد HITL في OrcaRouter MCP SDK يجري حلقة الاستطلاع-ثم-إعادة-التقديم لك: عندما يعيد evaluate قيمة pending_approval، يستطلع GET /api/v1/firewall/approvals/:id ويعيد التقديم بترويسة الموافقة عند الموافقة — أنت فقط تؤلّف القاعدة وتوظّف المراجِع.

5. الحالات والأدوار في لمحة

الحالةالمعنىإجراء الوكيل
pendingمُعلَّق، بانتظار قراراستمر في الاستطلاع
approvedقال المراجِع نعمأعد التقديم مرة واحدة بالترويسة
rejectedقال المراجِع لاعامله كـ deny
الإجراءالمسارالمصادقة · الدور
سرد الطابورGET /api/workspace/firewall/approvalsUserAuth · Developer+
الحلPATCH /api/workspace/firewall/approvals/:idUserAuth · Developer+
استدعاء WebhookPOST /api/v1/firewall/approvals/:id/callbackموقَّع بـ HMAC
استطلاع الحالةGET /api/v1/firewall/approvals/:idرمز البوابة

6. أين تقع الموافقات

حكم pending_approval أحد أحكام جدار الحماية — يتركّب مع كل شيء آخر في سياسة. تفاعلان يستحقان المعرفة:
  • حجر المهارة الصحي يتصاعد إلى تعليق. إذا كان استدعاء أداة مُعلَّق مملوكاً لـمهارة في الحجر الصحي، أي شيء دون deny يتصاعد إلى pending_approval تلقائياً — الحجر الصحي والموافقات هما نفس بوابة المراجعة من اتجاهين.
  • وضع الظل يسطّحه. في وضع الظل يُخفَّض حكم pending_approval إلى audit ويُسجَّل كـ [shadow] would …، فيمكنك قياس كم مرة كان تعليق سيُطلق قبل أن يبدأ حكم حركة المرور الحقيقية.
هذا هو التحكم الصحيح لـاستدعاءات الأدوات الخطرة والوكالة المفرطة — الحالات التي يتفوّق فيها حكم “اسأل إنساناً” على كل من allow وdeny.

أين تذهب بعد ذلك

الأحكام

أحكام جدار الحماية الستة جميعاً والحكم الافتراضي.

مفاتيح البوابة

اسكك رمز بوابة جدار الحماية المستخدم لاستطلاع الموافقات.

وضع الظل

قِس تعليقاً قبل أن يحكم حركة المرور الحقيقية.

مرجع القواعد

ألّف القاعدة التي تنتج حكم pending_approval.