شاهد فيديو الدرس: تأمين وكلاء الذكاء الاصطناعي باستخدام إيصالات تشفيرية
(فيديو الدرس والصورة المصغرة ستتم إضافتهما بواسطة فريق محتوى مايكروسوفت بعد الدمج، متطابقان مع نمط الدرس 14 / 15.)
سيغطي هذا الدرس:
بعد إكمال هذا الدرس، ستكون قادرًا على:
تخيل أنك نشرت وكيل ذكاء اصطناعي لشركة Contoso Travel. يقرأ الوكيل طلبات العملاء، ويستخدم واجهة برمجة تطبيقات الرحلات للبحث عن الخيارات، ويحجز المقاعد نيابةً عن العميل. في الربع الماضي، عالج الوكيل 50,000 حجز.
اليوم وصل مدقق. يطرح سؤالًا بسيطًا: “أرني ما فعله وكيلك.”
تسلمه ملفات السجل الخاصة بك. ينظر المدقق إليها ويسأل السؤال الأصعب: “كيف أعرف أن هذه السجلات لم تُحرر؟”
هذه هي مشكلة سجل التدقيق. تعتمد معظم عمليات نشر الوكلاء اليوم على:
لا يمكن لأي من هذه الإجابة على سؤال المدقق دون أن يطلب المدقق أن يثق بأحد (أنت، مزود السحابة الخاص بك، بائع قاعدة البيانات). للاستخدام الداخلي، يكون هذا الثقة مقبولًا غالبًا. ولكن في الأحمال الخاضعة للرقابة (المالية، الرعاية الصحية، أي شيء يخضع لقانون الذكاء الاصطناعي في الاتحاد الأوروبي)، هذا غير مقبول.
تحل الإيصالات التشفيرية هذه المشكلة بجعل كل إجراء للوكيل قابلاً للتحقق بشكل مستقل. لا يحتاج المدقق إلى الوثوق بك. يحتاج فقط إلى مفتاحك العام والإيصال نفسه.
الإيصال هو كائن JSON يسجل ما فعله الوكيل، موقعًا بتوقيع رقمي.
flowchart LR
A[الوكيل يستدعي أداة] --> B[بناء حمولة الإيصال]
B --> C[توحيد JSON وفق RFC 8785]
C --> 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). هذا يضمن أن تطبيقين ينتجان نفس الإيصال المنطقي ينتجان نفس التمثيل الباينري بالضبط. بدون التوحيد القياسي، قد تنتج محولات JSON مختلفة توقيعات مختلفة لنفس المحتوى.
سلسلة التجزئة. يربط حقل previous_receipt_hash كل إيصال بالإيصال الذي يسبقه. إزالة أو إعادة ترتيب إيصال يكسر كل الإيصالات التي تليه. يصبح التلاعب واضحًا على مستوى السلسلة حتى لو تم تجاوز التوقيعات الفردية.
معًا، توفر هذه الخصائص ثلاث ضمانات:
لا تحتاج إلى مكتبة خاصة لإنتاج إيصال. الأدوات التشفيرية متاحة على نطاق واسع والمنطق هو بضع عشرات من أسطر بايثون.
التمارين العملية في code_samples/18-signed-receipts.ipynb تستعرض العملية الكاملة. النسخة الملخصة:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # JSON القانوني RFC 8785
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,
}
# توحيد وقّع بايتات JCS مباشرة. PureEdDSA تقوم بالتجزئة داخليًا.
canonical_bytes = canonicalize(payload)
signature_bytes = signing_key.sign(canonical_bytes).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)
try:
verify_key = signing.VerifyKey(b64url_decode(sig_obj["public_key"]))
verify_key.verify(canonical_bytes, 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 على بايتاتها المعروفة JCS، مع كائن 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). يختلف الإيصال التعليمي المسطح في هذا الدرس عن الظرف {payload, signature} في المسودة ولا يُعرض كتنفيذ مطابق. تنشر المسودة مجموعة مطابقة مشتركة (agent-governance-testvectors) للتنفيذات التي تستهدف تنسيق السلك الخاص بها.protect-mcp (npm) و @veritasacta/verify (npm) تنفيذًا قائمًا على Node لتوقيع الإيصالات والتحقق دون اتصال، مخصصًا لتغليف أي خادم MCP بسجل تدقيق مقاوم للتلاعب، بما في ذلك تدفق موافقة مع تعليق العمل يصدر إيصال موافقة مرتبط بهضم الإجراء (يتم دعم WebAuthn في تدفق سطح المكتب)، نفس نمط إيصال الموافقة البشري في الدفتر أعلاه.pip install nobulex) نفس نمط التوقيع Ed25519 + JCS في Python مع تكاملات 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.انضم إلى Discord مايكروسوفت فاوندري لتلتقي بمتعلمين آخرين، تحضر ساعات العمل، وتحصل على إجابات لأسئلتك عن وكلاء الذكاء الاصطناعي.
يغطي هذا الدرس توقيع الإيصال الواحد وتسلسلات السلاسل المترابطة بالتجزئة. التركيبات نفسها تتشكل في عدة أنماط متقدمة قد تواجهها مع نضوج وضع الحوكمة لديك:
authorization_*) ونصف بعد التنفيذ (result_*) مع توقيعات مستقلة، مفيد عندما يكون قرار التفويض والنتيجة المرصودة ينتجها جهات مختلفة أو في أوقات مختلفة. هذا يركب مضافًا فوق تنسيق الإيصال الذي دُرس في هذا الدرس.result_hash. الحمولات الواقعية غالبًا ما تكون أغنى من مجرد نتيجة نداء أداة واحدة: التفكير قبل القرار (توقع النموذج، الخيارات المدروسة، الأدلة وكمالها، وضع المخاطر، سلسلة المساءلة، نتيجة البوابة) يمكن أن تعيش كلها داخل الحمولة، مختومة بإيصال واحد. هذا يحافظ على بساطة تنسيق الإيصال مع السماح لمخططات الحمولة بالتطور حسب المجال.signature.alg أن يحمل ML-DSA-65 (المعيار الكمومي لما بعد NIST) عند الحاجة للترحيل. خطط لفترة انتقال حيث تكون الإيصالات موقعة توقيعاً مزدوجاً.إنشاء وكلاء ذكاء اصطناعي محليين
تنويه: تمت ترجمة هذا المستند باستخدام خدمة الترجمة بالذكاء الاصطناعي Co-op Translator. بينما نسعى للدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو عدم دقة. يجب اعتبار المستند الأصلي بلغته الأصلية المصدر الرسمي والمعتمد. للمعلومات الهامة، يُنصح بالاستعانة بترجمة بشرية محترفة. نحن غير مسؤولين عن أي سوء فهم أو تفسير ناتج عن استخدام هذه الترجمة.