Supply Chain Security #
Serangan supply chain terhadap container image semakin umum — mulai dari library yang terkompromi, base image yang mengandung malware, hingga image yang dipalsukan di registry publik. Sebelum image berjalan di cluster production, ada beberapa lapisan verifikasi yang perlu dilakukan: scan vulnerability, verifikasi signature, dan policy enforcement yang mencegah image tidak dikenal masuk ke cluster.
Ancaman Supply Chain #
Vektor serangan supply chain yang umum:
1. Vulnerable base image
FROM ubuntu:20.04 ← mungkin mengandung CVE yang belum di-patch
→ Semua image turunannya mewarisi vulnerability
2. Dependency yang dikompromis
RUN pip install malicious-package-renamed-as-legit==1.0.0
→ Typosquatting atau compromised package di PyPI/npm/etc
3. Image yang dipalsukan di registry publik
my-app:latest ← mungkin bukan dari source yang kamu kira
→ Tanpa signature verification, tidak ada yang bisa dipercaya
4. Build pipeline yang dikompromis
CI/CD yang di-compromise bisa inject kode berbahaya
sebelum atau saat image di-build
5. Registry credentials yang bocor
→ Penyerang push image berbahaya ke registry private
Image Scanning dengan Trivy #
Trivy adalah scanner vulnerability yang bisa di-integrate ke CI/CD pipeline:
# Scan image sebelum push ke registry
trivy image my-api:v2
# Output:
# my-api:v2 (debian 12.4)
# ===========================
# Total: 12 (CRITICAL: 2, HIGH: 5, MEDIUM: 3, LOW: 2)
#
# ┌──────────────────┬────────────┬──────────┬──────────────────────┐
# │ Library │ CVE │ Severity │ Fixed Version │
# ├──────────────────┼────────────┼──────────┼──────────────────────┤
# │ libssl1.1 │ CVE-2023-X │ CRITICAL │ 1.1.1w │
# │ openssl │ CVE-2023-Y │ CRITICAL │ 3.0.8 │
# Fail build jika ada CRITICAL vulnerability
trivy image --exit-code 1 --severity CRITICAL my-api:v2
# Scan di GitHub Actions
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: my-api:${{ github.sha }}
format: sarif
exit-code: '1'
severity: 'CRITICAL,HIGH'
Image Signing dengan Cosign #
Cosign memungkinkan kamu menandatangani container image sehingga cluster bisa memverifikasi bahwa image benar-benar dari pipeline yang tepercaya.
# Generate keypair
cosign generate-key-pair
# Menghasilkan: cosign.key (private) dan cosign.pub (public)
# Sign image setelah di-push ke registry (di CI/CD)
cosign sign --key cosign.key my-registry.io/my-api:v2@sha256:abc123...
# Verify signature sebelum deploy
cosign verify --key cosign.pub my-registry.io/my-api:v2
# Keyless signing dengan OIDC (GitHub Actions, tidak perlu manage key)
cosign sign --yes my-registry.io/my-api:v2
# Signature tersimpan di transparency log (Rekor)
Policy Enforcement dengan Kyverno #
Kyverno adalah admission controller yang bisa enforce berbagai policy keamanan, termasuk memastikan semua image sudah di-sign:
# Policy: tolak image dari registry tidak dikenal
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: Enforce # Enforce = tolak, Audit = hanya log
background: true
rules:
- name: validate-registries
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "Image harus dari registry resmi perusahaan"
pattern:
spec:
containers:
- image: "registry.company.com/*"
# atau gunakan =(containers) untuk all containers including initContainers
# Policy: verifikasi image signature dengan Cosign
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: verify-cosign-signature
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences:
- "registry.company.com/*"
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----
Software Bill of Materials (SBOM) #
SBOM adalah daftar lengkap semua komponen yang ada dalam sebuah image — library, framework, dan dependencies. Ini memungkinkan audit cepat saat vulnerability baru ditemukan.
# Generate SBOM untuk image
syft my-api:v2 -o cyclonedx-json > sbom.json
# atau:
trivy image --format cyclonedx my-api:v2 > sbom.json
# Attach SBOM ke image sebagai attestation
cosign attest --key cosign.key \
--predicate sbom.json \
--type cyclonedx \
my-registry.io/my-api:v2
# Cek SBOM library tertentu dari image
syft packages my-api:v2 | grep "openssl"
Private Registry dan Pull Secret #
Selalu gunakan private registry untuk image production. Jangan andalkan public registry tanpa kontrol:
# Buat pull secret
kubectl create secret docker-registry registry-credentials \
--docker-server=registry.company.com \
--docker-username=ci-user \
--docker-password=<token> \
-n production
# Gunakan di Deployment
spec:
imagePullSecrets:
- name: registry-credentials
containers:
- name: api
image: registry.company.com/my-api:v2
# Best practice: attach pull secret ke ServiceAccount
# Semua Pod yang pakai ServiceAccount ini otomatis bisa pull
apiVersion: v1
kind: ServiceAccount
metadata:
name: api-service-account
namespace: production
imagePullSecrets:
- name: registry-credentials
Praktik Registry yang Aman #
1. Immutable tags
Aktifkan immutable tag di registry (ECR, GCR, Harbor)
→ Tag yang sudah di-push tidak bisa di-overwrite
→ my-api:v2.1.0 selalu menunjuk ke image yang sama
2. Content trust dan DCR
Enable Docker Content Trust di registry
Atau gunakan Cosign untuk signing yang lebih modern
3. Scan otomatis di registry
ECR, GCR, Harbor punya scan vulnerability bawaan
Aktifkan dan set alert untuk CRITICAL findings
4. Retain policy
Hapus image lama secara otomatis
Hanya simpan N versi terakhir
Image lama = surface area untuk vulnerability lama
5. Minimal base image
Gunakan distroless atau alpine sebagai base
FROM gcr.io/distroless/python3-debian12
→ Tidak ada shell, tidak ada package manager di image final
→ Sangat sulit bagi penyerang untuk install tools setelah masuk
Ringkasan #
- Scan setiap image di CI sebelum push — Trivy terintegrasi dengan GitHub Actions, GitLab CI, dan semua CI/CD populer; fail build jika ada CRITICAL CVE.
- Sign image dengan Cosign setelah build — signature membuktikan image dari pipeline yang tepercaya; cluster bisa verify sebelum menjalankan.
- Kyverno untuk enforce image policy — blokir image dari registry tidak dikenal dan pastikan semua image sudah di-sign sebelum masuk ke cluster.
- SBOM untuk audit dependency — daftar lengkap komponen memungkinkan identifikasi cepat saat zero-day vulnerability baru ditemukan.
- Immutable tags di registry — tag yang tidak bisa di-overwrite memastikan
my-api:v2.1.0selalu merujuk ke image yang sama.- Distroless atau Alpine sebagai base image — minimal base image mengurangi attack surface; tidak ada shell dan package manager = sangat sulit dieksploitasi.