ai-agents-for-beginners

شاهد فيديو الدرس: تأمين وكلاء الذكاء الاصطناعي بالإيصالات المشفرة

(فيديو الدرس والصورة المصغرة ستضاف من قبل فريق محتوى مايكروسوفت بعد الدمج، بما يتماشى مع نمط الدرس 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..."
  }
}

ثلاث خصائص تقوم بالعمل:

  1. التوقيع. يتم توقيع الإيصال بواسطة بوابة الوكيل باستخدام مفتاح خاص Ed25519. يمكن لأي شخص لديه المفتاح العام المقابل التحقق من التوقيع دون الاتصال. أي تلاعب بأي حقل يبطل التوقيع.

  2. الترميز القياسي. قبل التوقيع، يتم تسلسل الإيصال باستخدام مخطط التوحيد القياسي لـ JSON (JCS، RFC 8785). هذا يضمن أن تنفيذين ينتجان نفس الإيصال المنطقي ينتجان إخراجًا مطابقًا بالبتات. بدون التوحيد القياسي، تقوم أدوات التسلسل المختلفة بإنتاج توقيعات مختلفة لنفس المحتوى.

  3. ربط التجزئة. يربط الحقل 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 خلاف ذلك. لا حاجة لاتصال شبكة، لا اعتماد على خدمة، لا ثقة مطلوبة بأي طرف ثالث.

لرؤية اكتشاف التلاعب عمليًا، يشرح الدفتر:

  1. إنتاج إيصال صالح وتأكيد أنه يتحقق.
  2. تعديل بايت واحد من حقل tool_args_hash.
  3. إعادة تشغيل التحقق ورؤية فشل العملية.

هذا هو العرض العملي لإثبات أن الإيصالات صعبة التلاعب: أي تعديل، مهما كان صغيرًا، يكسر التوقيع.

ربط الإيصالات لوكلاء متعددين الخطوات

إيصال موقع واحد يحمي فعلًا واحدًا. سلسلة من الإيصالات تحمي تسلسلًا.

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 بدون اكتشاف، يحتاج المهاجم إلى إما:

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

يشرح الدفتر:

  1. بناء سلسلة من ثلاثة إيصالات.
  2. التحقق من أن حقل previous_receipt_hash لكل إيصال يطابق تجزئة الإيصال السابق الفعلية.
  3. التلاعب بإيصال واحد في المنتصف ورؤية السلسلة تنكسر عند هذه النقطة بالضبط.

هكذا تنتج سجل تدقيق يمكن لمدقق خارجي التحقق منه دون الحاجة إلى الوثوق بك.

ما تثبته الإيصالات (وما لا تثبته)

هذا هو القسم الأهم في هذا الدرس. الإيصالات قوية لكن قوتها محدودة.

تثبت الإيصالات ثلاثة أمور:

  1. النسبة: وقع مفتاح معين حمولة معينة.
  2. السلامة: لم تتغير الحمولة منذ التوقيع.
  3. الترتيب: جاء هذا الإيصال بعد ذلك الإيصال في سلسلة التجزئة.

الإيصالات لا تثبت:

  1. الصحة: أن الفعل الذي قام به الوكيل هو الفعل الصحيح. يمكن توقيع إيصال على إجابة خاطئة بنفس سهولة توقيعه على إجابة صحيحة.
  2. الامتثال للسياسة: أن السياسة المشار إليها في policy_id تم تقييمها بالفعل، أو أنها كانت سترخص هذا الفعل إذا تم التحقق منها. الإيصال يسجل ما تم الادعاء به، لا ما تم تطبيقه.
  3. الهوية أبعد من المفتاح: الإيصال يقول “هذا المفتاح وقع هذا المحتوى.” لا يقول “هذا الإنسان أذن بهذا.” ربط مفتاح بشخص أو منظمة يتطلب بنية هوية منفصلة (دليل، سجل مفاتيح عامة، إلخ).
  4. صحة المدخلات: إذا استلم الوكيل موجهًا متلاعبًا وتصرف بناء عليه، يسجل الإيصال الفعل بأمانة. الإيصالات تعقب التحقق من المدخلات، وليست بديلا عنه.

هذه الحدود مهمة لسببين:

خطأ شائع هو افتراض أن “لدينا إيصالات” يعني “نحن محكومون.” هذا غير صحيح. الإيصالات هي الأساس. الحوكمة هي النظام الذي تبنيه عليه.

إثبات أن إنسانًا وافق على الفعل المحدد

نقطة 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) هو شكل المسار القياسي لهذا النمط.

مراجع الإنتاج

