Tampilan
9.3 Auth
Tujuan bab
Setelah bab ini kamu bisa:
- Mengamankan server Mastra dengan
SimpleAuthuntuk pengembangan dan API key - Mengatur rute mana yang dilindungi dan mana yang publik
- Menggabungkan beberapa penyedia autentikasi dengan
CompositeAuth - Memilih penyedia identitas yang sesuai untuk produksi
- Menghubungkan hasil autentikasi ke
RequestContextdan ke lapisan data
Prasyarat
Dua pertanyaan yang berbeda
Autentikasi sering dibicarakan sebagai satu hal, padahal ada dua pertanyaan terpisah:
- Autentikasi — siapa kamu? Memverifikasi identitas.
- Otorisasi — kamu boleh apa? Menentukan hak akses.
Mastra menangani keduanya, tapi lewat mekanisme yang berbeda. Autentikasi lewat penyedia auth; otorisasi lewat authorizeUser, konfigurasi rute, dan — untuk kebutuhan yang lebih halus — Fine-Grained Authorization.
SimpleAuth — titik awal
SimpleAuth menyediakan autentikasi berbasis token dengan pemetaan token ke pengguna. Ia sudah termasuk dalam @mastra/core dan tidak butuh paket tambahan.
ts
// src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { SimpleAuth } from '@mastra/core/server'
type User = {
id: string
name: string
role: 'admin' | 'user'
}
export const mastra = new Mastra({
server: {
auth: new SimpleAuth<User>({
tokens: {
'sk-admin-token-123': {
id: 'user-1',
name: 'Admin User',
role: 'admin',
},
'sk-user-token-456': {
id: 'user-2',
name: 'Regular User',
role: 'user',
},
},
}),
},
})Perhatikan bahwa SimpleAuth bertipe generik — SimpleAuth<User> membuat bentuk objek pengguna kamu yang tentukan, dan tipe itu mengalir ke seluruh tempat pengguna dibaca.
Kapan SimpleAuth memadai
Dokumentasi menyebutkan kasus pemakaiannya:
- Pengembangan dan pengujian lokal
- Autentikasi API key sederhana
- Prototipe sebelum mengintegrasikan penyedia identitas penuh
- Layanan internal dengan token statis
Yang tidak termasuk: pengguna akhir manusia dalam jumlah banyak. Token statis di dalam kode tidak bisa dicabut per pengguna, tidak kedaluwarsa, dan tidak punya alur pendaftaran.
Jangan pernah menulis token asli di dalam kode
Contoh di atas menulis token secara langsung supaya mudah dibaca. Di proyek sungguhan, token dibaca dari variabel lingkungan.
Token yang ter-commit ke git harus dianggap bocor selamanya — riwayat git tidak lupa, dan menghapusnya dari commit terakhir tidak menghapusnya dari riwayat.
Opsi yang tersedia
| Opsi | Wajib | Kegunaan |
|---|---|---|
tokens | Ya | Peta token ke objek pengguna |
headers | Tidak | Header tambahan yang diperiksa |
name | Tidak | Nama penyedia untuk keperluan log |
authorizeUser | Tidak | Fungsi otorisasi kustom |
protected | Tidak | Path yang memerlukan autentikasi |
public | Tidak | Path yang melewati autentikasi |
Secara bawaan, SimpleAuth memeriksa header Authorization (dengan atau tanpa awalan Bearer) dan X-Playground-Access.
protected dan public
Kedua opsi ini yang menentukan permukaan yang terbuka, dan layak dipikirkan baik-baik.
Pola yang lebih aman adalah melindungi secara default dan membuka secara eksplisit — bukan sebaliknya. Rute yang lupa kamu daftarkan sebagai protected akan terbuka; rute yang lupa kamu daftarkan sebagai public hanya akan menolak permintaan. Kegagalan jenis kedua jauh lebih murah.
Kandidat yang wajar untuk public: endpoint pemeriksaan kesehatan, dan mungkin agent card A2A kalau kamu memang ingin ditemukan.
authorizeUser — dari "siapa" ke "boleh apa"
SimpleAuth memverifikasi token dan menghasilkan objek pengguna. Yang menentukan apakah pengguna itu boleh melakukan sesuatu adalah authorizeUser:
ts
auth: new SimpleAuth<User>({
tokens: { /* ... */ },
authorizeUser: (user, request) => {
return user.role === 'admin'
},
}),Fungsi ini menerima pengguna dan permintaan, dan mengembalikan boolean. Karena ia melihat keduanya, kamu bisa membuat aturan yang bergantung path atau method — misalnya hanya admin yang boleh menyentuh endpoint tertentu.
CompositeAuth — beberapa penyedia sekaligus
CompositeAuth menggabungkan beberapa penyedia menjadi satu penangan. Ia mencoba tiap penyedia secara berurutan sampai satu berhasil.
ts
// src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { CompositeAuth, SimpleAuth } from '@mastra/core/server'
import { MastraAuthClerk } from '@mastra/auth-clerk'
type ApiKeyUser = {
id: string
name: string
type: 'api-key'
}
const apiKeyAuth = new SimpleAuth<ApiKeyUser>({
tokens: {
'sk-integration-key-123': {
id: 'integration-1',
name: 'CI/CD Pipeline',
type: 'api-key',
},
},
})
export const mastra = new Mastra({
server: {
auth: new CompositeAuth([apiKeyAuth, new MastraAuthClerk()]),
},
})Kegunaan yang disebut dokumentasi:
- Mendukung API key dan token OAuth sekaligus — manusia lewat OAuth, integrasi lewat API key
- Bermigrasi antar penyedia tanpa memutus klien yang sudah ada
- Mengizinkan beberapa penyedia identitas
- Peluncuran bertahap metode autentikasi baru
Kasus kedua patut diperhatikan: mengganti penyedia identitas biasanya berarti memutus semua klien sekaligus. Dengan CompositeAuth, penyedia lama dan baru bisa hidup berdampingan selama masa transisi.
Karena urutannya berpengaruh, taruh penyedia yang paling sering dipakai di depan — setiap penyedia yang dicoba dan gagal menambah latensi.
Penyedia untuk produksi
Untuk pengguna akhir manusia, kamu butuh penyedia identitas sungguhan:
| Penyedia | Paket |
|---|---|
| JWT dengan secret bersama | @mastra/auth (MastraJwtAuth) |
| Clerk | @mastra/auth-clerk |
| Supabase | @mastra/auth-supabase |
| Firebase | @mastra/auth-firebase |
| Auth0 | @mastra/auth-auth0 |
| WorkOS | @mastra/auth-workos |
MastraJwtAuth adalah jalan tengah yang berguna: ia memverifikasi permintaan berdasarkan secret bersama lewat variabel MASTRA_JWT_SECRET, tanpa memerlukan layanan identitas eksternal. Cocok saat aplikasi utamamu sudah menangani login dan kamu hanya perlu server Mastra memercayai token yang sudah ia terbitkan.
Untuk kebutuhan izin tingkat sumber daya — "pengguna ini boleh membaca thread ini, tapi bukan thread itu" — tersedia Fine-Grained Authorization (FGA), yang memetakan rute ke tindakan dan membatasi cakupan sumber daya tersimpan.
Menyambungkan ke seluruh sistem
Autentikasi tidak berhenti di gerbang. Identitas yang sudah diverifikasi harus mengalir ke tempat keputusan diambil:
Tiga sambungan di bawah adalah yang membuat autentikasi benar-benar berarti:
Ke memory. Nilai resource di 3.1 harus berasal dari sini. Tanpa itu, ingatan pengguna bisa tertukar — dan dengan working memory berlingkup resource di 3.2, itu berarti profil pribadi bocor.
Ke tool. Seperti dibahas di 9.2, identitas dibaca dari requestContext, bukan dari inputSchema yang bisa dikarang model.
Ke trace. Lewat requestContextKeys di 8.1, sehingga trace bisa ditelusuri per pengguna.
Studio juga perlu diamankan
Satu hal yang mudah terlupa: Studio mengekspos agent-mu juga. Kalau kamu men-deploy Studio ke lingkungan yang bisa diakses orang lain, ia butuh perlindungan sendiri.
Mastra menyediakan alur login untuk Studio, penerusan token, kontrol akses berbasis peran, peran bawaan, dan render UI yang sadar izin. Ini dibahas lagi di 9.4.
Kesalahan umum
Gejala: Tagihan model melonjak tanpa penjelasan, dari lalu lintas yang tidak dikenali. Penyebab: Server Mastra menghadap internet tanpa autentikasi. Endpoint terbuka rutin ditemukan pemindai otomatis, dan agent adalah target yang menarik karena tiap panggilan berbiaya. Perbaikan: Pasang auth sebelum apa pun online — bahkan SimpleAuth dengan satu token jauh lebih baik daripada tidak sama sekali. Periksa juga public tidak lebih longgar dari yang kamu maksud.
Gejala: Pengguna melihat data pengguna lain, padahal autentikasi jelas bekerja dan token diverifikasi dengan benar. Penyebab: Autentikasi berhenti di gerbang. Identitas terverifikasi tidak diteruskan ke resource pada memory, atau tool masih menerima userId lewat inputSchema. Perbaikan: Alirkan identitas dari hasil autentikasi ke RequestContext, lalu pakai nilai itu untuk resource memory dan untuk identitas di dalam tool. Autentikasi tanpa penerusan hanya mengamankan pintu depan.
Coba sendiri
Tantangan: Amankan aplikasi dari 9.2 dari gerbang sampai ke lapisan data, lalu serang sendiri untuk membuktikannya.
Ketentuan:
- Pasang
SimpleAuthdengan tiga pengguna berbeda peran, token dibaca dari variabel lingkungan — bukan ditulis di kode - Atur
publichanya untuk endpoint pemeriksaan kesehatan; sisanya terlindungi - Tambahkan
authorizeUseryang membatasi satu endpoint tertentu hanya untuk peran admin - Alirkan identitas terverifikasi ke
RequestContext, lalu pakai sebagairesourcepada memory - Uji empat skenario: tanpa token, token tidak valid, token valid peran biasa ke endpoint admin, dan token valid peran admin
- Uji isolasi data: masuk sebagai pengguna A, simpan sesuatu ke memory, lalu masuk sebagai pengguna B dan coba mengaksesnya — termasuk dengan membujuk agent lewat kalimat
- Ganti
SimpleAuthmenjadiCompositeAuthyang menggabungkan duaSimpleAuthberbeda, dan pastikan keduanya tetap bekerja - Periksa apakah trace-mu bisa difilter per pengguna
Checklist penerimaan:
- [ ] Tidak ada token yang tertulis di dalam kode
- [ ] Endpoint kesehatan bisa diakses tanpa token; sisanya menolak
- [ ] Keempat skenario di langkah 5 memberi hasil yang tepat, termasuk perbedaan antara 401 dan 403
- [ ] Langkah 6 gagal mengakses data pengguna lain — baik lewat API maupun lewat bujukan kalimat ke agent
- [ ]
CompositeAuthmenerima token dari kedua penyedia - [ ] Trace bisa difilter berdasarkan pengguna
- [ ] Kamu bisa menjelaskan perbedaan peran
authdanauthorizeUser
Petunjuk: Langkah 6 adalah yang paling penting dan paling sering terlewatkan. Banyak aplikasi lulus uji autentikasi di gerbang tapi gagal di lapisan data — karena resource memory diisi nilai tetap, atau diambil dari parameter yang dikirim klien. Cobalah dua jalur serangan: mengirim resource lain lewat API, dan meminta agent secara halus lewat percakapan. Kalau identitas benar-benar mengalir dari RequestContext, keduanya buntu.
Ikhtisar
- Autentikasi menjawab "siapa kamu", otorisasi menjawab "boleh apa". Yang pertama lewat penyedia
auth, yang kedua lewatauthorizeUser, konfigurasi rute, dan FGA. SimpleAuthada di@mastra/core/server, bertipe generik, dan cocok untuk pengembangan, API key, prototipe, dan layanan internal — bukan untuk pengguna akhir manusia.- Jangan tulis token di kode. Baca dari variabel lingkungan.
- Lindungi secara default, buka secara eksplisit — kegagalan
publicyang terlupa jauh lebih murah daripadaprotectedyang terlupa. CompositeAuthmencoba beberapa penyedia berurutan — untuk mendukung API key dan OAuth bersamaan, atau bermigrasi tanpa memutus klien.- Untuk produksi:
MastraJwtAuthdengan secret bersama, atau penyedia identitas seperti Clerk, Supabase, Firebase, Auth0, WorkOS. FGA untuk izin tingkat sumber daya. - Autentikasi harus mengalir: ke
resourcememory, ke identitas di dalam tool, dan ke metadata trace. Berhenti di gerbang berarti hanya mengamankan pintu depan. - Studio juga mengekspos agent-mu dan butuh perlindungan sendiri.
Lanjut ke mana
Bab terakhir: membawa semua ini keluar dari laptopmu — 9.4 Deployment & Checklist Rilis.