Kodeloka
  1. Kodeloka
  2. Kelas Grafana
  3. Materi

Modul 13 · Modul 13 dari 15

Autentikasi, Organisasi, Tim, dan Izin

Mengatur siapa boleh melihat dan mengubah apa, tanpa membuat akun bersama yang dipakai seluruh tim.

Peran Bawaan

PeranBisaTidak bisa
ViewerMelihat dashboard, memakai Explore bila diizinkanMenyimpan apa pun
EditorMembuat/mengubah dashboard dan alert ruleMengelola pengguna, data source
AdminSemua dalam satu organisasi, termasuk data sourcePengaturan lintas organisasi
Server AdminSemua organisasi, semua pengguna—
⚠️ Editor lebih berkuasa dari yang terlihat

Editor bisa membuat panel dengan kueri SQL bebas ke data source mana pun yang bisa dilihatnya. Bila salah satu data source memakai kredensial yang bisa membaca tabel sensitif, seorang Editor bisa membacanya — bahkan bila tidak ada dashboard yang menampilkannya.

Karena itu pemisahan sebenarnya harus dilakukan di level kredensial data source, bukan hanya di izin dashboard.

Organisasi vs Folder vs Tim

KonsepIsolasiPakai untuk
OrganizationTotal: data source, dashboard, user terpisahMulti-tenant sungguhan, misalnya penyedia layanan
FolderIzin per folderPemisahan antar tim di dalam satu perusahaan
TeamKumpulan penggunaMemberi izin sekaligus, bukan per orang
💡 Hampir selalu pilih folder + team, bukan organisasi

Organisasi memisahkan segalanya, termasuk data source — artinya tiap organisasi harus mengonfigurasi Prometheus-nya sendiri, dan dashboard tidak bisa dibagi. Untuk perusahaan dengan banyak tim tetapi satu tumpukan observability, folder dengan izin tim jauh lebih praktis.

OAuth: Contoh Google dan Generik

grafana.ini — OAuthini
[auth.google]
enabled            = true
name               = Akun Perusahaan
client_id          = $__env{GOOGLE_CLIENT_ID}
client_secret      = $__env{GOOGLE_CLIENT_SECRET}
scopes             = openid email profile
allowed_domains    = perusahaan.id
allow_sign_up      = true
auto_login         = false

[auth.generic_oauth]
enabled       = true
name          = Keycloak
client_id     = grafana
client_secret = $__env{OIDC_SECRET}
scopes        = openid email profile roles
auth_url      = https://sso.perusahaan.id/realms/utama/protocol/openid-connect/auth
token_url     = https://sso.perusahaan.id/realms/utama/protocol/openid-connect/token
api_url       = https://sso.perusahaan.id/realms/utama/protocol/openid-connect/userinfo
role_attribute_path = contains(realm_access.roles[*], 'grafana-admin') && 'Admin' || contains(realm_access.roles[*], 'grafana-editor') && 'Editor' || 'Viewer'
role_attribute_strict = true
allow_assign_grafana_admin = false

[auth]
disable_login_form   = true     # paksa lewat SSO
oauth_auto_login     = false
login_maximum_inactive_lifetime_duration = 7d
login_maximum_lifetime_duration          = 30d

[auth.anonymous]
enabled = false
⛔ Jangan matikan form login sebelum SSO terbukti bekerja

Dengan disable_login_form = true dan konfigurasi OAuth yang salah, Anda terkunci dari Grafana sendiri.

Jalan keluar bila sudah terjadi: akses /login dengan parameter khusus tidak akan menolong — Anda perlu mengubah konfigurasi lewat env var lalu restart, atau mereset password admin lewat CLI:

bash
grafana cli admin reset-admin-password rahasiabaru

Urutan yang aman: aktifkan OAuth, uji sampai berhasil masuk, baru matikan form login.

Izin Folder dan Dashboard

izin folder lewat APIbash
curl -sS -u admin:rahasia -X POST \
  http://localhost:3000/api/folders/peringatan-produksi/permissions \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [
      { "role": "Viewer",  "permission": 1 },
      { "teamId": 3,       "permission": 2 },
      { "userId": 12,      "permission": 4 }
    ]
  }'

# permission: 1 = View, 2 = Edit, 4 = Admin

Izin diwariskan dari folder ke dashboard di dalamnya. Menetapkan izin per dashboard mungkin, tetapi cepat menjadi tidak terkelola — atur di tingkat folder.

Service Account: Pengganti API Key

API key lama sudah usang. Yang benar sekarang adalah service account dengan token — punya peran sendiri, bisa dicabut, dan terlihat di audit.

service accountbash
curl -sS -u admin:rahasia -X POST http://localhost:3000/api/serviceaccounts \
  -H 'Content-Type: application/json' \
  -d '{ "name": "ci-anotasi-deploy", "role": "Editor", "isDisabled": false }'

# lalu buat token untuk akun itu
curl -sS -u admin:rahasia -X POST \
  http://localhost:3000/api/serviceaccounts/5/tokens \
  -H 'Content-Type: application/json' \
  -d '{ "name": "token-pipeline", "secondsToLive": 7776000 }'
⚠️ Beri peran seminimal mungkin

Service account untuk mengirim anotasi deploy tidak perlu peran Admin. Peran Editor sudah cukup — dan bila token itu bocor dari log pipeline, kerusakannya jauh lebih terbatas.

Selalu set secondsToLive. Token tanpa masa berlaku akan hidup selamanya di riwayat CI seseorang.

Kesalahan Konfigurasi yang Perlu Diaudit

  • auth.anonymous.enabled = true di instansi yang bisa dijangkau dari internet.
  • users.allow_sign_up = true — siapa pun bisa mendaftar sendiri.
  • Password admin masih admin.
  • Satu akun bersama dipakai seluruh tim — audit log menjadi tidak berguna.
  • role_attribute_strict = false dengan allow_assign_grafana_admin = true — klaim OAuth bisa menaikkan hak sendiri.
  • Data source memakai kredensial superuser basis data.

Untuk Panel yang Disematkan di Aplikasi Lain

Kebutuhan "tampilkan dashboard di portal pelanggan" tidak boleh diselesaikan dengan menyalakan akses anonim. Pilihan yang benar:

  • Public dashboards — Grafana menyediakan URL publik khusus per dashboard, hanya-baca, tanpa membuka seluruh instansi.
  • Reverse proxy dengan auth proxy — aplikasi Anda yang mengautentikasi, lalu meneruskan identitas lewat header ke Grafana.
  • Render gambar lewat image renderer dan sajikan sebagai PNG statis untuk laporan.