Mengamankan FluxCD secara menyeluruh: autentikasi Git, registry, Helm repository, dan cluster, otorisasi berbasis RBAC, keamanan jaringan, hingga rantai pasok dengan Cosign dan admission controller.

Di episode 18 kalian sudah mengintegrasikan service mesh dengan FluxCD — instalasi Istio, Linkerd, dan AWS App Mesh lengkap dengan mTLS antar service. mTLS mengamankan trafik antar pod, tetapi masih ada satu pertanyaan besar: bagaimana mengamankan Flux itu sendiri, komponen yang justru memegang akses ke hampir seluruh cluster?
Flux adalah agen di dalam cluster dengan permission sangat luas: membaca Git, menarik image, memasang Helm chart, dan menerapkan manifest ke mana saja. Jika Flux disusupi, seluruh cluster ikut terancam. Episode ini membahas empat lapisan: authentication, authorization, network security, dan supply chain security.
Authentication menjawab "siapa Flux dan bagaimana ia membuktikan identitasnya". Empat koneksi diamankan: Git, registry, Helm, dan API server cluster.
Untuk repo privat, gunakan deploy key SSH read-only per repository — dibuat oleh flux bootstrap — atau token dengan scope minimal. Manifest GitRepository merujuk secret kredensial:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m
ref:
branch: main
url: git@github.com:devvnull/gitops-apps.git
secretRef:
name: git-credentialsSecret berisi kunci privat SSH disimpan di namespace flux-system — sebaiknya tidak mentah di Git, kita enkripsi dengan SOPS di episode 20. Jangan memberi kunci dengan hak tulis ke repositori yang dipantau Flux.
Registry privat memakai ImagePullSecret bertipe kubernetes.io/dockerconfigjson, dipakai deployment dan image-reflector-controller saat memindai image. Helm repository privat memakai secret basic-auth yang dirujuk HelmRepository:
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: private-charts
namespace: flux-system
spec:
interval: 10m
type: oci
url: oci://ghcr.io/devvnull/charts
secretRef:
name: helm-credentialsUntuk registry, secret kubernetes.io/dockerconfigjson berisi struktur JSON auths hasil login registry, dan dirujuk lewat imagePullSecrets pada deployment. Kedua token ini idealnya dienkripsi SOPS seperti kunci Git.
Flux mengautentikasi ke API server lewat ServiceAccount milik tiap kontroler; kredensial di-mount otomatis ke pod, dan apa yang boleh dilakukan diatur oleh RBAC di bagian berikut.
Authorization menjawab "apa yang boleh dilakukan Flux dan siapa yang boleh mengubah konfigurasi Flux".
Tiap kontroler Flux berjalan dengan ServiceAccount dan ClusterRole sendiri. Terapkan least privilege: jangan beri cluster-admin ke manusia, dan batasi siapa yang bisa mengubah GitRepository, Kustomization, dan HelmRelease. Flux menyediakan ClusterRole siap pakai flux-viewer dan flux-edit yang dibatasi per namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: flux-edit-apps
namespace: apps
subjects:
- kind: Group
name: platform-team@devvnull.dev
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: flux-edit
apiGroup: rbac.authorization.k8s.ioSimpan Flux di namespace khusus flux-system yang hanya bisa diubah tim platform. Verifikasi akses efektif sebuah identitas dengan kubectl auth can-i create kustomization.kustomize.toolkit.fluxcd.io pada namespace apps.
Jaringan membatasi apa yang bisa dijangkau Flux dan bagaimana ia diakses:
spec.secretRef.flux-system hanya dari kontrol plane dan dashboard yang sah.apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: flux-egress
namespace: flux-system
spec:
podSelector:
matchLabels:
app.kubernetes.io/part-of: flux
policyTypes:
- Egress
egress:
- ports:
- port: 443
- port: 22Jalankan flux check --pre untuk verifikasi, atau flux install --network-policy agar Flux membuat NetworkPolicy default saat instalasi.
Lapisan terpenting: memastikan hanya artefak yang sah yang masuk cluster.
Source controller memverifikasi tanda tangan Cosign pada artifact OCI sebelum menyediakannya; kunci publik disimpan sebagai secret yang dirujuk OCIRepository:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: api
namespace: apps
spec:
interval: 5m
url: oci://ghcr.io/devvnull/api
verify:
provider: cosign
secretRef:
name: cosign-public-keyDi CI, image ditandatangani sebelum di-push lalu diverifikasi dengan cosign sign --key cosign.key ghcr.io/devvnull/api:1.2.3 dan cosign verify --key cosign.pub ghcr.io/devvnull/api:1.2.3.
Verifikasi di sumber tidak menjamin image tidak diubah saat dipakai; lapisi dengan admission controller — Kyverno atau OPA Gatekeeper — yang memaksa setiap Pod memenuhi kebijakan, misalnya image harus bertanda tangan:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: verify-cosign
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- image: "*"
key: |-Kebijakan ini dan policy lain dideklarasikan di Git dan disinkronkan Flux — policy sebagai kode. Kyverno juga bisa memaksa resource limits, melarang container privileged, dan memastikan label keamanan ada.
Episode ini membangun empat lapisan pertahanan untuk Flux: autentikasi untuk Git, registry, Helm, dan cluster; otorisasi berbasis RBAC dengan least privilege; network security lewat TLS dan NetworkPolicy; serta supply chain security dengan Cosign dan admission controller. Keamanan selalu berlapis — tidak ada satu lapisan yang cukup.
Inti yang harus dibawa pulang:
flux-system terisolasi dengan RBAC dan NetworkPolicy yang ketat.Keamanan Flux sudah kokoh, tetapi secret — kunci SSH, token, password — masih disimpan mentah di Git pada contoh di atas. Di episode 20 selanjutnya kita belajar Secrets Management dengan SOPS: enkripsi secret di repo, decryption otomatis Flux, hingga key rotation. Sampai jumpa di episode 20!