
Hari 35: Rego Policy Pertama — Wajib Resource Limits
Tulis Rego policy pertama untuk Gatekeeper: Pod/Deployment tanpa resource limits dan requests ditolak. 4 violation rules, enforcementAction deny, 0 violations.
Hari 34 kemarin install OPA Gatekeeper — "bouncer" di pintu masuk cluster. Tapi bouncer-nya belum punya aturan. Hari ini tulis aturan pertama: Pod tanpa resource limits dan requests = ditolak.
Kenapa Resource Limits Penting?
Tanpa resource limits, Pod bisa menghabiskan CPU/memory node — menyebabkan DoS (Denial of Service) ke Pod lain di node yang sama. Kubernetes scheduler juga butuh resource requests untuk decision placement Pod ke node yang tepat.
Scanner seperti Checkov dan Trivy sudah menandai "no resources" sebagai finding (Day 32). Tapi scanner hanya melaporkan — tidak mencegah. Gatekeeper mencegah: Pod tanpa resources tidak akan masuk ke cluster, titik.
Dua File: ConstraintTemplate + Constraint
Gatekeeper punya konsep 2 layer:
ConstraintTemplate — berisi Rego policy code. Ini "template" yang mendefinisikan logic: "Kalau Pod tidak punya CPU limit = violation". Analoginya seperti template undangan.
Constraint — instance dari template. Berisi match rules: policy ini berlaku untuk Pod dan Deployment di namespace securebank saja, dengan enforcementAction: deny. Analoginya seperti undangan yang sudah dikirim ke tamu tertentu.
Satu template bisa punya banyak constraint — misalnya deny untuk production, dryrun untuk development.
Rego Policy: 4 Violation Rules
package k8srequiredlimits
# Rule 1: CPU limit wajib
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits.cpu
msg := sprintf("Container '%v' has no CPU limit", [container.name])
}
# Rule 2: Memory limit wajib
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.limits.memory
msg := sprintf("Container '%v' has no memory limit", [container.name])
}
# Rule 3: CPU request wajib
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.requests.cpu
msg := sprintf("Container '%v' has no CPU request", [container.name])
}
# Rule 4: Memory request wajib
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.resources.requests.memory
msg := sprintf("Container '%v' has no memory request", [container.name])
}
Tutorial cuma cek limits (2 rules). Aku tambah requests juga (4 rules total) — lebih comprehensive. Requests penting untuk scheduler: kalau tidak ada, scheduler tidak tahu berapa resource yang Pod butuhkan, bisa placement ke node yang salah.
Rego Syntax Yang Dipelajari
violation[{"msg": msg}]— Gatekeeper pattern: kalau rule ini match, ada violation dengan pesan errorinput.review.object— resource yang sedang di-apply (Pod atau Deployment)spec.containers[_]— iterasi semua container di Podnot container.resources.limits.cpu—not= negation. Kalau property tidak ada = true (violation)sprintf("Container '%v' ...", [container.name])— format string dengan container name
Constraint: Match Rules + Enforcement
spec:
enforcementAction: deny
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
- apiGroups: ["apps"]
kinds: ["Deployment"]
namespaces:
- securebank
enforcementAction: deny— explicit deny. Bisa jugadryrun(allow tapi report) atauwarn(allow dengan warning)apiGroups: [""]+kinds: ["Pod"]— match bare PodapiGroups: ["apps"]+kinds: ["Deployment"]— match Deployment (Gatekeeper expand ke Pod template)namespaces: ["securebank"]— hanya di namespacesecurebank
Hasil: 0 Violations
Setelah apply, verifikasi:
$ kubectl get k8srequiredlimits require-resource-limits
NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS
require-resource-limits deny
0 total violations. Artinya deployment.yaml yang sudah di-hardened di Day 33 (dengan resources: requests + limits) langsung pass policy. Tidak perlu fix apa-apa.
Before vs After
| Aspek | Before (Day 34) | After (Day 35) |
|---|---|---|
| Policy | Gatekeeper installed, no policy | Rego policy: 4 violation rules |
| Enforcement | Webhook aktif tapi kosong | Pod tanpa resources = ditolak |
| Scope | — | Namespace securebank only |
| enforcementAction | — | deny (explicit) |
| Violations | — | 0 (existing deployment compliant) |
Pelajaran Hari Ini
ConstraintTemplate = template, Constraint = instance. Template berisi Rego code (logic). Constraint berisi match rules (scope) + enforcementAction. Satu template bisa punya banyak constraint dengan enforcementAction berbeda.
not di Rego = negation. Rego tidak punya == nil atau != nil seperti Go. not container.resources.limits.cpu artinya "kalau property ini tidak ada". Simple tapi butuh adaptasi dari mindset Go/Python.
Scanner melaporkan, Gatekeeper mencegah. Checkov dan Trivy menemukan "no resources" di Day 32. Tapi scanner hanya laporkan — developer bisa ignore. Gatekeeper mencegah: kubectl apply Pod tanpa resources = ditolak. Prevention > detection.
Repo
Semua code dan dokumentasi ada di: https://github.com/stayrelevantid/chalange-devsecops
Kesimpulan
Rego policy pertama berhasil. 4 violation rules (CPU limit, memory limit, CPU request, memory request), enforcementAction: deny, 0 violations. Besok Day 36 — test policy-nya bekerja: apply Pod tanpa resources → expect ditolak. Apply Pod dengan resources → expect diterima. Menuju policy-as-code di K8s cluster.
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.