Password statis adalah beban yang selalu bocor; di episode ini kalian membangun identitas tanpa secret untuk pipeline dan workload — OIDC federation dari GitHub Actions ke cloud, workload identity Kubernetes via service account annotation, SPIFFE/SPIRE untuk identitas in-cluster, serta least privilege sampai permission boundary

Episode 9 sudah menyentuh OIDC sebagai cara deploy; episode ini membahasnya secara utuh karena identitas adalah fondasi yang mengikat semua episode sebelumnya. Pikirkan sejenak: network policy (ep 18) mengontrol berdasarkan label, Kyverno (ep 13) memverifikasi signature berdasarkan issuer — semuanya pada akhirnya menjawab satu pertanyaan: "siapa kamu, dan bagaimana aku memastikannya?"
Masalah klasiknya adalah jawaban lama: password, API key, access token statis. Semua bentuk secret punya masalah sama — bisa dicuri, harus dirotasi, dan tidak membuktikan proses pemanggilnya, hanya pemegang kredensialnya. Episode ini membangun identitas modern: terverifikasi kriptografis, pendek umur, terikat pada konteks (repo/workload), tanpa secret untuk dijaga.
Peta lengkapnya sebelum masuk detail:
| Lapisan | Mekanisme | Contoh |
|---|---|---|
| Pipeline → Cloud | OIDC federation | GitHub Actions assume AWS role |
| Workload → Cloud | IRSA / Workload Identity | Pod K8s akses S3 |
| Workload → Workload | SPIFFE/SPIRE atau mesh | api ↔ database client |
Prinsip yang identik di ketiganya: bukti kriptografis pendek-umur ditukar dengan token scoped — bukan credential panjang yang disimpan.
Konfigurasi inti sudah dibahas di episode 9. Yang sering terlewat adalah disiplin claim binding:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": [
"repo:org/myapp:environment:production",
"repo:org/myapp:ref:refs/heads/main"
]
},
"StringLike": {
"token.actions.githubusercontent.com:job_workflow_ref":
"org/myapp/.github/workflows/deploy.yml@*"
}
}
}]
}Semakin spesifik binding, semakin sempit jalur penyalahgunaan:
job_workflow_ref — hanya workflow file tertentu; PR jahat yang menambahkan workflow baru tidak otomatis dapat akses.Audit berkala penting di sini — daftar semua role federated dan cek apakah masih relevan:
aws iam list-roles --query 'Roles[?AssumeRolePolicyDocument.Statement[?Action==`sts:AssumeRoleWithWebIdentity`]].RoleName'Pod Kubernetes yang perlu akses S3 tidak perlu static key juga. Di EKS pola ini disebut IRSA (IAM Roles for Service Accounts): service account K8s dipetakan ke IAM role via annotation:
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: prod
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/app-s3-reader
automountServiceAccountToken: true # token K8s dibutuhkan untuk exchangeAlur internalnya: pod menukar token service account (JWT bertanda cluster OIDC provider) dengan STS untuk mendapat kredensial AWS sementara. IAM role memvalidasi bahwa JWT berasal dari kombinasi cluster+namespace+SA tertentu — pod dari namespace lain atau SA lain ditolak.
GCP menyebut padanannya Workload Identity Federation for GKE; Azure punya konsep mirip via Microsoft Entra Workload ID. Konsepnya identik, sintaksnya beda.
Untuk percakapan antar-workload (dan lintas runtime), standar terbukanya adalah SPIFFE — identitas berformat URI (spiffe://trust-domain/ns/prod/sa/app) yang dibuktikan lewat sertifikat SVID pendek-masa-hidup. SPIRE adalah implementasinya:
Workload start -> attestasi (node/pod identity) -> SPIRE server terbitkan SVID
-> sertifikat X.509 pendek umur -> dipakai mTLS antar-serviceManfaat praktis: aplikasi tidak lagi memakai shared API key untuk saling autentikasi — mTLS dengan SVID memberi identitas per-workload yang bisa diaudit, dan rotasi terjadi otomatis tiap beberapa jam. Istio/Linkerd bisa memakai SPIRE sebagai backend identitasnya.
Tip
Jangan adopsi SPIRE hanya karena hype. Aturannya: kalau stack kalian satu mesh, identitas mesh cukup. SPIRE bernilai saat kalian butuh identitas konsisten lintas runtime — VM, cluster berbeda, serverless, bahkan bare metal.
Identitas modern tanpa least privilege hanya mengganti nama masalah. Tiga teknik wajib:
Batasi apa pun yang bisa dilakukan role, meski policy-nya keliru over-permissive:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"NotAction": ["s3:GetObject", "s3:ListBucket"],
"Resource": "*"
}]
}Anti-pattern: deploy-role dengan akses ECR+EKS+S3+SQS dipakai semua job. Pisahkan: build-push-role, deploy-role, migration-role. Blast radius insiden satu token menjadi satu fungsi.
Selalu set role-duration-seconds: 900 (15 menit) untuk CI. Kalau job deploy rata-rata 5 menit, tidak ada alasan sesi hidup 1 jam.
sub: repo:org/*) — membuka federation untuk semua repo termasuk yang baru dibuat developer mana pun.Inti yang harus dibawa pulang:
Di episode 20 selanjutnya kita membahas Audit & Incident Automation — mengaktifkan audit log Kubernetes dengan policy selektif, membangun incident response automation dari alert hingga containment otomatis, dan runbook as code yang dieksekusi mesin bukan sekadar dokumen wiki. Sampai jumpa!