
Hari 36: OPA Policy Testing — Deny vs Allow
Test Gatekeeper policy: Pod tanpa resources ditolak (4 violations), Pod dengan resources diterima. Surprise: K8s auto-fill requests dari limits sebelum webhook dipanggil.
Hari 35 kemarin tulis Rego policy — 4 violation rules, enforcementAction: deny, 0 violations. Tapi apakah policy-nya beneran bekerja? Hari ini test dengan 3 skenario: Pod tanpa resources, Pod dengan full resources, dan Pod dengan partial resources.
Test 1: Pod Tanpa Resources — DENIED
Deploy Pod sederhana tanpa resources block di namespace securebank:
# Before: Pod tanpa resources
apiVersion: v1
kind: Pod
metadata:
name: test-no-limits
namespace: securebank
spec:
containers:
- name: nginx
image: nginx:latest
# NO resources defined
$ kubectl apply -f test-no-limits.yaml
Error from server (Forbidden): error when creating "test-no-limits.yaml":
admission webhook "validation.gatekeeper.sh" denied the request:
[require-resource-limits] Container 'nginx' has no CPU limit
[require-resource-limits] Container 'nginx' has no CPU request
[require-resource-limits] Container 'nginx' has no memory limit
[require-resource-limits] Container 'nginx' has no memory request
DITOLAK. 4 violation messages — sesuai dengan 4 violation rules di Rego policy. Gatekeeper mengevaluasi semua rules dan mengumpulkan semua violations dalam satu response. Developer bisa lihat semua masalah sekaligus, bukan fix satu-satu.
Test 2: Pod Dengan Full Resources — ACCEPTED
Tambahkan resources block lengkap (limits + requests):
# After: Pod dengan full resources
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
$ kubectl apply -f test-with-limits.yaml
pod/test-with-limits created # DITERIMA
Policy pass. Pod dengan full resources diterima tanpa masalah.
Test 3: Pod Dengan Partial Resources — ACCEPTED (Surprise!)
Hanya defini limits, tanpa requests:
resources:
limits:
cpu: 200m
memory: 128Mi
# NO requests defined — expect DITOLAK?
$ kubectl apply -f test-partial-limits.yaml
pod/test-partial-limits created # DITERIMA!
Kenapa diterima? Kubernetes otomatis mengisi requests = limits jika requests tidak ditentukan. Setelah Pod dibuat, kubectl get pod -o yaml menunjukkan:
# Before (YAML original):
resources:
limits:
cpu: 200m
memory: 128Mi
# NO requests
# After (K8s auto-fill):
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 200m # K8s auto-fill dari limits
memory: 128Mi # K8s auto-fill dari limits
Gatekeeper mengevaluasi admission request dari API Server — dan API Server sudah auto-fill requests sebelum webhook dipanggil. Jadi dari POV Gatekeeper, requests sudah ada. Bukan bug di policy, ini Kubernetes default behavior.
Test Results: Before vs After
| # | Test | Resources | Expected | Actual | Result |
|---|---|---|---|---|---|
| 1 | test-no-limits | none | DENIED | DENIED | ✅ Match |
| 2 | test-with-limits | full (limits + requests) | ACCEPTED | ACCEPTED | ✅ Match |
| 3 | test-partial-limits | limits only | DENIED | ACCEPTED | ⚠️ K8s auto-fill |
| 4 | deployment.yaml | full (Day 33) | ACCEPTED | ACCEPTED | ✅ Match |
Gatekeeper Evaluation Flow
Test 1: kubectl apply (no resources)
→ API Server → K8s defaulting (nothing to fill) → Gatekeeper webhook
→ 4 violations → DENY ✅
Test 2: kubectl apply (full resources)
→ API Server → K8s defaulting (nothing to fill) → Gatekeeper webhook
→ 0 violations → ALLOW ✅
Test 3: kubectl apply (limits only)
→ API Server → K8s defaulting (auto-fill requests = limits) → Gatekeeper webhook
→ 0 violations (requests already filled) → ALLOW ✅ (surprise but correct)
Pelajaran Hari Ini
Gatekeeper webhook dipanggil SETELAH K8s defaulting. Kubernetes auto-fill requests = limits kalau requests tidak ditentukan. Gatekeeper melihat Pod yang sudah di-default, bukan YAML original. Untuk mencegah auto-fill, perlu ValidatingAdmissionPolicy (K8s 1.30+) yang dipanggil sebelum defaulting.
4 violation messages dalam satu response. Gatekeeper mengumpulkan semua violations dari semua rules, bukan stop di rule pertama. Developer dapat lihat semua masalah sekaligus — lebih efficient.
Testing = discovery. Kalau tidak test skenario partial resources, kita tidak akan tahu K8s auto-fill behavior. Testing membuktikan assumption — dan kadang assumption salah.
Policy enforcement works. Pod tanpa resources = ditolak sebelum masuk cluster. Scanner (Checkov/Trivy) melaporkan, Gatekeeper mencegah.
Repo
Semua code dan dokumentasi ada di: https://github.com/stayrelevantid/chalange-devsecops
Kesimpulan
Gatekeeper policy confirmed working. Pod tanpa resources = ditolak dengan 4 violation messages. Pod dengan resources = diterima. Discovery menarik: K8s auto-fill requests = limits sebelum webhook dipanggil — bukan bug, itu default behavior. Besok Day 37 — Network Policies, default deny all + whitelist traffic.
Diskusi & Komentar
Artikel Terkait
Hari 20: Terraform + Checkov, 15 Celah IaC Ketahuan
Bikin infrastructure as code pakai Terraform, lalu scan dengan Checkov. Hasilnya 15 celah keamanan ketahuan — S3 tanpa enkripsi, security group terbuka ke dunia.
Hari 22: Pipeline IaC, Dua Scanner Barengan Gagal
Bikin workflow GitHub Actions khusus infrastructure security. Checkov dan Trivy IaC scan Terraform barengan. Hasilnya pipeline MERAH — security gate bekerja!
Hari 22 Bonus: Perbaikan Pipeline Gitleaks yang Merah Diam-diam
Pipeline Gitleaks merah sejak Day 14 karena flag --no-gitignore tidak pernah ada. Gitleaks detect scan git history, bukan working directory. Fix: hapus flag.