نظرة عامة
Tekton هو إطار عمل مفتوح المصدر قوي يعمل بشكل أصلي على Kubernetes لإنشاء أنظمة التكامل المستمر والتسليم المستمر (CI/CD). يعمل كمجموعة من تعريفات الموارد المخصصة (CRDs) على أي مجموعة Kubernetes، مما يتيح لك تعريف خطوط الأنابيب كملفات YAML تصريحية قابلة للنقل بين البيئات المختلفة.
Tekton Chains هو مشروع مرافق يضيف أمان سلسلة التوريد تلقائياً إلى خطوط أنابيب Tekton الخاصة بك. بمجرد تثبيته، يراقب Chains عمليات TaskRun المكتملة، ويوقّع نتائجها تلقائياً باستخدام Cosign أو أدوات توقيع أخرى، ويُنشئ شهادات مصدر SLSA — كل ذلك دون الحاجة إلى أي تغييرات في تعريفات خطوط الأنابيب الحالية.
في هذا المختبر العملي، ستقوم بما يلي:
- نشر Tekton Pipelines و Tekton Chains على مجموعة Kubernetes محلية
- تكوين Chains لتوقيع العناصر تلقائياً وإنشاء شهادات مصدر in-toto
- بناء صورة حاوية من خلال Tekton Pipeline
- التحقق من التوقيع وشهادة مصدر SLSA المُنشأة تلقائياً
- إضافة خطوة فحص الثغرات الأمنية إلى خط الأنابيب
- استكشاف التوقيع بدون مفاتيح باستخدام Sigstore Fulcio
- فرض سياسات الصور الموقّعة عند وقت النشر
بنهاية هذا المختبر، سيكون لديك خط أنابيب بناء آمن يعمل بالكامل وينتج صور حاويات موقّعة ومُصدّقة مع مصدر قابل للتحقق — محققاً التوافق مع SLSA Level 2 تلقائياً.
المتطلبات الأساسية
قبل البدء في هذا المختبر، تأكد من تثبيت الأدوات التالية على محطة العمل الخاصة بك:
- مجموعة Kubernetes — سنستخدم kind (Kubernetes in Docker) لإنشاء مجموعة محلية. بدلاً من ذلك، يعمل minikube أيضاً.
- kubectl — واجهة سطر أوامر Kubernetes، الإصدار 1.26 أو أحدث.
- Helm — مدير حزم Kubernetes، الإصدار 3.x.
- tkn — واجهة سطر أوامر Tekton، تُستخدم للتفاعل مع موارد Tekton.
- Cosign — جزء من مشروع Sigstore، يُستخدم لتوقيع صور الحاويات والتحقق منها.
- jq — معالج JSON لسطر الأوامر لفحص حمولات شهادات المصدر.
- سجل حاويات — سجل يمكنك الدفع إليه، مثل GitHub Container Registry (GHCR) أو Docker Hub. ستحتاج إلى صلاحية الكتابة وبيانات اعتماد صالحة.
يفترض هذا المختبر الإلمام بأساسيات Kubernetes (pods، namespaces، configmaps) ومفاهيم CI/CD العامة.
إعداد البيئة
الخطوة 1: إنشاء مجموعة kind
ابدأ بإنشاء مجموعة Kubernetes جديدة باستخدام kind:
kind create cluster --name tekton-lab
kubectl cluster-info --context kind-tekton-lab
تأكد من أن المجموعة تعمل:
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# tekton-lab-control-plane Ready control-plane 30s v1.31.0
الخطوة 2: تثبيت Tekton Pipelines
قم بتثبيت أحدث إصدار من Tekton Pipelines:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
انتظر حتى تصبح pods الخاصة بـ Tekton Pipelines جاهزة:
kubectl get pods -n tekton-pipelines --watch
يجب أن ترى pods tekton-pipelines-controller و tekton-pipelines-webhook تعمل:
NAME READY STATUS RESTARTS AGE
tekton-pipelines-controller-7f6b9b5b95-xk2rj 1/1 Running 0 45s
tekton-pipelines-webhook-6c4f8b7d4f-m9nlp 1/1 Running 0 45s
الخطوة 3: تثبيت Tekton Chains
قم بتثبيت Tekton Chains في مساحة الأسماء الخاصة به:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
تحقق من أن Chains يعمل:
kubectl get pods -n tekton-chains
# NAME READY STATUS RESTARTS AGE
# tekton-chains-controller-5f4b7c8d6f-r7t2x 1/1 Running 0 30s
في هذه المرحلة، كل من Tekton Pipelines و Tekton Chains يعملان على مجموعتك.
التمرين 1: تكوين Tekton Chains للتوقيع باستخدام Cosign
يحتاج Tekton Chains إلى مفتاح توقيع وتكوين لمعرفة كيفية ومكان تخزين التوقيعات والشهادات. في هذا التمرين، ستقوم بإنشاء زوج مفاتيح Cosign وتكوين Chains لاستخدام تخزين OCI مع تنسيق شهادات in-toto.
إنشاء زوج مفاتيح Cosign
يمكن لـ Cosign إنشاء زوج مفاتيح وتخزينه مباشرة كـ Kubernetes Secret في مساحة الأسماء tekton-chains:
cosign generate-key-pair k8s://tekton-chains/signing-secrets
سيُطلب منك إدخال كلمة مرور للمفتاح الخاص. في هذا المختبر، يمكنك الضغط على Enter لتركها فارغة. ينشئ Cosign سراً باسم signing-secrets يحتوي على المفتاح الخاص والمفتاح العام وكلمة المرور.
تحقق من إنشاء السر:
kubectl get secret signing-secrets -n tekton-chains
# NAME TYPE DATA AGE
# signing-secrets Opaque 3 10s
تكوين تخزين وتنسيق Chains
بعد ذلك، قم بتكوين Chains لتخزين التوقيعات في سجل OCI بجانب الصورة ولإنشاء شهادات المصدر بتنسيق in-toto:
kubectl patch configmap chains-config -n tekton-chains \
-p='{"data":{"artifacts.oci.storage":"oci","artifacts.taskrun.format":"in-toto","artifacts.taskrun.storage":"oci"}}'
يخبر هذا التكوين Chains بما يلي:
- artifacts.oci.storage: oci — تخزين توقيعات عناصر OCI في سجل OCI
- artifacts.taskrun.format: in-toto — إنشاء الشهادات بتنسيق in-toto، وهو المعيار لشهادات مصدر SLSA
- artifacts.taskrun.storage: oci — تخزين شهادات TaskRun في سجل OCI
إعادة تشغيل وحدة تحكم Chains
بعد تغيير التكوين، أعد تشغيل وحدة تحكم Chains لتطبيق الإعدادات الجديدة:
kubectl rollout restart deployment tekton-chains-controller -n tekton-chains
kubectl rollout status deployment tekton-chains-controller -n tekton-chains
كيف يعمل Chains
مع تكوين Chains، إليك ما يحدث تلقائياً عند اكتمال أي TaskRun:
- تكتشف وحدة تحكم Chains عملية TaskRun المكتملة.
- تفحص نتائج TaskRun بحثاً عن مراجع صور OCI (تحديداً النتائج المسماة
IMAGE_URLوIMAGE_DIGEST). - توقّع الصورة باستخدام مفتاح Cosign المخزن في السر
signing-secrets. - تُنشئ شهادة مصدر in-toto تلتقط تفاصيل البناء.
- تدفع التوقيع والشهادة إلى سجل OCI.
- تُضيف تعليقاً توضيحياً على TaskRun بقيمة
chains.tekton.dev/signed=true.
لا يتطلب أي من هذا أي تعديل على المهام أو خطوط الأنابيب الخاصة بك.
التمرين 2: إنشاء خط أنابيب البناء
الآن ستقوم بإنشاء Tekton Pipeline يستنسخ مستودع Git ويبني صورة حاوية باستخدام Kaniko. أولاً، قم بإعداد بيانات اعتماد السجل حتى يتمكن Tekton من دفع الصور.
تكوين بيانات اعتماد السجل
أنشئ Kubernetes Secret ببيانات اعتماد السجل الخاصة بك. استبدل القيم المؤقتة بتفاصيل السجل الفعلية:
export REGISTRY_SERVER=ghcr.io
export REGISTRY_USER=your-username
export REGISTRY_PASSWORD=your-token
kubectl create secret docker-registry registry-credentials \
--docker-server=$REGISTRY_SERVER \
--docker-username=$REGISTRY_USER \
--docker-password=$REGISTRY_PASSWORD
kubectl patch serviceaccount default -p '{"secrets": [{"name": "registry-credentials"}]}'
إنشاء مهمة البناء
أنشئ ملفاً باسم build-task.yaml. تقبل هذه المهمة عنوان URL لمستودع Git واسم صورة مستهدفة وتستخدم Kaniko لبناء الصورة ودفعها:
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: git-clone-and-build
spec:
params:
- name: repo-url
type: string
description: The Git repository URL to clone
- name: image
type: string
description: The image reference to build and push (e.g., ghcr.io/user/app:tag)
results:
- name: IMAGE_URL
description: The image URL that was built
- name: IMAGE_DIGEST
description: The digest of the built image
workspaces:
- name: source
steps:
- name: clone
image: alpine/git:2.43.0
script: |
#!/usr/bin/env sh
set -eu
git clone $(params.repo-url) $(workspaces.source.path)/src
echo "Repository cloned successfully"
- name: build-and-push
image: gcr.io/kaniko-project/executor:latest
args:
- --dockerfile=$(workspaces.source.path)/src/Dockerfile
- --context=$(workspaces.source.path)/src
- --destination=$(params.image)
- --digest-file=$(results.IMAGE_DIGEST.path)
securityContext:
runAsUser: 0
- name: write-url
image: alpine:3.19
script: |
#!/usr/bin/env sh
set -eu
echo -n "$(params.image)" > "$(results.IMAGE_URL.path)"
echo "Image URL written: $(params.image)"
طبّق المهمة:
kubectl apply -f build-task.yaml
إنشاء مهمة فحص الثغرات الأمنية (للاستخدام لاحقاً)
أنشئ vuln-scan-task.yaml — ستضيف هذا إلى خط الأنابيب في تمرين لاحق:
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: vulnerability-scan
spec:
params:
- name: image
type: string
description: The image reference to scan
steps:
- name: scan
image: anchore/grype:latest
args:
- $(params.image)
- --fail-on
- critical
- --output
- table
إنشاء خط الأنابيب
أنشئ build-pipeline.yaml الذي يربط خطوات الاستنساخ والبناء:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: secure-build
spec:
params:
- name: repo-url
type: string
- name: image
type: string
workspaces:
- name: shared-workspace
tasks:
- name: build
taskRef:
name: git-clone-and-build
params:
- name: repo-url
value: $(params.repo-url)
- name: image
value: $(params.image)
workspaces:
- name: source
workspace: shared-workspace
طبّق خط الأنابيب:
kubectl apply -f build-pipeline.yaml
تشغيل خط الأنابيب
أنشئ PipelineRun لتنفيذ خط الأنابيب. استبدل مرجع الصورة بسجلك:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: secure-build-run-
spec:
pipelineRef:
name: secure-build
params:
- name: repo-url
value: "https://github.com/GoogleContainerTools/kaniko.git"
- name: image
value: "ghcr.io/your-username/tekton-lab:v1"
workspaces:
- name: shared-workspace
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
احفظ هذا باسم pipelinerun.yaml وأنشئه:
kubectl create -f pipelinerun.yaml
راقب تنفيذ خط الأنابيب:
tkn pipelinerun logs -f --last
# [build : clone] Cloning into '/workspace/source/src'...
# [build : clone] Repository cloned successfully
# [build : build-and-push] INFO[0001] Resolved base image golang:1.22
# [build : build-and-push] ...
# [build : build-and-push] INFO[0045] Pushing image to ghcr.io/your-username/tekton-lab:v1
# [build : write-url] Image URL written: ghcr.io/your-username/tekton-lab:v1
يجب أن يكتمل البناء بنجاح. يمكنك أيضاً التحقق من حالة PipelineRun:
tkn pipelinerun list
# NAME STARTED DURATION STATUS
# secure-build-run-x7k2p 1 minute ago 1m 15s Succeeded
التمرين 3: التحقق من التوقيع التلقائي
بمجرد اكتمال PipelineRun، يكتشف Tekton Chains تلقائياً عملية TaskRun المكتملة، ويوقّع الصورة المبنية، ويُضيف تعليقات توضيحية على TaskRun. كل هذا يحدث في الخلفية — دون الحاجة إلى تغييرات في خط الأنابيب.
انتظار توقيع Chains
يعالج Chains عمليات TaskRun المكتملة بشكل غير متزامن. انتظر بضع لحظات، ثم تحقق من تعليقات TaskRun التوضيحية:
# Get the TaskRun name from the PipelineRun
TASKRUN=$(kubectl get taskrun -l tekton.dev/pipeline=secure-build -o name --sort-by=.metadata.creationTimestamp | tail -1)
echo $TASKRUN
# Check if Chains has signed it
kubectl get $TASKRUN -o jsonpath='{.metadata.annotations.chains\.tekton\.dev/signed}'
يجب أن يكون الناتج:
true
إذا كان لا يزال فارغاً، انتظر بضع ثوانٍ وحاول مرة أخرى — يحتاج Chains وقتاً لمعالجة التوقيع.
التحقق من التوقيع باستخدام Cosign
الآن تحقق من توقيع الصورة باستخدام المفتاح العام من زوج مفاتيح Cosign الذي أنشأته سابقاً:
cosign verify \
--key k8s://tekton-chains/signing-secrets \
ghcr.io/your-username/tekton-lab:v1
يجب أن ترى ناتجاً يؤكد نجاح التحقق:
Verification for ghcr.io/your-username/tekton-lab:v1 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[{"critical":{"identity":{"docker-reference":"ghcr.io/your-username/tekton-lab"},"image":{"docker-manifest-digest":"sha256:abc123..."},"type":"cosign container image signature"},"optional":{}}]
فحص تعليقات TaskRun التوضيحية
يُضيف Chains تعليقات توضيحية غنية على TaskRun حول عملية التوقيع:
kubectl get $TASKRUN -o jsonpath='{.metadata.annotations}' | jq .
تشمل التعليقات التوضيحية الرئيسية:
{
"chains.tekton.dev/signed": "true",
"chains.tekton.dev/transparency": "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=...",
"chains.tekton.dev/signature-taskrun-...": "..."
}
يؤكد التعليق التوضيحي chains.tekton.dev/signed=true أن Chains عالج ووقّع هذا TaskRun بنجاح. إذا تم تكوين سجل الشفافية، سترى أيضاً مرجع إدخال سجل Rekor.
التمرين 4: فحص شهادة مصدر SLSA
بالإضافة إلى التوقيعات البسيطة، يُنشئ Tekton Chains شهادات مصدر SLSA كاملة. تصف هذه الشهادات كيف تم بناء العنصر — أي مصدر تم استخدامه، وما هي خطوات البناء التي نُفّذت، وما هي الأدوات المستخدمة.
جلب شهادة المصدر
استخدم Cosign للتحقق من شهادة in-toto واسترجاعها:
cosign verify-attestation \
--key k8s://tekton-chains/signing-secrets \
--type slsaprovenance \
ghcr.io/your-username/tekton-lab:v1 | jq -r '.payload' | base64 -d | jq .
فهم هيكل شهادة المصدر
تتبع شهادة المصدر تنسيق بيان in-toto مع مُسند SLSA Provenance. فيما يلي شرح للحقول الرئيسية:
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
"name": "ghcr.io/your-username/tekton-lab",
"digest": {
"sha256": "abc123def456..."
}
}
],
"predicate": {
"builder": {
"id": "https://tekton.dev/chains/v2"
},
"buildType": "tekton.dev/v1beta1/TaskRun",
"invocation": {
"configSource": {},
"parameters": {
"repo-url": "https://github.com/GoogleContainerTools/kaniko.git",
"image": "ghcr.io/your-username/tekton-lab:v1"
}
},
"buildConfig": {
"steps": [
{
"entryPoint": "...",
"arguments": null,
"environment": {
"container": "clone",
"image": "alpine/git:2.43.0@sha256:..."
}
},
{
"entryPoint": "...",
"environment": {
"container": "build-and-push",
"image": "gcr.io/kaniko-project/executor:latest@sha256:..."
}
}
]
},
"materials": [
{
"uri": "oci://alpine/git:2.43.0",
"digest": { "sha256": "..." }
},
{
"uri": "oci://gcr.io/kaniko-project/executor:latest",
"digest": { "sha256": "..." }
}
]
}
}
دعونا نستعرض كل حقل:
- subject — العنصر الذي تم إنتاجه، مُعرَّف بعنوان URL الخاص بالسجل وملخص SHA-256. هذا هو ما تتعلق به شهادة المصدر.
- builder.id — يُحدد نظام البناء. يُعيّن Tekton Chains هذا إلى
https://tekton.dev/chains/v2. - buildConfig.steps — يُسجل كل خطوة نُفّذت في TaskRun، بما في ذلك صور الحاويات الدقيقة المستخدمة (مثبتة بالملخص).
- materials — يُدرج عناصر الإدخال المستهلكة أثناء البناء، مثل الصور الأساسية. يتضمن كل عنصر ملخصاً لضمان قابلية التكرار.
- invocation.parameters — يلتقط المعاملات الممررة إلى TaskRun، مُظهراً بالضبط المدخلات التي قادت عملية البناء.
تفي بيانات شهادة المصدر هذه بمتطلبات SLSA Level 2: يتم تعريف عملية البناء في خدمة بناء (Tekton)، ويتم إنشاء شهادة المصدر تلقائياً بواسطة Tekton Chains (وليس بواسطة سكريبت البناء نفسه). شهادة المصدر موقّعة، مما يوفر دليلاً على عدم التلاعب.
التمرين 5: إضافة مهمة فحص الثغرات الأمنية
يجب ألا يقتصر خط الأنابيب الآمن على توقيع العناصر فحسب، بل يجب أيضاً التحقق من خلوها من الثغرات الأمنية المعروفة قبل النشر. في هذا التمرين، ستضيف خطوة فحص ثغرات Grype إلى خط الأنابيب.
تطبيق مهمة الفحص
طبّق مهمة فحص الثغرات الأمنية التي أنشأتها سابقاً:
kubectl apply -f vuln-scan-task.yaml
تحديث خط الأنابيب
حدّث build-pipeline.yaml لتضمين فحص الثغرات الأمنية بعد خطوة البناء:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: secure-build
spec:
params:
- name: repo-url
type: string
- name: image
type: string
workspaces:
- name: shared-workspace
tasks:
- name: build
taskRef:
name: git-clone-and-build
params:
- name: repo-url
value: $(params.repo-url)
- name: image
value: $(params.image)
workspaces:
- name: source
workspace: shared-workspace
- name: vulnerability-scan
runAfter:
- build
taskRef:
name: vulnerability-scan
params:
- name: image
value: $(params.image)
طبّق خط الأنابيب المُحدّث:
kubectl apply -f build-pipeline.yaml
الاختبار بصورة تحتوي على ثغرات
لتوضيح كيفية اكتشاف الفحص للثغرات، أنشئ Dockerfile يستخدم صورة أساسية معروفة بوجود ثغرات فيها وادفع مستودعاً أو عدّل المعاملات وفقاً لذلك. إذا احتوت الصورة على ثغرات حرجة، سيُفشل Grype الخطوة:
tkn pipelinerun logs -f --last
# [vulnerability-scan : scan] NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
# [vulnerability-scan : scan] libcrypto3 3.0.12 3.0.13 apk CVE-2024-0727 Critical
# [vulnerability-scan : scan] 1 critical vulnerability found
# [vulnerability-scan : scan] ERROR: failed to pass severity threshold
#
# TaskRun failed: step "scan" exited with code 1
يفشل خط الأنابيب بشكل صحيح عند خطوة الفحص، مما يمنع ترقية صورة تحتوي على ثغرات.
الاختبار بصورة مُحدّثة
الآن شغّل خط الأنابيب على مستودع يحتوي على صورة أساسية محدّثة. عندما لا يتم العثور على ثغرات حرجة، ينجح الفحص:
tkn pipelinerun logs -f --last
# [vulnerability-scan : scan] No critical vulnerabilities found
# PipelineRun completed successfully
تدفق خط الأنابيب الآن هو: git-clone ← build-push ← vulnerability-scan. فقط الصور التي تجتاز فحص الثغرات يتم توقيعها بواسطة Tekton Chains، لأن Chains يعالج فقط عمليات TaskRun الناجحة.
التمرين 6: التوقيع بدون مفاتيح باستخدام Fulcio (متقدم)
تُدخل إدارة مفاتيح التوقيع طويلة العمر تعقيداً تشغيلياً ومخاطر أمنية. يوفر Fulcio من Sigstore توقيعاً بدون مفاتيح عن طريق إصدار شهادات قصيرة العمر مرتبطة بهوية OIDC. في هذا التمرين، ستقوم بتكوين Tekton Chains لاستخدام التوقيع بدون مفاتيح.
تحديث تكوين Chains
عدّل تكوين Chains لتمكين التوقيع بدون مفاتيح:
kubectl patch configmap chains-config -n tekton-chains -p='{"data":{
"signers.x509.fulcio.enabled": "true",
"signers.x509.fulcio.address": "https://fulcio.sigstore.dev",
"transparency.enabled": "true",
"transparency.url": "https://rekor.sigstore.dev"
}}'
تحتاج أيضاً إلى حذف أو إعادة تسمية السر signing-secrets الحالي حتى يعود Chains إلى وضع التوقيع بدون مفاتيح:
kubectl delete secret signing-secrets -n tekton-chains
أعد تشغيل وحدة تحكم Chains:
kubectl rollout restart deployment tekton-chains-controller -n tekton-chains
تكوين OIDC لـ Chains
يحتاج Chains إلى رمز OIDC للمصادقة مع Fulcio. على خدمة Kubernetes مُدارة (GKE، EKS، AKS)، يمكنك استخدام هوية عبء العمل. لمجموعة kind محلية، يمكنك تكوين Spiffe/SPIRE أو استخدام موفر OIDC محيط. توفر وثائق Tekton Chains تعليمات الإعداد لكل بيئة.
لإعداد إنتاجي على GKE، يتم ربط حساب الخدمة تلقائياً:
# Example: GKE workload identity binding
gcloud iam service-accounts add-iam-policy-binding \
tekton-chains-sa@your-project.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:your-project.svc.id.goog[tekton-chains/tekton-chains-controller]"
تشغيل خط الأنابيب مع التوقيع بدون مفاتيح
أطلق PipelineRun جديداً:
kubectl create -f pipelinerun.yaml
بعد الاكتمال، تحقق باستخدام التحقق بدون مفاتيح عن طريق تحديد الهوية المتوقعة ومُصدر OIDC:
cosign verify \
--certificate-identity "https://kubernetes.io/namespaces/tekton-chains/serviceaccounts/tekton-chains-controller" \
--certificate-oidc-issuer "https://your-oidc-issuer" \
ghcr.io/your-username/tekton-lab:v2
يعتمد التحقق الآن على سلسلة الشهادات من Fulcio بدلاً من زوج مفاتيح ثابت. يُلغي هذا النهج إدارة المفاتيح بالكامل: تحصل كل عملية توقيع على شهادة جديدة قصيرة العمر، ويتم تسجيل حدث التوقيع في سجل شفافية Rekor لأغراض التدقيق.
التمرين 7: فرض الصور الموقّعة عند النشر
توقيع الصور يكون مفيداً فقط إذا فرضت التحقق من التوقيع عند وقت النشر. في هذا التمرين، ستنشر Sigstore policy-controller لرفض أي صورة حاوية تفتقر إلى توقيع Tekton Chains صالح.
تثبيت Sigstore Policy Controller
helm repo add sigstore https://sigstore.github.io/helm-charts
helm repo update
helm install policy-controller sigstore/policy-controller \
--namespace cosign-system \
--create-namespace \
--set webhook.configMapName=policy-controller-config
انتظر حتى يصبح policy controller جاهزاً:
kubectl get pods -n cosign-system --watch
إنشاء سياسة الصور
أنشئ ClusterImagePolicy تتطلب توقيع الصور بمفتاح Tekton Chains الخاص بك. احفظ هذا باسم image-policy.yaml:
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: tekton-chains-signed
spec:
images:
- glob: "ghcr.io/your-username/**"
authorities:
- key:
data: |
-----BEGIN PUBLIC KEY-----
YOUR_COSIGN_PUBLIC_KEY_HERE
-----END PUBLIC KEY-----
attestations:
- name: must-have-slsa-provenance
predicateType: "https://slsa.dev/provenance/v0.2"
policy:
type: cue
data: |
predicateType: "https://slsa.dev/provenance/v0.2"
استبدل المفتاح العام بمفتاح Cosign العام الذي أنشأته سابقاً:
# Extract the public key
kubectl get secret signing-secrets -n tekton-chains -o jsonpath='{.data.cosign\.pub}' | base64 -d
طبّق السياسة:
kubectl apply -f image-policy.yaml
فرض السياسة على مساحة أسماء
ضع تسمية على مساحة أسماء لتمكين فرض السياسة:
kubectl create namespace secure-apps
kubectl label namespace secure-apps policy.sigstore.dev/include=true
اختبار: نشر صورة موقّعة
انشر الصورة التي تم توقيعها بواسطة Tekton Chains:
kubectl run signed-app \
--image=ghcr.io/your-username/tekton-lab:v1 \
--namespace=secure-apps
# pod/signed-app created
ينجح النشر لأن الصورة تحتوي على توقيع صالح وشهادة مصدر.
اختبار: نشر صورة غير موقّعة
الآن حاول نشر صورة لم يتم توقيعها:
kubectl run unsigned-app \
--image=ghcr.io/your-username/unsigned-image:latest \
--namespace=secure-apps
# Error from server (BadRequest): admission webhook "policy.sigstore.dev" denied the request:
# validation failed: failed policy: tekton-chains-signed:
# spec.containers[0].image ghcr.io/your-username/unsigned-image:latest
# signature key validation failed for authority
يرفض webhook القبول الصورة غير الموقّعة بشكل صحيح. هذا يُغلق الحلقة: يتم توقيع الصور تلقائياً أثناء البناء، ولا يمكن نشر سوى الصور الموقّعة.
التنظيف
عند الانتهاء من المختبر، نظّف الموارد:
# Delete Tekton Chains
kubectl delete -f https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
# Delete Tekton Pipelines
kubectl delete -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# Delete the policy controller
helm uninstall policy-controller -n cosign-system
kubectl delete namespace cosign-system
# Delete the kind cluster
kind delete cluster --name tekton-lab
النقاط الرئيسية
- يوفر Tekton Chains أمان سلسلة التوريد بدون تكوين إضافي. بمجرد تثبيته وتكوينه، يوقّع تلقائياً كل نتيجة TaskRun ويُنشئ شهادة مصدر SLSA — دون الحاجة إلى تعديلات في خط الأنابيب.
- تربط شهادة مصدر SLSA العناصر بعملية بنائها. تُسجل شهادة in-toto بالضبط أي مصدر وخطوات وأدوات أنتجت العنصر، مما يُنشئ سلسلة حفظ قابلة للتدقيق.
- التحقق باستخدام Cosign بسيط ومباشر. أمر واحد يتحقق من أن الصورة تم توقيعها بواسطة نسخة Tekton Chains الخاصة بك ولم يتم التلاعب بها منذ ذلك الحين.
- التوقيع بدون مفاتيح يُلغي إدارة المفاتيح. من خلال التكامل مع Fulcio و Rekor، يمكنك توقيع العناصر بشهادات قصيرة العمر مرتبطة بهوية عبء العمل، مما يُزيل عبء تدوير وتأمين المفاتيح طويلة العمر.
- فحص الثغرات الأمنية كبوابة في خط الأنابيب يمنع عمليات النشر غير الآمنة. إضافة Grype أو ماسح مشابه كخطوة في خط الأنابيب يضمن أن الصور الخالية من الثغرات الحرجة فقط تنتقل إلى التوقيع والنشر.
- التحكم في القبول يفرض السياسة. استخدام Sigstore policy-controller كـ Kubernetes admission webhook يضمن أن الصور الموقّعة والمُصدّقة بشكل صحيح فقط يمكن تشغيلها في مجموعتك، مما يُغلق حلقة الأمان من البناء إلى النشر.
الخطوات التالية
واصل تعزيز معرفتك بأمان سلسلة التوريد مع هذه الأدلة ذات الصلة:
- شهادات مصدر العناصر: من SLSA إلى in-toto — تعمق في إطار عمل SLSA ومستويات المصدر ومواصفات شهادات in-toto.
- توقيع صور الحاويات والتحقق منها باستخدام Sigstore و Cosign — دليل شامل حول Cosign و Fulcio و Rekor لتوقيع صور الحاويات والتحقق منها.