كود بايثون في هذا الدرس بسيط عمدًا لكي تقرأ كل سطر وتفهم تمامًا ما يحدث. في الإنتاج، لديك خياران:

  1. ابنِ مباشرة على البُنى التشفيرية الأساسية. الخمسون سطرًا التي شاهدتها أعلاه تكفي للعديد من الاستخدامات. مكتبة PyNaCl (Ed25519) وحزمة jcs (JSON القياسي) مكتبات مدعومة ومراجعة جيدًا.

  2. استخدم مكتبة للإيصالات في الإنتاج. تنفذ عدة مشاريع مفتوحة المصدر نفس النمط مع ميزات إضافية (تدوير المفاتيح، التحقق المجمّع، توزيع مجموعة JWK، تكامل مع محركات السياسات):

    • تنسيق الإيصال المستخدم في هذا الدرس يتبع مسودة IETF (draft-farley-acta-signed-receipts، المراجعة 02) وهي حالياً في مسار المعايير، مع مجموعة توافق مشتركة (agent-governance-testvectors) تتحقق من صحة التطبيقات المستقلة مقابل إخراج قياسي مطابق بالبتات.
    • مجموعة أدوات حوكمة الوكيل من مايكروسوفت تدمج الإيصالات مع قرارات سياسة تعتمد على Cedar؛ انظر الدرس 33 في ذلك المستودع لمثال شامل من البداية للنهاية.
    • حزم protect-mcp (npm) و @veritasacta/verify (npm) توفر تنفيذ Node لتوقيع الإيصالات والتحقق دون اتصال، مصممة لتغليف أي خادم MCP بسجل تدقيق صعب التلاعب، بما في ذلك تدفق الاحتجاز للموافقة في النشاط المعلق (مدعوم بـ WebAuthn في تدفق سطح المكتب)، وهو نفس نمط موافقة الإيصال كما في الدفتر البشري أعلاه.
    • مزود SDK بايثون nobulex (pip install nobulex) يقدم نفس نمط التوقيع Ed25519 + JCS في بايثون مع تكاملات LangChain و CrewAI، بما في ذلك متجهات اختبار التحقق المتقاطعة المنشورة وخريطة الامتثال المساهمة عبر OWASP PR #2210.

القرار بين كتابة كودك الخاص واستخدام مكتبة يعكس القرار بين كتابة مكتبة JWT خاصة بك واستخدام مكتبة مختبرة: كلاهما معقول؛ توفر المكتبة الوقت وتقلل من مساحة التدقيق؛ الطريقة من الصفر تجبرك على فهم كل عنصر أساسي. هذا الدرس يعلم الطريق من الصفر لكي تحصل على الأساس لأي خيار.

اختبار المعرفة

اختبر فهمك قبل الانتقال إلى تمرين الممارسة.

1. يقوم توقيع الإيصال بمفتاح Ed25519 الخاص بالوكيل. لدى المدقق المفتاح العام فقط. هل يمكن للمدقق التحقق من الإيصال دون اتصال؟

الإجابة نعم. يتطلب التحقق باستخدام Ed25519 المفتاح العام والبايتات الموقعة فقط. لا يوجد اتصال شبكة، ولا اعتماد على خدمة. هذه الخاصية تجعل الإيصالات مفيدة في بيئات التدقيق المنفصلة، متعددة المنظمات، أو منخفضة الثقة.

2. عدل مهاجم حقل policy_id في إيصال ليُدعي أنه خضع لسياسة أكثر تساهلًا. كان التوقيع على الحمولة الأصلية. ماذا يحدث أثناء التحقق؟

الإجابة فشلت عملية التحقق. تم حساب التوقيع على البايتات المعيارية للحمل الأصلي؛ تعديل أي حقل يغير البايتات المعيارية، مما يغير تجزئة SHA-256، مما يجعل التوقيع غير صالح. يحتاج المهاجم إلى المفتاح الخاص لإنتاج توقيع جديد صالح، وهو ما لا يملكه.

3. لماذا يتضمن الإيصال tool_args_hash و result_hash بدلاً من الوسائط والنتيجة الأصلية؟

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

4. يربط حقل previous_receipt_hash كل إيصال بالذي سبقه. إذا حذف مهاجم إيصالًا من منتصف سلسلة بصمت، ماذا يصبح غير صالح؟

الإجابة كل إيصال جاء بعد الإيصال المحذوف. لم تعد حقول `previous_receipt_hash` الخاصة بهم تطابق السلسلة الفعلية (لأن الإيصال الذي أشاروا إليه لم يعد موجودًا، أو السلسلة تشير الآن إلى سلف مختلف). لإخفاء الحذف، يجب على المهاجم إعادة توقيع كل إيصال لاحق، مما يتطلب المفتاح الخاص.

