المؤلف: أغيلس آيت مساود، دكتوراه، مهندس برمجيات بحثية يعمل في iExec.

المقدمة

الجزء 1 من هذه السلسلة وضع الأساس لسلسلة الثقة Nox: تحقق وقت الإقلاع الذي يمنع الجهاز الظاهري السري (CVM) من الحصول على أي سر ما لم يكن قد أقلع صورة نظام تشغيل معروفة ومجموعة تطبيقات معروفة على عتاد Intel TDX موثّق. غير أن هذا الضمان، مع ذلك، يُطبَّق داخليًا بواسطة المنصة في وقت الإقلاع؛ ومن تلقاء نفسه، لا يتيح ذلك للمستخدم النهائي أو المدقق الخارجي أي طريقة مباشرة للتحقق، في لحظة لاحقة، من أن خدمة Nox قيد التشغيل ما تزال هي نفس عبء العمل الدقيق الذي تم توثيقه.

هذه الوثيقة هي الجزء الثاني من السلسلة وتعالج هذه الفجوة: attest وقت التشغيل، أي قدرة أي طرف على التحقق، في أي لحظة خلال عمر CVM، أن مكوّن Nox يعمل فعلًا داخل Intel TDX Trust Domain حقيقي. نوضح (i) كيفية طلب عرض TDX quote جديد من CVM قيد التشغيل وماذا يحتوي؛ (ii) المكونات المُنشرَة حول أسطول TDX لاكتشاف CVMs قيد التشغيل وإظهار quotes الخاصة بها؛ (iii) التسلسل الكامل والواجهة التي يراها المستخدم وتعرض هذا الدليل؛ و (iv) بروتوكول خطوة بخطوة الذي يتم عبره التحقق من عرض السعر، بدءًا من توقيعه وصولًا إلى docker-compose الذي تم تنفيذه فعليًا.

يُبنى مباشرة على أساس TEE الموضح في الجزء 1، ويحد بشكل متعمد نطاقه في attest وقت التشغيل كما يتم إظهاره عبر واجهة Runtime Attestation UI. يتم التعامل مع الروابط المتبقية في سلسلة الثقة، مثل ربط التعليمات البرمجية بالمصدر والحوكمة على السلسلة (on-chain governance) للقياسات المصرح بها، في أجزاء لاحقة.

يتم تنظيم بقية هذه الوثيقة على النحو التالي. في الخلفية (Background)، نعيد التذكير بما هو attest وقت التشغيل وكيف يتم تنظيم TDX quote وما هي الحقول الثلاثة التي يعتمد عليها Nox. في النشر المعماري (Architectural deployment)، نصف المكوّنات التي يتم نشرها حول خوادم TDX والبيانات التي يتبادلونها. في البيئة المرجعية (Reference environment)، نحدد إصدارات المكوّنات التي تعتمد عليها هذه المقالة. في مخطط التسلسل (Sequence Diagram)، نتابع تدفق النهاية إلى النهاية الذي من خلاله تكتشف الواجهة الـ CVMs قيد التشغيل وتقوم بـ attest لها. في عرض واجهة المستخدم (User Interface Presentation)، نعرض الواجهة ومستويات attest الثلاثة الخاصة بها. في خطوات التحقق من مكوّن Nox، نُفصّل بروتوكول التحقق المطبق على CVM واحد. وأخيرًا، في العمل المستقبلي (Future Work)، نلخص التحسينات المخططة: منشأ الصورة (image provenance)، تحديات يزودها المستخدم، وعمليات تحقق إضافية لعرض السعر.

الخلفية (Background)

في هذا القسم، نراجع المفاهيم التي تبني عليها هذه الوثيقة: ما هو attest وقت التشغيل، وكيف يتم تنظيم TDX quote، والحقول الثلاثة التي يعتمد عليها Nox، وهي report_data وRTMRs وسجلات الأحداث المرتبطة بها.

Runtime Attestation

