نشر السياسات بضابط مزدوج عبر HashiCorp Vault Transit
حزمة السياسات الموقّعة هي المخرج الوحيد الذي ينبغي لوكيل الحوكمة أن يثق به. وهكذا ننشرها بضابط مزدوج، وندوّر المفاتيح بلا انقطاع، ونثبت السلامة عند كل طلب، باستخدام HashiCorp Vault Transit وتواقيع Ed25519.
الخلاصة. إن استطاع مهندس واحد دفع تغيير سياسة يخفف الحجب، أو يفتح نقطة نهاية جديدة، أو يضيف نموذجًا إلى القائمة البيضاء، فوكيل الحوكمة مسرحية. فالإنفاذ الحقيقي يقوم على حزم موقّعة، وضابط مزدوج عند كل نشر، وتدوير مفاتيح لا يحتاج إعادة نشر. ويتولى HashiCorp Vault Transit التشفير، ويُبقي Ed25519 التحقق رخيصًا، بينما تربط مجموعة صغيرة من سياسات النشر الاثنين معًا.
يقرر وكيل الحوكمة، عند كل طلب، ما إذا كان يجوز لطلب أن يغادر محيطك، وهل تُحجب البيانات الشخصية، وهل يجوز أن يتضمن الرد شيفرة، وأي النماذج يمكن الوصول إليها أصلًا. ويُنفَّذ ذلك الحد بواسطة حزمة سياسات: مخرج مُدار بالإصدارات وقابل للقراءة آليًا، مُجمَّع من قواعد تعريفية. ومن يستطيع تغيير تلك الحزمة يتحكم بالمحيط.
يستعرض هذا المقال النموذج الذي نستخدمه لنشر حزم السياسات في Raigate: كيف تُصدَر تواقيع Ed25519 عبر HashiCorp Vault Transit، وكيف يُفرض الضابط المزدوج عند خطوة النشر (لا في بيئة التطوير)، وكيف يتحقق الوكيل من الحزم عند التحميل، وكيف ندوّر مفاتيح التوقيع بلا نافذة صيانة.
المحتويات
- لماذا ينتمي الضابط المزدوج إلى طبقة السياسات
- تشريح حزمة سياسات موقّعة
- Vault Transit كوسيط توقيع
- تدفق النشر من الطرف إلى الطرف
- التحقق عند طبقة الوكيل
- تدوير المفاتيح ونمط إعادة التوقيع
- زاوية الامتثال: ما يطلبه المدققون فعلًا
1. لماذا ينتمي الضابط المزدوج إلى طبقة السياسات
معظم الفرق تفرض الضابط المزدوج في مكان ما أصلًا: عمليات النشر الإنتاجية، وترحيلات قواعد البيانات، وتغييرات إدارة الهوية والوصول. وحزم السياسات لوكيل حوكمة ذكاء اصطناعي تستحق المعاملة نفسها، لسبب بسيط: الحزمة هي السياسة.
وتغيير سطر واحد في مسند JSON قد:
- يعطّل بصمت حجب البيانات الشخصية لمستأجر،
- يسمح بنقطة نهاية صادرة جديدة تسرّب الطلبات،
- يضيف إلى القائمة البيضاء نموذجًا غير معتمد بمواءمة أمان أضعف،
- يحوّل الافتراضات من فشل مغلق إلى فشل مفتوح.
ومراجعة الشيفرة وحدها لا تكفي. فالمراجع الذي يعتمد طلب الدمج ليس هو الموقّع المشارك تشفيريًا الذي يشهد على المخرج الذي يُنشر فعلًا. وقد ينحرف الاثنان عبر إعادة أساس، أو تعارض دمج، أو تعديل «بسيط» في اللحظة الأخيرة بعد الاعتماد، أو منفّذ تكامل مستمر مخترق.
والحل نقل حد الثقة من مستودع الشيفرة إلى المخرج الموقّع. فكل وكيل عامل يتحقق من التوقيع قبل تحميل حزمة. ولا تُحمَّل حزمة إلا إن حملت توقيعًا صالحًا من مفتاح يثق به الوكيل أصلًا؛ أما التوقيع المفقود أو الفاسد أو الصالح من مفتاح غير معروف فيبقي الحزمة على القرص بلا تحميل.
2. تشريح حزمة سياسات موقّعة
الحزمة أرشيف حتمي. تدخل المدخلات، ويخرج تدفق بايتات معياري، ثم يُجزَّأ ذلك التدفق ويُوقَّع. والحتمية تهم لأن السياسة المنطقية نفسها يجب أن تنتج التجزئة نفسها على أي آلة. وإلا صار التحقق من التوقيع تقلّبًا لا ضمانة.
bundle/
├── manifest.json # version, created_at, source commit, framework refs
├── policies/
│ ├── redaction.json # PII handling rules, fail-closed defaults
│ ├── routing.json # which models, which endpoints, per tenant
│ └── content.json # blocked categories, output constraints
├── checksums.txt # SHA-256 of every file above, sorted by path
└── signatures/
├── primary.sig # Ed25519 over checksums.txt
└── secondary.sig # Ed25519 over checksums.txt, different signer
- redaction.json: قواعد البيانات الشخصية، وافتراضات الفشل المغلق
- routing.json: النماذج ونقاط النهاية لكل مستأجر
- content.json: الفئات المحظورة وحدود المخرجات
- primary.sig: Ed25519، هوية قائد السياسات
- secondary.sig: Ed25519، هوية المراجعة الأمنية
- كلاهما مطلوب. شخصان مختلفان، ومفتاحا Vault مختلفان.
الملف checksums.txt هو نقطة التوحيد المعياري. فالملفات مسرودة أبجديًا؛ وكل سطر هو <sha256> <path>. ولا يوقّع الموقّعون الأرشيف الخام قط؛ بل يوقّعون checksums.txt. وهذا يبقي التواقيع مستقرة عبر صيغ الأرشيف وإصدارات الأدوات، ويمنح المتحقق مسارًا سريعًا: جزّئ الملفات، وأعد توليد checksums.txt، وقارنه بما وُقّع.
وسطح الضابط المزدوج هو هذا بالضبط: توقيعان، ينتجهما مفتاحان مختلفان يملكهما شخصان مختلفان.
3. Vault Transit كوسيط توقيع
نحن لا نحتفظ أبدًا بمفاتيح خاصة خام على أجهزة المطورين أو منفّذي التكامل المستمر. فـ Vault Transit يعرض التوقيع كواجهة برمجية؛ وتبقى مادة المفتاح داخل Vault ويمكن تدويرها أو إدارة إصداراتها أو إبطالها دون لمس أي عميل.
ويعيش مفتاحان مسمّيان في خلفية Transit:
policy-bundle-primary، يملكه دور قائد هندسة السياساتpolicy-bundle-secondary، يملكه دور المراجعة الأمنية
وكلا المفتاحين Ed25519 وغير قابلين للتصدير، ولكليهما إدارة إصدارات مفعّلة.
وإصدار توقيع استدعاء واجهة واحد مقابل Vault: المدخل هو تجزئة SHA-256 لملف checksums.txt مُرمَّزة بـ base64، والمخرج توقيع بـ base64 مع إصدار المفتاح الذي أنتجه:
vault write transit/sign/policy-bundle-primary/sha2-256 \
input="$(sha256sum checksums.txt | awk '{print $1}' | xxd -r -p | base64)" \
prehashed=true \
signature_algorithm=pkcs1v15
واستدعاء التوقيع مقيّد بسياسة Vault تتطلب هوية بشرية مصادَقة وتذكرة موافقة نشطة معًا. فلا يستطيع أي حساب خدمة استدعاء transit/sign/policy-bundle-primary مباشرة. والأمر نفسه، بسياسة مختلفة ومجموعة هوية مختلفة، ينطبق على المفتاح الثانوي.
وهذا ما يحوّل الضابط المزدوج من عرف فريق إلى خاصية مفروضة في النظام: فلا يستطيع شخص واحد إنتاج التوقيعين، لأن لا هوية واحدة تملك صلاحيات Vault لاستدعاء نقطتَي التوقيع معًا.
4. تدفق النشر من الطرف إلى الطرف
وسيط التوقيع هو حجر الزاوية، لكن التدفق حوله هو ما يجعل تشغيل النظام آمنًا. والمسار الذي يسلكه تغيير سياسة من المسودة إلى النشر:
وعمليًا:
- المؤلف يفتح تغيير السياسة كطلب دمج عادي. ويبني مسار التكامل المستمر حزمة مرشّحة وينشر تجزئة SHA-256 لها كفحص حالة. ولا يمكن دمج الطلب دون مطابقة تلك التجزئة لآخر التزام في الفرع.
- المراجع يفتح الحزمة المرشّحة في استوديو السياسات، ويجري تقييمًا جافًا مقابل مجموعة انحدار (حركة تاريخية معادة التشغيل مع مجموعة منتقاة من طلبات الفريق الأحمر)، ثم إما يرفض أو يَسِم الحزمة جاهزة للنشر. والمراجع ليس المؤلف.
- التوقيع الأساسي يُطلَب. فيسحب النظام الحزمة المرشّحة، ويعيد حساب
checksums.txt، ويستدعي Vault Transit بهوية المؤلف مؤكّدًا سياسة التوقيع الأساسية. ويُرفَق التوقيع. - التوقيع الثانوي يُطلَب تحت هوية المراجع، مقابل المفتاح الثانوي. وإن كان أي توقيع مفقودًا أو باطلًا، فلا تغادر الحزمة بيئة البناء أبدًا.
- الموزّع ينشر الحزمة مزدوجة التوقيع إلى مخزن المخرجات على مسار معنون بالمحتوى:
bundles/<sha256>.tar.gz. ويسحب الأسطول من هناك. - أسطول الوكلاء يتحقق من التوقيعين مقابل المفاتيح العامة المثبَّتة لإصدارات المفاتيح الحالية، ثم يبدّل السياسة النشطة ذريًا. وفشل التحميل يبقي الحزمة السابقة في مكانها، بفشل مغلق حتى النهاية.
فلا يستطيع أحد اعتماد تغييره الخاص، ولا يستطيع المراجع النشر دون التوقيع الأساسي من المؤلف. والموزّع بدوره لا يقبل إلا حزمًا يتحقق توقيعاها تحت مجموعة المفاتيح العامة الحالية. وكل بوابة فحص تشفيري صارم لا عنصر واجهة.
5. التحقق عند طبقة الوكيل
يحتفظ الوكيل بمجموعة صغيرة من المفاتيح العامة المثبَّتة بالإصدار في تهيئته:
{
"trusted_signers": [
{
"name": "policy-bundle-primary",
"key_versions": {
"v2": "MCowBQYDK2VwAyEA<...base64 ed25519 public key...>",
"v3": "MCowBQYDK2VwAyEA<...base64 ed25519 public key...>"
}
},
{
"name": "policy-bundle-secondary",
"key_versions": {
"v1": "MCowBQYDK2VwAyEA<...base64 ed25519 public key...>",
"v2": "MCowBQYDK2VwAyEA<...base64 ed25519 public key...>"
}
}
],
"require_both": true,
"min_key_versions": { "primary": 2, "secondary": 1 }
}
وروتين التحقق، بخطوات واضحة:
- فك الأرشيف إلى دليل مؤقت.
- إعادة توليد
checksums.txtمن الملفات المستخرجة بترتيب مرتّب. - تجزئته بـ SHA-256.
- لكل ملف
.sig، قراءة اسم المفتاح وإصداره المضمّنين، والبحث عنهما فيtrusted_signers، والفشل المغلق إن كانا مفقودين. - التحقق من توقيع Ed25519 مقابل التجزئة المُعاد حسابها.
- إن كان
require_bothمضبوطًا، وجب تحقق الاثنين. وإلا فالرفض.
واختير Ed25519 لكلفة تحققه. فالتحقق من توقيع واحد دون الميلي ثانية على عتاد اعتيادي، وهو رخيص بما يكفي للتشغيل عند كل إعادة تحميل حزمة، وعند فحص صحة الوكيل، وداخل فحص جاهزية يرفض وسم الحاوية جاهزة حتى تُعاد صحة الحزمة النشطة.
ولا يثق الوكيل أبدًا بمفتاح لم يُخبَر به. فإصدارات المفاتيح الجديدة تتطلب تحديث تهيئة، وهو نفسه يمر بمسار المراجعة والنشر نفسه لأي تغيير إنتاجي آخر.
6. تدوير المفاتيح ونمط إعادة التوقيع
مفاتيح Ed25519 لا تضعف بمرور الوقت، لكن المبدأ التشغيلي يبقى: أي مفتاح وقّع مدة طويلة كفاية ينبغي تدويره. والخطر ليس الخوارزمية، بل الحيازة، ودوران الموظفين، والتراكم البطيء للهويات التي كان يمكنها لمس نقطة توقيع عبر نافذة تمتد سنوات.
والجزء المؤلم من التدوير ليس توليد مفتاح جديد. فـ Vault Transit يفعل ذلك باستدعاء واحد:
vault write -f transit/keys/policy-bundle-primary/rotate
الجزء المؤلم هو ما يحدث للحزم المنشورة أصلًا والموقّعة بإصدار المفتاح القديم. وأمامك خياران:
- فرض إعادة نشر لكل حزمة، ولكل مستأجر، عند كل تدوير. صاخب ومُعطِّل ومغرٍ بتخطيه المرة القادمة.
- إعادة توقيع الحزم القائمة في مكانها عبر عملية دفعية محكومة.
ونحن نستخدم الثاني. فمُعيد التوقيع مهمة قصيرة العمر تعمل مقابل مخزن المخرجات: تحمّل كل حزمة منشورة حاليًا، وتعيد التحقق من التواقيع القائمة (فإصدارات المفاتيح القديمة تبقى موثوقة أثناء نافذة التداخل)، ثم تطلب توقيعًا أساسيًا جديدًا تحت إصدار المفتاح المُدوَّر وتعيد كتابة الحزمة بالتوقيعين مرفقين.
- ينتج Vault Transit إصدار مفتاح جديدًا (v_new)
- يبقى الإصدار القديم (v_old) صالحًا للتحقق
- تُحدَّث تهيئة ثقة الوكيل لقبول الإصدارين
الحالةإصدارا مفتاح في التداول؛ ولم يتغير شيء بعد للحزم المنشورة
- تسرد مهمة إعادة التوقيع كل حزمة في مخزن المخرجات
- لكل منها: تحقق(v_old) + تحقق(الثانوي)، ثم توقيع(v_new)
- تُعاد كتابة الحزمة بتوقيع أساسي جديد مع حفظ الثانوي
- هوية مُعيد التوقيع محصورة بهذا التدفق فقط
الحالةكل حزمة منشورة تحمل الآن توقيعًا أساسيًا بإصدار v_new
- إزالة v_old من تهيئة ثقة الوكيل
- إزالة v_old من Vault Transit
- يحفظ سجل التدقيق حدثَي التوقيع كليهما للحزمة التاريخية
الحالةلم يعد v_old موثوقًا في أي مكان؛ اكتمل التدوير بلا انقطاع
أمران يستحقان الملاحظة:
- يُحفظ التوقيع الثانوي دون تغيير. فتدوير المفتاحين في آن واحد سيمحو دليل الضابط المزدوج على كل حزمة تاريخية. ونحن ندوّرهما بجداول متباعدة.
- يعمل مُعيد التوقيع بـهوية مخصصة خاصة به لا يُسمح لها إلا باستدعاء تدفق إعادة التوقيع: فلا يستطيع تأليف حزم جديدة، ولا نشر تغييرات سياسة مستحدثة، ولا إزالة تواقيع. بل يستطيع فقط إعادة ربط حزمة وقّعها بشران أصلًا بأحدث إصدار للمفتاح الأساسي. وذلك النطاق المحدود هو السبب الكامل لأمان أتمتته.
7. زاوية الامتثال: ما يطلبه المدققون فعلًا
المادة 12 من قانون الذكاء الاصطناعي الأوروبي (حفظ السجلات)، وISO 27001 الملحق أ.12.4 (التسجيل)، وSOC 2 CC7.2 (إدارة التغيير). كلها تتقارب على الأسئلة الثلاثة نفسها حين تُطبَّق على سياسة حوكمة الذكاء الاصطناعي:
- من صرّح بهذا التغيير، وكيف تثبت ذلك؟
- هل يمكن العبث بالتغيير بعد التصريح؟
- هل تستطيع إعادة بناء أي سياسة كانت نشطة لحظة أي قرار سابق؟
والحزم الموقّعة تجيب عن الثلاثة:
- من صرّح تجيب عنه هويتان مختلفتان في Vault، لكل منهما حدث توقيع مسجَّل في جهاز تدقيق Vault. والهويتان مرتبطتان ببشر عبر مزوّد الهوية لديك، ويسجّل حدث التوقيع الطابع الزمني وإصدار المفتاح وتجزئة المدخل.
- مقاومة العبث تتبع لأن أي تعديل لأي ملف داخل الحزمة يغيّر
checksums.txt، وهو ما يُبطل التوقيعين، فيرفض الوكيل تحميلها. - إعادة البناء التاريخية تأتي من حقل
policy_bundle_sha256الذي يمكن أن يحمله كل طلب في سجل التدقيق. فقارن تلك التجزئة بمخزن المخرجات ولديك الحزمة الدقيقة، بتواقيعها الدقيقة، التي قررت في ذلك الطلب.
وتمتد سلسلة التدقيق من الطرف إلى الطرف: فسجل الطلب يشير إلى الحزمة، والحزمة إلى أحداث التوقيع، وتلك إلى الهويات البشرية خلفها، فيقوم المسار على سجلات لا على تطمينات شفهية.
خاتمة
الضابط المزدوج على نشر السياسات من الاستثمارات الهندسية التي تبدو عبئًا حتى أول مرة توقف فيها تغييرًا سيئًا من الشحن، وعندها تكون قد سدّدت كلفتها تقريبًا. والتشفير مفهوم جيدًا، والأدوات موجودة، وتحقق Ed25519 رخيص بما يكفي لانتفاء أي حجة أداء ضد تشغيله عند كل تحميل حزمة.
والعمل الأصعب تشغيلي: تعريف دورَي التوقيع، ووضع سياسات Vault الصحيحة أمام المفاتيح، وبناء مُعيد توقيع تثق بتشغيله بلا إشراف، ومقاومة إغراء إضافة مسار «كسر الزجاج» يهزم النموذج كله.
سننشر لاحقًا قائمة تحقق الامتثال لقانون الذكاء الاصطناعي الأوروبي: سطح الضوابط نفسه، مربوطًا مادةً بمادة، بمؤشرات صريحة إلى موضع وفاء كل مخرج (حزمة موقّعة، وسجل تدقيق، وسجل تدوير مفاتيح) بأي متطلب.
قراءات إضافية
- HashiCorp Vault: وثائق محرك أسرار Transit
- RFC 8032: خوارزمية التوقيع الرقمي على منحنيات إدواردز (EdDSA)
- ISO/IEC 27001:2022، الملحق أ.12.4 (التسجيل والمراقبة)
- اللائحة (EU) 2024/1689، المواد 12 و15 و26
هل أنت مستعد لتأمين
بنيتك المؤسسية؟
احجز جلسة إحاطة تقنية. بلا عروض بيع، فقط مهندسون وفريقك.