5. تحقق الإيصال بشكل نظيف. هل يثبت ذلك صحة الإجراء أو صوابه أو توافقه مع السياسة؟

الإجابة لا. إيصال صالح يثبت ثلاثة أشياء: النسب (هذا المفتاح وقع هذا المحتوى)، السلامة (المحتوى لم يتغير)، والترتيب (هذا الإيصال جاء بعد ذلك الإيصال). لا يثبت أن الإجراء كان صحيحًا أو أن السياسة المسماة في `policy_id` قد تم تقييمها فعليًا، أو أن الوكيل اتبع كل القواعد. تجعل الإيصالات سلوك الوكيل قابلًا للتدقيق، وليس بالضرورة صحيحًا. هذا هو الحد الأهم في الدرس.

تمرين تطبيقي

افتح code_samples/18-signed-receipts.ipynb وأكمل الأقسام الأربعة كلها:

  1. القسم 1: وقّع إيصالك الأول وتحقق منه.
  2. القسم 2: قم بالتلاعب بالإيصال وراقب فشل التحقق.
  3. القسم 3: أنشئ سلسلة من ثلاثة إيصالات وتحقق من سلامة السلسلة.
  4. القسم 4: طبق النمط على وكيل مبني بإطار عمل Microsoft Agent: لف استدعاء أداة بتوقيع الإيصال، ثم تحقق من الإيصال بشكل مستقل.

تحدي امتداد 1: قم بتوسيع مخطط الإيصال بحقل إضافي تختاره (مثلاً: معرف طلب للتتبع)، حدّث منطق التوقيع المعياري ليشمله، وتأكد من أن الإيصال لا يزال يمر بالتحقق بشكل صحيح. ثم عدّل الحقل بعد التوقيع وتأكد من فشل التحقق. هذا يجبرك على فهم كيف يساهم كل بايت من الترميز المعياري في التوقيع.

تحدي امتداد 2: قم بتجزئة SHA-256 لإثنين من إيصالاتك معًا (ربط البايتات المعيارية بترتيب حتمي) وادمج الرقم المختصر الناتج كحقل جديد على إيصال ثالث قبل توقيعه. تحقق من أن الثلاثة إيصالات لا تزال تمر بالتحقق. لقد أنشأت لتوك دليل دمج خطوة واحدة: يمكن لأي شخص يحمل الإيصال الثالث إثبات وجود الإثنين الأولين وقت توقيعه، دون الحاجة لكشف محتواهما. هذا هو النمط المستخدم في إيصالات الكشف الانتقائي على نطاق واسع (ارتباطات ميركل، RFC 6962).

الخاتمة

تمنح الإيصالات المشفرة لوكلاء الذكاء الاصطناعي مسار تدقيق يكون:

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

أهم نقطة: تثبت الإيصالات من قال ماذا ومتى. لا تثبت أن ما قيل كان صحيحًا أو صائبًا. احتفظ بهذا التمييز بإحكام. هو الفرق بين نظام مصدر نزيه وآخر مضلل.

قائمة التحقق للإنتاج

عندما تكون مستعدًا للتخرج من هذا الدرس إلى نشر وكلاء موقعين بإيصالات في بيئة حقيقية:

هل لديك المزيد من الأسئلة حول تأمين وكلاء الذكاء الاصطناعي؟

انضم إلى Microsoft Foundry Discord للقاء متعلمين آخرين، حضور ساعات المكتب، والحصول على إجابات لأسئلتك عن وكلاء الذكاء الاصطناعي.

ما بعد هذا الدرس

يغطي هذا الدرس توقيع إيصال واحد وتسلسل السلاسل المترابطة. نفس البدايات تترتب في عدة أنماط متقدمة قد تواجهها مع تطور وضع الحوكمة لديك:

موارد إضافية

الدرس السابق

إنشاء وكلاء ذكاء اصطناعي محليين


تنويه: تمت ترجمة هذا المستند باستخدام خدمة الترجمة بالذكاء الاصطناعي Co-op Translator. بينما نسعى للدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو عدم دقة. يجب اعتبار المستند الأصلي بلغته الأصلية المصدر الرسمي والمعتمد. للمعلومات الهامة، يُنصح بالاستعانة بترجمة بشرية محترفة. نحن غير مسؤولين عن أي سوء فهم أو تفسير ناتج عن استخدام هذه الترجمة.