يعد attest وقت التشغيل (runtime attestation) هو الآلية التي تتيح لأي طرف بعيد التحقق، عند الطلب وفي أي وقت خلال عمر CVM، أن مكوّن Nox يعمل فعليًا داخل Intel TDX Trust Domain (TD) حقيقي بالرمز والإعدادات المتوقعة. وبحيث إن attest وقت الإقلاع (boot-time attestation) (انظر الجزء 1) يثبت سلسلة الثقة من العتاد وصولًا إلى dstack-OS، فإن attest وقت التشغيل يعرض ذلك الثقة للمتحققين الخارجيين عبر بروتوكول بسيط challenge-response.

عرض TDX quote

يُعد عرض TDX quote بنية موقعة تشفيريًا يتم إنتاجها بواسطة Quoting Enclave للمنصة. يحمل هذا الدليل (evidence) الذي يحتاجه المُتحقق ليثق بـ TD ويتم توقيعه بمفتاح attest تم توفيره بواسطة Intel، بحيث يمكن لأي شخص التحقق من أصالته عبر تتبع سلسلة الشهادة وصولًا إلى جذر الثقة الخاص بـ Intel. الحقول الثلاثة التي يعتمد عليها Nox في attest وقت التشغيل (report_data وRTMRs وسجلات الأحداث المرتبطة بها) موضحة بالتفصيل أدناه.

report_data

report_data هو حقل بطول 64 بايت محتواه يتم اختياره بالكامل بواسطة التطبيق (workload). تقوم TDX بنسخه حرفيًا إلى عرض السعر الموقّع، ما يتيح للتطبيق ربط بيانات تعسفية (arbitrary data) بـ attest العتاد. من الاستخدامات الشائعة:

  • الحداثة / الاستجابة للتحدي (challenge-response): تضمين nonce يزوّده المُتحقق (verifier)، كما تفعل واجهة Runtime Attestation UI، لإثبات أن عرض السعر تم توليده عند الطلب (on demand).

  • ربط الهوية: تضمين تجزئة مفتاح عام أو شهادة TLS (أساس RA-TLS، انظر الجزء 1)، بحيث يتم إنهاء قناة آمنة داخل TD بصورة يمكن إثباتها.

  • أدلة أخرى، مثل عناوين محافظ blockchain أو تجزئات حالة التطبيق.

في Nox، تُنشئ الواجهة تحديًا عشوائيًا وتنتظر العثور على هذه القيمة بالضبط داخل report_data الخاص بعرض السعر.

RTMRs

سجلات قياس وقت التشغيل (RTMRs) هي مكافئ TDX لسجلات TPM PCRs: سجلات لا تقبل إلا الإلحاق (append-only) ولا يمكن كتابتها مباشرة، بل يتم فقط تمديدها عبر سلسلة تجزئة. يكشف TD أربعة منها، ويُسند dstack لكل واحد دورًا محددًا جيدًا:

  • RTMR0: بيئة العتاد الافتراضي / البرمجية الثابتة (firmware).

  • RTMR1: نواة Linux.

  • RTMR2: سطر أوامر kernel وinitrd.

  • RTMR3: قياسات خاصة بالتطبيق: app-id وos_image_hash وcompose-hash وinstance-id وkey-provider.

يتم التقاط محتوى الذاكرة الأولية وإعدادات TD بشكل منفصل في MRTD. أثناء التحقق، تقوم RTMR0–RTMR2 (مع MRTD) بإثبات سلامة سلسلة الإقلاع، بينما تقوم RTMR3 بإثبات أن كود التطبيق والإعدادات المتوقعة قيد التشغيل. في Nox نركز على RTMR3، لأنه يربط عرض السعر بمكوّن Nox المحدد وdocker-compose الخاص به.

سجلات الأحداث

قيمة RTMR هي تجزئة (hash) غير شفافة: فهي تؤكد ما إذا كانت القياسات المتوقعة قد تم دمجها، لكنها لا تُظهر ما كانت عليه. سجل الأحداث (event log) هو سجل قابل للقراءة من البشر لأحداث القياس الفردية التي تم تمديدها إلى RTMR (فعليًا، RTMR3). كل حدث هو قياس مفتاح-قيمة مثل app-id وcompose-hash وinstance-id أو key-provider، ويتم دمج كل حدث في السجل باستخدام معادلة التمديد:

RTMR3_new = SHA384(RTMR3_old || SHA384(event_log))

