شاهد فيديو الدرس: تأمين وكلاء الذكاء الاصطناعي بالإيصالات المشفرة
(فيديو الدرس والصورة المصغرة ستضاف من قبل فريق محتوى مايكروسوفت بعد الدمج، بما يتماشى مع نمط الدرس 14 / 15.)
يغطي هذا الدرس:
بعد إكمال هذا الدرس، ستتمكن من:
تخيل أنك نشرت وكيلاً للذكاء الاصطناعي لشركة Contoso Travel. يقرأ الوكيل طلبات العملاء، ويتصل بواجهة برمجة تطبيقات رحلات جوية للبحث عن الخيارات، ويحجز مقاعد نيابة عن العميل. في الربع الأخير، عالج الوكيل 50,000 حجز.
اليوم وصل مدقق. يسأل سؤالاً بسيطاً: “أرني ماذا فعل وكيلك.”
تسلم ملفات السجل الخاصة بك. ينظر المدقق إليها ويسأل السؤال الأصعب: “كيف أعلم أن هذه السجلات لم تُحرر؟”
هذه هي مشكلة سجل التدقيق. تعتمد معظم عمليات نشر الوكلاء اليوم على:
لا يمكن لأي منها الإجابة على سؤال المدقق بدون حاجة إلى أن يثق المدقق بشخص ما (أنت، موفر السحابة، بائع قاعدة البيانات). للاستخدام الداخلي، يكون ذلك مقبولاً غالبًا. للأعباء الخاضعة للتنظيم (المالية، الرعاية الصحية، أي شيء خاضع لقانون EU AI)، فهو غير مقبول.
تحل الإيصالات المشفرة هذه المشكلة بجعل كل فعل وكيل قابلًا للتحقق بشكل مستقل. لا يحتاج المدقق إلى الوثوق بك. يحتاج فقط إلى مفتاحك العام والإيصال نفسه.
الإيصال هو كائن JSON يسجل ما فعله الوكيل، موقعًا بتوقيع رقمي.
flowchart LR
A[الوكيل يستدعي أداة] --> B[بناء حمولة الإيصال]
B --> C[تنظيم JSON وفق RFC 8785]
C --> D[تجزئة SHA-256]
D --> E[توقيع Ed25519]
E --> F[الإيصال مع التوقيع]
F --> G[المدقق يتحقق خارجيًا]
G --> H{هل التوقيع صالح؟}
H -- yes --> I[إثبات مقاوم للتلاعب]
H -- no --> J[تم رفض الإيصال]
إيصال بسيط يبدو هكذا:
{
"type": "agent.tool_call.v1",
"agent_id": "contoso-travel-bot",
"tool_name": "lookup_flights",
"tool_args_hash": "sha256:a3f9c1...",
"result_hash": "sha256:7b2e1d...",
"policy_id": "contoso-travel-policy-v3",
"timestamp": "2026-04-25T14:30:00Z",
"sequence": 47,
"previous_receipt_hash": "sha256:9d4e6a...",
"signature": {
"alg": "EdDSA",
"sig": "c5af83...",
"public_key": "8f3b2c..."
}
}
ثلاث خصائص تقوم بالعمل:
التوقيع. يتم توقيع الإيصال بواسطة بوابة الوكيل باستخدام مفتاح خاص Ed25519. يمكن لأي شخص لديه المفتاح العام المقابل التحقق من التوقيع دون الاتصال. أي تلاعب بأي حقل يبطل التوقيع.
الترميز القياسي. قبل التوقيع، يتم تسلسل الإيصال باستخدام مخطط التوحيد القياسي لـ JSON (JCS، RFC 8785). هذا يضمن أن تنفيذين ينتجان نفس الإيصال المنطقي ينتجان إخراجًا مطابقًا بالبتات. بدون التوحيد القياسي، تقوم أدوات التسلسل المختلفة بإنتاج توقيعات مختلفة لنفس المحتوى.
ربط التجزئة. يربط الحقل previous_receipt_hash كل إيصال بالإيصال الذي قبله. إزالة أو إعادة ترتيب إيصال يكسر كل الإيصالات التي جاءت بعده. يصبح التلاعب مرئيًا على مستوى السلسلة حتى لو تم تجاوز التوقيعات الفردية.
تزود هذه الخصائص معًا ثلاث ضمانات:
لست بحاجة إلى مكتبة خاصة لإنتاج إيصال. البُنى التشفيرية متوفرة على نطاق واسع والمنطق يتألف من عدة عشرات الأسطر في بايثون.
تمارين التطبيق العملي في code_samples/18-signed-receipts.ipynb تشرح التدفق الكامل. النسخة الملخصة:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 JSON الرسمي
def b64url_nopad(data: bytes) -> str:
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
def sha256_canonical(obj) -> str:
"""SHA-256 of a Python object's JCS-canonical JSON form."""
return f"sha256:{hashlib.sha256(canonicalize(obj)).hexdigest()}"
# توليد أو تحميل مفتاح توقيع (في الإنتاج، خزنه في خزنة مفاتيح)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# بناء حمولة الإيصال (لا توقيع حتى الآن)
tool_args = {"origin": "SYD", "destination": "LAX"}
tool_result = [{"flight": "QF11", "price": 1850, "stops": 0}]
payload = {
"type": "agent.tool_call.v1",
"agent_id": "contoso-travel-bot",
"tool_name": "lookup_flights",
"tool_args_hash": sha256_canonical(tool_args),
"result_hash": sha256_canonical(tool_result),
"policy_id": "contoso-travel-policy-v3",
"timestamp": "2026-04-25T14:30:00Z",
"sequence": 0,
"previous_receipt_hash": None,
}
# جَعْلها رسمية، تجزئتها، التوقيع.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# إرفاق كائن توقيع منظم.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
هذا هو خط أنابيب التوقيع الكامل. تشرح التمارين في الدفتر كل خطوة.
التحقق هو العملية العكسية:
import base64
import hashlib
from nacl import signing
from nacl.exceptions import BadSignatureError
from jcs import canonicalize
def b64url_decode(s: str) -> bytes:
padding = "=" * ((4 - len(s) % 4) % 4)
return base64.urlsafe_b64decode(s + padding)
def verify_receipt(receipt: dict) -> bool:
# التوقيع هو كائن منظم: {"alg"، "sig"، "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# إعادة بناء الحمولة التي تم توقيعها فعليًا (كل شيء ما عدا التوقيع).
payload = {k: v for k, v in receipt.items() if k != "signature"}
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
try:
verify_key = signing.VerifyKey(b64url_decode(sig_obj["public_key"]))
verify_key.verify(message_hash, b64url_decode(sig_obj["sig"]))
return True
except BadSignatureError:
return False
هذه الدالة تأخذ إيصالًا وتُرجع True إذا كان التوقيع صالحًا، و False خلاف ذلك. لا حاجة لاتصال شبكة، لا اعتماد على خدمة، لا ثقة مطلوبة بأي طرف ثالث.
لرؤية اكتشاف التلاعب عمليًا، يشرح الدفتر:
tool_args_hash.هذا هو العرض العملي لإثبات أن الإيصالات صعبة التلاعب: أي تعديل، مهما كان صغيرًا، يكسر التوقيع.
إيصال موقع واحد يحمي فعلًا واحدًا. سلسلة من الإيصالات تحمي تسلسلًا.
flowchart LR
R0[الإيصال 0<br/>الأصل] --> R1[الإيصال 1]
R1 --> R2[الإيصال 2]
R2 --> R3[الإيصال 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
يسجل كل إيصال تجزئة الإيصال الذي قبله. لإزالة الإيصال رقم 2 بدون اكتشاف، يحتاج المهاجم إلى إما:
previous_receipt_hash في الإيصال 3 (يكسر توقيع الإيصال 3)، أوإذا كان المفتاح الخاص محفوظًا في خزنة مفاتيح مادية وقمت بنشر المفتاح العام مع كل إيصال، فإن أي هجوم منهما غير ممكن بدون اكتشاف.
يشرح الدفتر:
previous_receipt_hash لكل إيصال يطابق تجزئة الإيصال السابق الفعلية.هكذا تنتج سجل تدقيق يمكن لمدقق خارجي التحقق منه دون الحاجة إلى الوثوق بك.
هذا هو القسم الأهم في هذا الدرس. الإيصالات قوية لكن قوتها محدودة.
تثبت الإيصالات ثلاثة أمور:
الإيصالات لا تثبت:
policy_id تم تقييمها بالفعل، أو أنها كانت سترخص هذا الفعل إذا تم التحقق منها. الإيصال يسجل ما تم الادعاء به، لا ما تم تطبيقه.هذه الحدود مهمة لسببين:
خطأ شائع هو افتراض أن “لدينا إيصالات” يعني “نحن محكومون.” هذا غير صحيح. الإيصالات هي الأساس. الحوكمة هي النظام الذي تبنيه عليه.
نقطة 3 أعلاه تستحق قسمًا خاصًا: إيصال الفعل يقول “وقع هذا المفتاح هذا المحتوى”، لا يقول أبدًا “أذن إنسان بهذا.” للأفعال عالية المخاطر (رد الأموال، الحذف، التحويلات المالية)، تتطلب أطر الحوكمة بشكل متزايد ذلك البيان المفقود تمامًا، ويمكن إنتاجه باستخدام نفس البُنى التي بنيتها في هذا الدرس.
الدفتر التالي code_samples/human-authorization-receipts.ipynb يضيف نوعًا ثانيًا من الإيصالات، human.approval.v1، بنفس شكل المغلف كما في إيصالات الدرس (حمولة مكتوبة بتوقيع Ed25519 على SHA-256 القياسي، مع كائن signature خارج البايتات الموقعة). يوقع الموافق المسجل الفعل الكامل القياسي وهضمته قبل التنفيذ؛ يحمل إيصال فعل الوكيل نفس هضم الفعل و parent_approval_ref، وهو receipt_hash للموافقة، نفس قاعدة previous_receipt_hash في السلسلة التي بنيتها أعلاه. تعمل دالة verify_chain على التحقق من القطعتين تحت سجلات مفاتيح مستقلة (مفاتيح الموافق مقابل مفاتيح الوكيل)، لذا المسار البرمجي مشترك لكن السلطات لا تتقاطع أبدًا.
الخاصية التي يشتريها هذا، بصياغة دقيقة: وافق الإنسان على هذا الفعل بالذات، ونفذ الوكيل هذا الفعل الموافق عليه بالضبط. التهديدات التي يناقشها الدفتر هي ما يجعل الخاصية حقيقية وليست مجرد ادعاء:
يرفض كل فشل لسبب مميز، بحيث يمكن للمدقق عند قراءة الرفض معرفة ما إذا كانت السلطة قد أصبحت قديمة أو تغيّر الفعل المنفذ. القاعدة التي يعلمها الدفتر: الموافقة الموقعة ليست سلطة بحد ذاتها. السلطة موجودة فقط إذا بقي الاثنان (الإيصالان) مربوطين بنفس الفعل القياسي وقت التنفيذ. مسار التوقيع المشترك في نفس مسودة الإنترنت التي يتبعها هذا الدرس (draft-farley-acta-signed-receipts) هو شكل المسار القياسي لهذا النمط.
كود بايثون في هذا الدرس بسيط عمدًا لكي تقرأ كل سطر وتفهم تمامًا ما يحدث. في الإنتاج، لديك خياران:
ابنِ مباشرة على البُنى التشفيرية الأساسية. الخمسون سطرًا التي شاهدتها أعلاه تكفي للعديد من الاستخدامات. مكتبة PyNaCl (Ed25519) وحزمة jcs (JSON القياسي) مكتبات مدعومة ومراجعة جيدًا.
استخدم مكتبة للإيصالات في الإنتاج. تنفذ عدة مشاريع مفتوحة المصدر نفس النمط مع ميزات إضافية (تدوير المفاتيح، التحقق المجمّع، توزيع مجموعة JWK، تكامل مع محركات السياسات):
draft-farley-acta-signed-receipts، المراجعة 02) وهي حالياً في مسار المعايير، مع مجموعة توافق مشتركة (agent-governance-testvectors) تتحقق من صحة التطبيقات المستقلة مقابل إخراج قياسي مطابق بالبتات.protect-mcp (npm) و @veritasacta/verify (npm) توفر تنفيذ Node لتوقيع الإيصالات والتحقق دون اتصال، مصممة لتغليف أي خادم MCP بسجل تدقيق صعب التلاعب، بما في ذلك تدفق الاحتجاز للموافقة في النشاط المعلق (مدعوم بـ WebAuthn في تدفق سطح المكتب)، وهو نفس نمط موافقة الإيصال كما في الدفتر البشري أعلاه.pip install nobulex) يقدم نفس نمط التوقيع Ed25519 + JCS في بايثون مع تكاملات LangChain و CrewAI، بما في ذلك متجهات اختبار التحقق المتقاطعة المنشورة وخريطة الامتثال المساهمة عبر OWASP PR #2210.القرار بين كتابة كودك الخاص واستخدام مكتبة يعكس القرار بين كتابة مكتبة JWT خاصة بك واستخدام مكتبة مختبرة: كلاهما معقول؛ توفر المكتبة الوقت وتقلل من مساحة التدقيق؛ الطريقة من الصفر تجبرك على فهم كل عنصر أساسي. هذا الدرس يعلم الطريق من الصفر لكي تحصل على الأساس لأي خيار.
اختبر فهمك قبل الانتقال إلى تمرين الممارسة.
1. يقوم توقيع الإيصال بمفتاح Ed25519 الخاص بالوكيل. لدى المدقق المفتاح العام فقط. هل يمكن للمدقق التحقق من الإيصال دون اتصال؟
2. عدل مهاجم حقل policy_id في إيصال ليُدعي أنه خضع لسياسة أكثر تساهلًا. كان التوقيع على الحمولة الأصلية. ماذا يحدث أثناء التحقق؟
3. لماذا يتضمن الإيصال tool_args_hash و result_hash بدلاً من الوسائط والنتيجة الأصلية؟
4. يربط حقل previous_receipt_hash كل إيصال بالذي سبقه. إذا حذف مهاجم إيصالًا من منتصف سلسلة بصمت، ماذا يصبح غير صالح؟
5. تحقق الإيصال بشكل نظيف. هل يثبت ذلك صحة الإجراء أو صوابه أو توافقه مع السياسة؟
افتح code_samples/18-signed-receipts.ipynb وأكمل الأقسام الأربعة كلها:
تحدي امتداد 1: قم بتوسيع مخطط الإيصال بحقل إضافي تختاره (مثلاً: معرف طلب للتتبع)، حدّث منطق التوقيع المعياري ليشمله، وتأكد من أن الإيصال لا يزال يمر بالتحقق بشكل صحيح. ثم عدّل الحقل بعد التوقيع وتأكد من فشل التحقق. هذا يجبرك على فهم كيف يساهم كل بايت من الترميز المعياري في التوقيع.
تحدي امتداد 2: قم بتجزئة SHA-256 لإثنين من إيصالاتك معًا (ربط البايتات المعيارية بترتيب حتمي) وادمج الرقم المختصر الناتج كحقل جديد على إيصال ثالث قبل توقيعه. تحقق من أن الثلاثة إيصالات لا تزال تمر بالتحقق. لقد أنشأت لتوك دليل دمج خطوة واحدة: يمكن لأي شخص يحمل الإيصال الثالث إثبات وجود الإثنين الأولين وقت توقيعه، دون الحاجة لكشف محتواهما. هذا هو النمط المستخدم في إيصالات الكشف الانتقائي على نطاق واسع (ارتباطات ميركل، RFC 6962).
تمنح الإيصالات المشفرة لوكلاء الذكاء الاصطناعي مسار تدقيق يكون:
ليست بديلاً عن التحقق من المدخلات، أو فرض السياسات، أو بنية الهوية. هي أساس لتلك الطبقات. عند نشر الوكلاء في بيئات محكومة، أو تدفقات عمل متعددة المنظمات، أو أي وضع حيث لا يمكن افتراض ثقة المدقق المستقبلي، الإيصالات هي وسيلة جعل مسار التدقيق نزيهًا.
أهم نقطة: تثبت الإيصالات من قال ماذا ومتى. لا تثبت أن ما قيل كان صحيحًا أو صائبًا. احتفظ بهذا التمييز بإحكام. هو الفرق بين نظام مصدر نزيه وآخر مضلل.
عندما تكون مستعدًا للتخرج من هذا الدرس إلى نشر وكلاء موقعين بإيصالات في بيئة حقيقية:
https://your-org.example.com/.well-known/agent-keys.json.انضم إلى Microsoft Foundry Discord للقاء متعلمين آخرين، حضور ساعات المكتب، والحصول على إجابات لأسئلتك عن وكلاء الذكاء الاصطناعي.
يغطي هذا الدرس توقيع إيصال واحد وتسلسل السلاسل المترابطة. نفس البدايات تترتب في عدة أنماط متقدمة قد تواجهها مع تطور وضع الحوكمة لديك:
authorization_*) ونصف ما بعد التنفيذ (result_*) مع توقيعات مستقلة، مفيد عندما يتم إصدار قرار التفويض والنتيجة الملاحظة من جهات مختلفة أو في أوقات مختلفة. هذا يضاف فوق تنسيق الإيصال الذي تم تدريسه في هذا الدرس.result_hash. الحمل الواقعي غالبًا أغنى من نتيجة استدعاء أداة واحدة: التفكير قبل القرار (توقع النموذج، الخيارات المدروسة، الأدلة وكمالها، موقف المخاطر، سلسلة المسؤولية، نتيجة البوابة) يمكن أن تعيش داخل الحمولة، مختومة بإيصال واحد. هذا يحافظ على بساطة تنسيق الإيصال مع السماح بتطور مخططات الحمولة حسب المجال.signature.alg يمكن أن يحمل ML-DSA-65 (معيار التوقيع ما بعد الكمومي من NIST) عند الحاجة للانتقال. خطط لفترة انتقالية يتواجد فيها التوقيع المزدوج.إنشاء وكلاء ذكاء اصطناعي محليين
تنويه: تمت ترجمة هذا المستند باستخدام خدمة الترجمة بالذكاء الاصطناعي Co-op Translator. بينما نسعى للدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو عدم دقة. يجب اعتبار المستند الأصلي بلغته الأصلية المصدر الرسمي والمعتمد. للمعلومات الهامة، يُنصح بالاستعانة بترجمة بشرية محترفة. نحن غير مسؤولين عن أي سوء فهم أو تفسير ناتج عن استخدام هذه الترجمة.