بيانات الاعتماد والأسرار في Jenkins
بيانات الاعتماد والأسرار في Jenkins
تُعدّ الأسرار أخطر أنواع البيانات في أي منظومة CI/CD. تسريب بيانات اعتماد في سجل بناء، أو مفتاح API مُضمَّن في Jenkinsfile، أو رمز وصول واسع النطاق مشترك بين جميع خطوط الأنابيب — كلها أسباب أفضت إلى اختراقات حقيقية في شركات من مختلف الأحجام. يأتي Jenkins مزوَّدًا بنظام بيانات اعتماد ناضج، غير أن استخدامه بأمان على نطاق المؤسسات يستلزم فهم آلية عمله وأماكن التخزين والأنماط التي تفضي إلى تسريب صامت للبيانات.
مخزن بيانات الاعتماد
يخزِّن Jenkins بيانات الاعتماد في مخزن مشفَّر من نوع مفتاح/قيمة مدعوم بالمكوِّن الإضافي Credentials Plugin (مدمج منذ Jenkins LTS 2.x). يقع مفتاح التشفير الرئيسي في $JENKINS_HOME/secrets/master.key، وتُخزَّن النصوص المشفَّرة لكل بيانات اعتماد في ملفات XML ضمن $JENKINS_HOME/credentials.xml (نطاق عام) أو داخل $JENKINS_HOME/jobs/<name>/config.xml (نطاق مجلد/عنصر).
يعتمد التشفير على طبقتين: يُستخدم المفتاح الرئيسي لاشتقاق مفتاح AES-128 خاص بكل بيانات اعتماد عبر ملف بذرة سري. هذا يعني أن نسخ Jenkins احتياطيًا دون دليل secrets/ يجعل بيانات الاعتماد غير قابلة للاسترداد — وفي المقابل، نسخ credentials.xml وحده دون المفتاح الرئيسي آمنٌ لأن المحتوى مشفَّر.
أنواع بيانات الاعتماد
يشحن Credentials Plugin بأنواع مدمجة متعددة، وتضيف المكوِّنات الإضافية للمؤسسات أنواعًا أخرى:
- اسم مستخدم مع كلمة مرور — الأكثر شيوعًا؛ يُربط بـ
usernameVariableوpasswordVariable. - نص سري — سلسلة نصية معتمة واحدة (رموز API، مفاتيح التوقيع).
- SSH مع مفتاح خاص — يُدخَل المفتاح مباشرةً أو يُحمَّل من مسار ملف على العامل؛ تُخزَّن عبارة المرور منفصلةً.
- شهادة (PKCS#12) — TLS المتبادل وتوقيع الكود. يُربط عبر
KEYSTORE_FILEوKEYSTORE_PASSWORD. - ملف سري — بيانات ثنائية اعتباطية (kubeconfig، مفتاح GCP بصيغة JSON). تتجسَّد كملف مؤقت في مساحة عمل العامل ويحذفه Jenkins بعد اكتمال الخطوة.
- Vault: AppRole / AWS IAM / GCP Workload Identity — توفِّرها مكوِّنات HashiCorp Vault Plugin وAWS Credentials Plugin وغيرها. لا يُخزَّن أي سرٌّ ثابت في Jenkins.
استخدام بيانات الاعتماد في خط أنابيب تصريحي
الطريقة الصحيحة لكشف بيانات الاعتماد داخل خطوة خط أنابيب هي استخدام كتلة withCredentials. يعمل Jenkins تلقائيًا على إخفاء أي متغير مرتبط بهذه الطريقة: إذا ظهرت القيمة الخام في أي سطر سجل، تُستبدَل بـ ****.
echo $SECRET أو sh 'printenv' داخل كتلة withCredentials. يُخفي Jenkins التطابقات الحرفية فقط، لكن أشكال base64 أو URL-encode للسر لا تُخفى. أي تحويل للقيمة الخام قد يُسرِّبها في السجلات دون تنبيه.
نطاقات بيانات الاعتماد عمليًا
يدعم Jenkins ثلاثة نطاقات جوهرية:
- System — متاح لعمليات Jenkins الداخلية فقط (اتصالات العقد، خادم البريد). لا يمكن استخدامه داخل خطوات خط الأنابيب. مخصَّص لبيانات اعتماد البنية التحتية.
- Global (نطاق: Jenkins) — مرئي لجميع المهام على المتحكم. استخدمه فقط لبيانات الاعتماد المشتركة منخفضة القيمة (مثل حساب قراءة فقط على Nexus).
- Folder / Item — الموصى به لأي شيء حساس. بيانات الاعتماد في
/team-payments/غير مرئية للمهام في/team-platform/. هذه هي الضبطة الأساسية لنطاق التأثير في بيئة Jenkins متعددة الفرق.
التكامل مع الخزائن الخارجية
على نطاق واسع، يُعدّ تخزين الأسرار داخل Jenkins نمطًا مضادًا. النهج المقبول في المؤسسات هو التعامل مع Jenkins بوصفه مستهلِكًا لا مخزنًا. تعيش الأسرار في HashiCorp Vault أو AWS Secrets Manager أو Azure Key Vault؛ يسترجعها Jenkins في وقت التشغيل باستخدام رموز قصيرة العمر:
بهذا النمط، لا تُحفظ الأسرار أبدًا في Jenkins: لا XML على القرص، لا صف في قاعدة البيانات، لا config.xml. تُطبِّق Vault سياسات TTL وتسجيل التدقيق والتدوير التلقائي باستقلالية تامة عن Jenkins.
سلوك الإخفاء وحدوده
يعترض إخفاء Jenkins كل عملية println / كتابة سجل ويُجري استبدالًا حرفيًا. افهم حدوده في بيئة الإنتاج:
- الإخفاء يعمل بالقيمة لا بالتسلسل البايتي. سرٌّ مكوَّن من 3 أحرف (
abc) يتطابق تافهيًا مع ضجيج السجل — تجنَّب الأسرار القصيرة. - الأسرار متعددة الأسطر (مفاتيح PEM) تُخفى سطرًا بسطر فقط إذا كان Mask Passwords Plugin نشطًا. الإخفاء المدمج يغطي السلسلة المرتبطة حرفيًا فقط.
- تقارير الاختبارات المُؤرشَفة وملفات JUnit XML وHTML لـ Jacoco وغيرها من القطع الأثرية لا تُخفى أبدًا. يمكن أن يحتوي تتبُّع المكدس على سر مُمرَّر كوسيطة.
- مخرجات وحدة التحكم للعامل المُوجَّهة إلى منظِّمات السجلات الخارجية (Splunk, ELK) تمرّ عبر إخفاء Jenkins قبل الإرسال — لكن فقط إذا كان Pipeline Logging Plugin أو ما يعادله نشطًا في المسار.
تدوير بيانات الاعتماد دون توقف
أأمن استراتيجية للتدوير هي: إنشاء بيانات الاعتماد الجديدة بـمعرِّف جديد، وتحديث جميع مراجع خط الأنابيب في التحكم بالمصدر (تمرّ تغييرات Jenkinsfile عبر مراجعة طلب السحب)، ونشر خطوط الأنابيب المحدَّثة، ثم حذف بيانات الاعتماد القديمة. لا تُلغي بيانات الاعتماد في موضعها خلال تشغيل خط أنابيب نشط — تحتفظ عمليات البناء الجارية بمرجع لمعرِّف بيانات الاعتماد وستقرأ القيمة مجددًا؛ إذا كانت القيمة القديمة غير صالحة الآن، تفشل تلك عمليات البناء في منتصف التنفيذ بطريقة غير حتمية.
قائمة التحقق من مبدأ الحد الأدنى من الصلاحيات
- استخدم بيانات اعتماد ذات نطاق مجلد لكل حد فريق أو مشروع.
- امنح خطوط الأنابيب أضيق نطاق رمز ممكن (رمز نشر للقراءة فقط بدلًا من رمز مدير المستودع).
- فضِّل الأسرار الديناميكية قصيرة العمر من Vault أو IAM السحابي على الرموز الثابتة طويلة العمر.
- لا تطبع ولا تسجِّل الأسرار أبدًا، حتى في كتل catch.
- دوِّر جميع بيانات الاعتماد عند إنهاء عضوية أي مهندس أو عند الاشتباه في اختراق.
- انسخ
$JENKINS_HOME/secrets/احتياطيًا بشكل منفصل، مشفَّرًا، مع تدقيق الوصول.