يعيد المُتحقق تشغيل (replays) سجل الأحداث عبر هذه الصيغة ثم يقارن السجل المُعاد حسابه بقيمة rt_mr3 داخل عرض السعر الموقّع. إذا تطابقت القيم، فيمكن الوثوق بقيم الحدث الفردية، ولا سيما os_image_hash وcompose_hash، بوصفها تمثيلًا أمينًا لصورة نظام التشغيل و docker-compose التي تم تنفيذها فعليًا بواسطة CVM.

النشر المعماري (Architectural deployment)

في هذا القسم، نصف المكوّنات التي يتم نشرها حول خوادم TDX لجعل واجهة Runtime Attestation UI تعمل، ونوضح شكل البيانات التي يتبادلونها.

لجعل واجهة Runtime Attestation UI تعمل، تتعاون خمسة مكوّنات رئيسية:

  • بوابة واجهة Runtime Attestation UI: الواجهة التي يصل إليها المستخدم لتصور عملية Runtime Attestation. تم نشرها بالفعل على جانب iExec عند https://trust.noxprotocol.io/، لكنها يمكن أيضًا إعادة بنائها ونشرها على أجهزة الكمبيوتر الشخصية باستخدام كود المصدر (https://github.com/iExec-Nox/nox-attestation-portal) . تطلب الواجهة nox-cvms-exporter-aggregator للحصول على قائمة CVMs النشطة، ومع كل واحدة منها عرض quote الذي تم جلبه حديثًا وdocker-compose الخاص بها. يتصل المُجمِّع نفسه بكل CVM عبر dstack-quote-service، لذلك لا تتحدث الواجهة (UI) مع CVMs مباشرةً.

  • nox-cvms-exporter: خدمة مضيفة (host service) تتصل بـ dstack hypervisor (dstack-vmm) لجمع قائمة CVMs النشطة (رابط dstack-quote-service الخاص بها) على جهاز TDX المحلي، ثم ترسلها إلى nox-cvms-exporter-aggregator.

  • nox-cvms-exporter-aggregator: خدمة تم نشرها على Azure Kubernetes Service وتقوم بتجميع قائمة CVMs النشطة التي تصل من كل nox-cvms-exporter فردي. بالنسبة لكل CVM مُدرج، تتصل بعد ذلك بخدمة dstack-quote-service الخاصة بـ CVM لجلب quote الجديد (مرتبط بتحدي الواجهة) وdocker-compose، ثم تُرجع القائمة المُثرّاة إلى بوابة واجهة Runtime Attestation UI.

  • إثبات ثقة خادم السحابة (Proof of Cloud Trust Server): خادم iExec لإثبات الثقة عبر السحابة (http://github.com/proofofcloud/trust-server) للتحقق مما إذا كان عرض السعر صادرًا من آلة TDX ضمن قائمة بيضاء ولم يتم إلغاؤه. يتم توثيق تفاصيل عملية إدراج الثقة عبر Proof of Cloud في الجزء الأول من سلسلة مقالاتنا.

  • Phala PCCS: ذاكرة تخزين محلية على Phala لحفظ بيانات التجميع/الملحقات (collaterals) (TCB Infos وشهادات Intel PCK وقائمة إلغاء الشهادات) للتحقق من عرض سعر.

البيئة المرجعية (Reference environment)

في هذا القسم، نُحدد بدقة الإصدارات المتضمنة للمكوّنات في واجهة Runtime Attestation UI، بحيث يمكن إعادة إنتاج سلوك موصوف في باقي هذه المقالة، ومع تطور هذه المكوّنات يمكن مقارنته بخط أساس (baseline) معروف.

مخطط التسلسل

في هذا القسم، نتابع التسلسل الكامل من البداية إلى النهاية الذي يكتشف من خلاله واجهة Runtime Attestation UI أجهزة CVMs قيد التشغيل ويؤكد (attests) عليها، بدءًا من فتح البوابة إلى عرض النتيجة.

يصف هذا المخطط كيف تكتشف واجهة Runtime Attestation UI الـ Confidential VMs (CVMs) التي تعمل عبر مجموعة TDX، وكيف تقوم بـ attest لها.

  1. فتح البوابة: يفتح المستخدم البوابة، إما مباشرة عبر مثيل iExec المُستضاف https://trust.noxprotocol.io أو عبر إنشاء المصدر وتشغيله ذاتيًا (https://githu b.com/iExec-Nox/nox-attestation-portal )عند التحميل، تُولِّد الواجهة تحديًا عشوائيًا واحدًا (32 بايت) يُتوقع أن يكون مرتبطًا (bound) بالعروض التي تم جمعها.

  2. طلب الاكتشاف (Discovery request): تستدعي الواجهة المُجمِّع GET /cvms، وتمرير تحديها كمعامل استعلام (?challenge=...). يُعد هذا المعامل إلزاميًا لأن التحدي يجب تمريره إلى CVMs لربط عروض الأسعار التي سيتم إرجاعها.

  3. توزيع المهام على عدة مُصدّرين (Fan-out to exporters): لكل آلة TDX ضمن قائمة المُصدّرين (exporter list) المُهيأة لديها، يستدعي المُجمِّع GET {base_url}/cvms بالتوازي. لا يتم تمرير التحدي في هذه المرحلة؛ بل يُستخدم لاحقًا عند جلب عروض الأسعار.

  4. تعداد CVM محلي: يستعلم كل مُصدِّر (exporter) عن جهاز dstack-vmm المحلي لديه (POST /prpc/Status?json) لإدراج VMs التي تعمل على تلك الآلة.

  5. استجابة VMM: يُرجع dstack-vmm قائمة VM الخام. يقوم المُصدّر بفلترة VMs التي تكون حالتها متوقفة/محذوفة، ويستبعد الـ kms وdstack-gateway باعتبارهما CVMs نظامية (system CVMs).

  6. استجابة المُصدّر (Exporter response): يبني المُصدِّر لكل CVM عنوان (base URL) لخدمة quote ويعيد CVMs مجمعة حسب app_id، بحيث يحمل كل مثيل { instance_id, url, machine_id }.

  7. طلب عرض السعر (إثراء): يُثري المُجمِّع كل مثيل بعرضه الجديد: لكل مثيل، يستدعي المُجمِّع خدمة quote الخاصة بـ CVM GET {url}/quote?data={challenge}، مع تمرير تحدي الواجهة (UI challenge) بحيث يكون عرض السعر المُعاد مرتبطًا به.

  8. استجابة عرض السعر: تُرجع خدمة quote-service { quote, event_log } لأن الواجهة تحتاج عرض السعر للتحقق من التوقيع، وسجل الأحداث (event log) لإعادة تشغيل RTMR3.

  9. طلب manifest: بالتزامن مع طلب عرض السعر، يستدعي المُجمِّع نفس خدمة quote-service في CVM GET {url}/info لاسترجاع manifest النشر (deployment manifest).

  10. استجابة manifest: تُرجع خدمة quote-service حمولة /info الخاصة بها، ومن خلالها يستخرج المُجمِّع manifest docker-compose (tcb_info.app_compose).

  11. الدمج (Merge) والرد (respond): يعيد المُجمِّع تجميع المثيلات المثرّاة حسب app_id ويُرجع القائمة المدمجة إلى الواجهة (UI)، حيث يحمل كل مثيل الآن { instance_id, machine_id, quote: { quote, event_log }, app_compose }. يتم الاحتفاظ بحقل url داخليًا لدى المُجمِّع ولا يتم إظهاره للواجهة إطلاقًا، لذلك لا توجد طريقة للمتصفح للوصول إلى CVMs مباشرةً. يُوضح ملف JSON أدناه مثالًا لسجل مُجمَّع تم إرساله بواسطة nox-cvms-exporter-aggregator إلى واجهة attest.

{

"app_id": "a1b2c3...",

"name": "nox-component-cvm",

"instances": [

{

"instance_id": "i-0abc123",

"machine_id": "Node 1",

"quote": {

"quote": "0x0400...", # عرض TDX (hex)

"event_log": [ ... ] # سجل RTMR3

},

"app_compose": "..." # manifest docker-compose (YAML)

},

{

"instance_id": "i-0def456",

"machine_id": "Node 2",

"quote": {

"quote": "0x0400...",

"event_log": [ ... ]

},

"app_compose": "..."

}

]

}

التحقق والعرض (Verify & display): لكل CVM يُعاد، تتحقق الواجهة محليًا من attest وتعرض CVMs مع النتيجة. يتم تفصيل بروتوكول التحقق هذا في قسم "خطوات التحقق من مكوّن Nox".

عرض واجهة المستخدم (User Interface Presentation)

في هذا القسم، نعرض واجهة Runtime Attestation UI والمستويات الثلاثة من attest التي تُظهرها للمستخدم.

واجهة Runtime Attestation UI كما تظهر في NOX · سلسلة الثقة https://trust.noxprotocol.io

توضح اللقطة أعلاه واجهة Runtime Attestation UI. عند التحميل، يسرد الجزء الأيسر مكوّنات nox قيد التشغيل على أجهزة TDX الخاصة بالشبكة التجريبية (testnet)، ولكل مكوّن يتم وضع تعليق يوضح عدد النسخ (replicas) (مثل 6 لـ nox-kms). توفر الواجهة ثلاثة مستويات من attest لمكوّنات nox:

  1. تحقق كامل (Full verification): عند النقر على زر Verify all، سيتم التحقق من جميع مثيلات CVM لجميع مكوّنات nox
    .

  2. تحقق على مستوى المكوّن (Component-level verification): يصبح هذا المستوى متاحًا بمجرد اختيار مكوّن nox من اللوحة الجانبية اليسرى. عند النقر على Verify all، سيتم التحقق من جميع مثيلات CVM التابعة للمكوّن المختار بغض النظر عن الآلة الأساسية التي تعمل عليها.

  3. تحقق على مستوى المثيل (Instance-level verification): يصبح هذا المستوى متاحًا أيضًا بمجرد اختيار مكوّن nox من اللوحة الجانبية اليسرى. عند النقر على Verify، سيتم التحقق من المثيل المحدد فقط من المكوّن المختار.

خطوات التحقق من مكوّن Nox

في هذا القسم، نُفصِّل بروتوكول التحقق خطوة بخطوة المطبق على CVM لمكوّن Nox واحد، ونصف ما الذي تعرضه الواجهة (UI) بمجرد اجتياز كل فحص.

سير عمل Runtime Attestation لمكوّن Nox

يستمر بروتوكول التحقق المطبق على CVM لمكوّن Nox كما يلي:

  1. احصل على عرض سعر جديد: الواجهة (UI) تُنشئ تحديًا عشوائيًا وتستحصل، عبر المُجمِّع (aggregator)، على عرض سعر جديد مرتبط بذلك التحدي (انظر مخطط التسلسل). يُتوقع أن يكون التحدي مضمَّنًا داخل تقرير (report_data) عرض السعر.

  2. التحقق من توقيع عرض السعر وسلسلة الشهادات: يتم التحقق من توقيع عرض السعر وسلسلة الشهادات الخاصة به حتى Intel بواسطة مُتحقق DCAP. وفي التنفيذ الحالي، يتم ذلك محليًا داخل المتصفح عبر Phala dcap-qvl المضمَّن (مكتبة التحقق من عرض السعر: githubl). يجلب QVL بيانات التحقق الملحقة (معلومات TCB وسلسلة شهادات Intel المرتكزة على الجذر) من dstack PCCS (خدمة تخزين شهادات التزويد Provisioning Certificate Caching Service المُستضافة على Phala) ثم يقوم بالتحقق بنفسه. بالتوازي، يتم إرسال عرض السعر إلى خادم Proof of Cloud trust server, والذي يُبلِّغ عما إذا كانت الآلة التي تمّت attest لها تنتمي إلى أسطول سحابي مُدرجًا في القائمة البيضاء (مُعتمدًا). وتُعد نتيجة Proof-of-cloud معلوماتية وغير مُعيقة (non-blocking): فإذا كان خادم الثقة غير متاح أو حدث مهلة زمنية (timeout)، يستمر التحقق (attestation) رغم ذلك.

  3. التحقق من حداثة عرض السعر: يتم تأكيد حداثة عرض السعر عبر التحقق من أن تحديًا عشوائيًا تم توليده بواسطة الواجهة (UI) تم تضمينه داخل report_data الخاص بعرض السعر.

  4. عرض قيم RTMR: خطوة إرشادية (informative) تستخرج وتعرض قيم RTMR الخاصة بعرض السعر.

  5. إعادة تشغيل (Replay) RTMR3: يتم استخدام سجلات الأحداث التي تُعاد إلى جانب عرض السعر (في استجابة المُجمِّع) لإعادة تشغيل RTMR3 وفقًا لصيغة Intel: RTMR3_new = SHA384(RTMR3_old || SHA384(event_log)). إذا تطابقت قيمة RTMR3 المُعاد تشغيلها مع القيمة الموجودة في عرض السعر (attested)، فيمكن الوثوق بقيم event_log الخاصة بـ os_image_hash وcompose_hash بوصفها ممثلة للأوس (OS) و docker-compose التي تم تنفيذها فعليًا.

  6. التحقق من صورة نظام التشغيل (OS image): يتم استخراج سجل حدث RTMR3 الخاص بـ os_image_hash، ويتم توفير رابط تنزيل حتى يمكن التحقق يدويًا من الصورة وبصمتها (hash) عند الحاجة. في iExec، تكون هذه الصورة هي dstackOS.

  7. التحقق من compose-hash: يتم تجزئة docker-compose (app_compose، المقدم في استجابة المُجمِّع) ومقارنة النتيجة بالـ compose_hash المضمّن كـ RTMR3 event log.

بعد تنفيذ خطوات التحقق هذه، يتم عرض docker-compose المقابل لـ compose-hash الخاص بـ CVM الذي تم attest له كما هو موضح في الصورة أدناه.

جزء من docker-compose الخاص بـ nox-kms

يشمل docker-compose الخاص بـ CVM ثلاث خدمات:

  • مكوّن nox: خدمة الأعمال التي يتم تنفيذها داخل CVM (مثل nox-kms)

  • خدمة quote-service: الخدمة المستخدمة للحصول على عرض السعر وسجلات الأحداث المطلوبة لإجراء attest على CVM

  • fluent-bit: خدمة مُصدّر سجلات iExec log exporter لأغراض المراقبة الداخلية (internal observability)

العمل المستقبلي

في هذا القسم، نُحدد التحسينات المخطط لها لمسار (flow) attest: منشأ الصورة (image provenance)، التحديات التي يقدمها المستخدم، وعمليات تحقق إضافية لعرض السعر (quote verifiers).

منشأ الصورة (Image provenance)

حتى الآن، يتوقف attest عندما نعرض docker compose الذي يسرد الصور التي تم تنفيذها داخل CVM الذي تم attest له. الخطوة التالية هي الاستفادة من بنية Sigstore لتوقيع سير عمل GitHub Actions الذي أنشأ كل صورة أثناء بنائها، ثم نشر attest لـ SLSA (Supply-chain Levels for Software Artifacts) المحدد بواسطة sha256 checksum للصورة (subject-name) في GitHub وسجل docker registry للصورة. سيتم دفع إدخال Rekor أيضًا بشكل طبيعي. ومن خلال ذلك، سنكون قادرين على توسيع خطوات التحقق المذكورة في هذه المقالة عبر attest على منشأ (provenance) كل صورة من صور Nox (أي سير عمل البناء وcommit الخاص بمستودع GitHub).

تحدي يُدخل من المستخدم

حاليًا، لاختبار حداثة عرض سعر، نستخدم تحديًا يتم توليده تلقائيًا يتم تمريره من الواجهة إلى المُجمِّع كمعامل استعلام، والذي بدوره يمرره إلى كل quote-service. سنقوي هذه العملية عبر السماح لمستخدمي الواجهة بإدخال تحديهم الخاص للحصول على مستوى إضافي من الثقة في حداثة عرض السعر.

متعددون من المُتحققين

حاليًا، نستخدم Phala qvl كطريقة تحقق وحيدة للتحقق من توقيع Intel وسلسلة الشهادات الخاصة بعرض سعر. سنضيف طرق تحقق إضافية، إما كنسخ احتياطية أو كعمليات تحقق إلزامية عند توفرها، لتحسين الثقة في نتيجة التحقق. ومن المتحققين المحتملين لإضافتهم: dstack-verifier المُستضاف على iExec وIntel Trust Authority.