CI/CD وأمن سلسلة التوريد
Pipeline تسليم آمنة
واجهة API صغيرة بلغة Python تُسلَّم بأسلوب DevSecOps: كل تغيير يُختبر ويُفحص، والصورة تُبنى مرة واحدة وتُوقَّع وتُنشر عبر GitOps، والعنقود لا يشغّل إلا الصور التي وقّعتها هذه الـ pipeline.
نظرة سريعة
- 6
- فحوص أمنية تلقائية
- 0
- مفاتيح توقيع مخزّنة
- 1
- موافقة بشرية للإنتاج
- < 3 د
- من الدمج حتى dev
الهدف
كثير من الهجمات على البرمجيات اليوم لا تكسر التطبيق نفسه، بل طريقة بنائه وتسليمه: رمز وصول مسرّب، أو صورة ملغومة، أو تعديل يدوي في الإنتاج. الهدف: نظام تسليم تكون فيه كل خطوة تلقائية ومفحوصة وقابلة للتتبع، ولا يقبل فيه الإنتاج إلا ما بنته الـ pipeline ووقّعته. التطبيق صغير عن قصد؛ القيمة في نظام التسليم حوله.
ماذا يُظهر المشروع
- التكامل المستمر
- ruff (مع قواعد bandit)، وpytest بحد تغطية 90 %، واختبار تشغيل للحاوية الحقيقية.
- الأمان المبكّر
- gitleaks للأسرار، وSemgrep للكود، وTrivy وkubeconform لملف Dockerfile وملفات Kubernetes.
- سلسلة التوريد
- فحص الصورة بـ Trivy، وSBOM بـ Syft (CycloneDX)، وتوقيع cosign بلا مفاتيح، وإثبات SBOM، وSLSA provenance.
- التسليم
- طبقات Kustomize، والصورة مثبّتة بالـ digest، وArgo CD يزامن dev تلقائيًا، والإنتاج عبر pull request مُراجَع.
- أمان التشغيل
- Pod Security بمستوى restricted، بلا root، ونظام ملفات للقراءة فقط، بلا capabilities، وseccomp، وسياسة شبكة ترفض كل شيء افتراضيًا.
- التحكم في القبول
- Kyverno لا يقبل إلا الصور الموقّعة من هذا المستودع، ولا يقبل إلا pods لها حدود موارد وفحوص صحة.
البنية
تغيير واحد، من المطوّر حتى العنقود. الـ pipeline لا تحصل أبدًا على صلاحيات العنقود: Argo CD يسحب التغيير من Git.
خطوة بخطوة
Pull request
فحص الكود والاختبارات وفحص الأسرار وSAST وفحص IaC تعمل معًا. تُبنى الصورة وتُختبر وتُفحص وتحصل على SBOM. لا يُنشر شيء بعد.
الدمج في main
تعمل الفحوص نفسها مرة أخرى. تُرفع الصورة إلى GHCR بالـ digest، وتُوقَّع بـ cosign (بلا مفاتيح، بهوية GitHub)، وتحصل على إثبات SBOM وSLSA provenance.
النشر إلى dev
تكتب الـ pipeline الـ digest الجديد في طبقة dev. يرى Argo CD الـ commit ويزامن dev تلقائيًا.
الترقية إلى الإنتاج
تفتح الـ pipeline طلب pull request لطبقة prod بالـ digest نفسه. يراجعه شخص ويدمجه: هذا الدمج هو الإصدار. التراجع = git revert.
القبول
قبل تشغيل أي pod، يتحقق Kyverno من التوقيع وهوية الـ pipeline، ومن حدود الموارد وفحوص الصحة. أي شيء آخر يُرفض.
دليل من تشغيل حقيقي
تشغيل على الفرع main بتاريخ 2026-10-27، من GitHub Actions. مدة كل مهمة:
- Lint and unit tests 12s
- Secret scan (gitleaks) 10s
- SAST (semgrep) 33s
- IaC and manifest checks 15s
- Build, scan, SBOM, sign 1m 53s
- Deploy to dev (GitOps commit) 4s
افتح هذا التشغيل (opens in a new tab)
· deploy(dev): shop-api bf471203925f
ضوابط الأمان
| الضابط | ماذا يمنع |
|---|---|
| gitleaks في pre-commit وCI | كلمات المرور ورموز الوصول داخل Git. |
| Semgrep SAST | الحقن والدوال غير الآمنة والتشفير الضعيف في الكود. |
| فحص الصورة بـ Trivy مع حد | تسليم ثغرات حرجة معروفة. |
| Digest بدل tag | صورة مختلفة خلف الوسم نفسه. |
| cosign بلا مفاتيح + Kyverno | صور لم تبنها الـ pipeline ولم توقّعها. |
| GitOps بالسحب | صلاحيات CI مسروقة تصل إلى العنقود. |
| Pods مقيّدة + شبكة ترفض افتراضيًا | الهروب والانتشار من pod مخترق. |
| Actions مثبّتة على commit SHA | Action خارجية تغيّرت داخل الـ pipeline. |
جرّبه بنفسك
make install test # Python 3.12+: lint, tests, 90 % coverage gate
make run # http://127.0.0.1:8080/docs
docker compose up --build # the hardened container: read-only, non-root, no capabilities
make kind-up # local Kubernetes with ingress, Kyverno and Argo CD
# check the signature of a published image (keyless, GitHub OIDC identity)
cosign verify ghcr.io/s0sta/secure-delivery-pipeline@sha256:… \
--certificate-identity-regexp 'https://github.com/s0sta/secure-delivery-pipeline/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comماذا تعلّمت
- الحدود العادلة تُقبل: أوقف البناء أولًا عند النتائج الحرجة الجديدة فقط، ثم ارفع المستوى خطوة بخطوة.
- التوقيع لا قيمة له إلا إذا تحقق منه شيء: السياسة داخل العنقود هي الضابط الحقيقي.
- تشغيل CI حقيقي يكشف ما تفوّته الاختبارات المحلية: إصدار أداة محذوف، أو مسار ناقص، أو إعداد في المستودع.