Authentication sudah menjawab “siapa yang terhubung”; sekarang server perlu menjawab “identitas ini boleh melakukan apa”. Jawaban MongoDB atas pertanyaan itu adalah Role-Based Access Control (RBAC): hak akses tidak diberikan langsung ke user, melainkan dikemas dalam role yang bisa dipakai ulang. Chapter ini membongkar anatomi privilege, memetakan role bawaan yang tersedia, lalu membangun role kustom ketika role bawaan terlalu besar atau terlalu kecil.
Peta materi Chapter ini:
- Anatomi privilege: pasangan resource + actions.
- Peta role bawaan dan use case-nya, termasuk peringatan untuk
root. - Role kustom dengan
db.createRole(): privilege presisi pada satu collection. - Penerusan role (inheritance) lewat field
roles.
Privilege: Resource dan Actions #
Satu privilege selalu memuat dua bagian: resource (di mana) dan actions (apa yang boleh dilakukan). Resource bisa berupa satu collection, seluruh database, cluster, atau kombinasi khusus. Actions adalah daftar operasi seperti find, insert, remove, atau createIndex. Role adalah sekumpulan privilege — dan role juga bisa mewarisi role lain lewat field roles.
Kita intip isi role bawaan read langsung dari server latihan:
use latihan_uji
const privilegePertama = db.getRole("read", { showPrivileges: true }).privileges[0]
printjson(privilegePertama)Output yang Dihasilkan:
switched to db latihan_uji
{
resource: {
db: 'latihan_uji',
collection: ''
},
actions: [
'changeStream',
'collStats',
'dbHash',
'dbStats',
'find',
'killCursors',
'listCollections',
'listIndexes',
'listSearchIndexes',
'planCacheRead',
'performRawDataOperations'
]
}Terbaca dua bagian itu persis: resource { db: "latihan_uji", collection: "" } berarti seluruh collection di latihan_uji (string kosong adalah wildcard collection), dan actions-nya dipimpin find — operasi baca inti — ditemani actions pendukung seperti listCollections dan dbStats. Method db.getRole() di atas adalah pembungkus dari perintah rolesInfo; tambahkan showBuiltinRoles: true bila ingin melihat role bawaan pada database admin.
Peta Role Bawaan #
MongoDB mengirim role bawaan yang menutupi kebutuhan umum. Mengenal peta ini menghemat banyak keputusan:
| Role | Berlaku di | Use case |
|---|---|---|
read | Semua db | Dashboard analitik, pelaporan read-only |
readWrite | Semua db | User aplikasi CRUD standar |
dbAdmin | Semua db | Maintenance satu database: index, statistik, validasi |
dbOwner | Semua db | Pemilik penuh satu database (readWrite + dbAdmin + userAdmin) |
userAdmin | Semua db | Mengelola user dan role pada satu database |
clusterMonitor | admin | Monitoring cluster read-only (serverStatus, replSetGetStatus) |
backup / restore | admin | Menjalankan mongodump / mongorestore |
root | admin | Semua hal di semua database |
Varian readAnyDatabase, readWriteAnyDatabase, dbAdminAnyDatabase, dan userAdminAnyDatabase adalah versi lintas-database dari empat role pertama, dan semuanya hanya bisa diberikan dari database admin. Role backup dan restore sengaja dipisahkan — tugas pencadangan rutin hanya butuh backup, dan restore yang lebih berbahaya hanya dipasang saat pemulihan.
Role Kustom #
Role bawaan selalu menyapu satu database penuh. Ketika sebuah aplikasi hanya boleh membaca satu collection — misalnya layanan katalog yang hanya butuh collection buku — role kustom memberi privilege presisi. Kita buat role pembaca khusus:
db.buku.drop()
db.buku.insertOne({ judul: "Bumi", penulis: "Tere Liye", harga: 89000 })
db.createRole({
role: "bacaJudulBuku",
privileges: [
{ resource: { db: "latihan_uji", collection: "buku" }, actions: ["find"] }
],
roles: []
})
db.getRole("bacaJudulBuku", { showPrivileges: true })Output yang Dihasilkan (bagian $clusterTime dan operationTime yang berulang diringkas):
true
{
acknowledged: true,
insertedId: ObjectId('6ad3bede35f0a6cf9b086b48')
}
{ ok: 1 }
{
_id: 'latihan_uji.bacaJudulBuku',
role: 'bacaJudulBuku',
db: 'latihan_uji',
privileges: [
{
resource: { db: 'latihan_uji', collection: 'buku' },
actions: [ 'find' ]
}
],
roles: [],
inheritedRoles: [],
inheritedPrivileges: [
{
resource: { db: 'latihan_uji', collection: 'buku' },
actions: [ 'find' ]
}
],
isBuiltin: false
}Bedah bagiannya:
privileges: satu privilege berisi tepat satu resource — collectionbukudilatihan_uji— dengan satu actionfind. Tidak ada action tulis, tidak ada collection lain.roles: []: role ini tidak mewarisi role lain. Field inilah jalur inheritance — isi dengan[{ role: "read", db: "latihan_uji" }]dan role kustom langsung mewarisi seluruh privilegeread.db.getRole(): mengembalikan definisi tersimpan;inheritedPrivilegesmenunjukkan privilege efektif setelah semua warisan dihitung.
Role kustom dipakai persis seperti role bawaan — sebagai entri roles pada db.createUser() atau grantRolesToUser():
db.createUser({
user: "budi_pembaca",
pwd: "sandiBudi123",
roles: [{ role: "bacaJudulBuku", db: "latihan_uji" }]
})
db.getUsers()Output yang Dihasilkan (diringkas serupa):
{ ok: 1 }
{
users: [
{
_id: 'latihan_uji.budi_pembaca',
userId: UUID('2c8cb6a5-4787-405d-b854-7b6bb3ed670c'),
user: 'budi_pembaca',
db: 'latihan_uji',
roles: [ { role: 'bacaJudulBuku', db: 'latihan_uji' } ],
mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}
],
ok: 1
}Pada server dengan authorization aktif, user budi_pembaca kini hanya bisa menjalankan find pada latihan_uji.buku — mencoba membaca collection lain atau menulis akan ditolak. Server latihan kita tidak menegakkan aturan itu, tetapi struktur data role dan user-nya nyata dan persis seperti produksi.
Terakhir, kita rapikan semua artefak percobaan:
db.dropUser("budi_pembaca")
db.dropRole("bacaJudulBuku")
db.buku.drop()
db.getRoles()Output yang Dihasilkan (bagian $clusterTime dan operationTime yang berulang diringkas):
{ ok: 1 }
{ ok: 1 }
true
{
roles: [],
ok: 1
}Perlu diketahui: db.dropRole() segera mencabut role yang dihapus dari semua user pemegangnya — user yang kehilangan satu-satunya role menjadi tanpa hak akses. Kita menjatuhkan user dahulu agar tidak menyisakan user menganggur. Pengelolaan role lanjutan (updateRole, grantPrivilegesToRole, grantRolesToRole) mengikuti pola yang sama dengan manajemen user di chapter sebelumnya.
Rangkuman #
- Privilege = resource (di mana) + actions (apa); role adalah kumpulan privilege dan bisa mewarisi role lain.
- Mulai dari role bawaan:
read/readWriteuntuk aplikasi,dbAdmin/dbOwneruntuk operasional,clusterMonitor/backupuntuk tugas khusus. - Varian
*AnyDatabase,clusterMonitor,backup,restore, danroothidup di databaseadmin. db.createRole()merakit privilege presisi — misalnyafindpada satu collection — untuk kebutuhan yang tidak pas dengan role bawaan.rootdanuserAdmindiadminadalah tiket superuser: simpan sebagai akun darurat, bukan user harian.