Perbedaan autentikasi OAuth dan Service Account, dari robot yang mati tiap hari kedelapan

Beberapa bulan lalu saya membuat satu aplikasi untuk kantor. Tugasnya mengirim rekap proyek lewat WhatsApp ke beberapa petinggi perusahaan, lengkap dengan status tagihan, kendala terakhir, dan perkembangan terbaru.

Apa yang dikerjakan aplikasi ini?

Sederhana saja. Ada satu Google Sheets berisi daftar semua proyek yang dikerjakan oleh perusahaan kami. Setiap baris memuat nama proyek, nomor PO, pekerjaan yang sedang jalan, nilai tagihan, dan kendala di lapangan yang diperbarui berkala oleh setiap site manager proyek.

Robot dari aplikasi ini membaca sheet tersebut secara keseluruhan. Selanjutnya, aplikasi ini punya dua mode otomatis. Mode pagi selalu mengirim rekap total, apa pun keadaannya, karena orang perlu tahu posisi terakhir seluruh proyek waktu memulai hari. Mode sore lebih pemilih. Mode ini hanya mengirim pesan kalau ada yang benar-benar berubah, dibandingkan dengan salinan terakhir yang tersimpan. Kalau ada perubahan, robotnya membuka WhatsApp Web lalu mengirim. Kalau tidak ada, robotnya diam dan tidur lagi. Robot mendeteksi perubahan dari ingatan yang dibuat setiap selesai menjalankan sesi pagi.

Singkat cerita, aplikasi berjalan mulus selama tujuh hari pertama. Tidak ada masalah. Tapi di hari kedelapan aplikasinya berhenti di tengah jalan saat berjalan otomatis. Saya coba jalankan manual dan muncul blok tulisan panjang berwarna merah, oranye, dan ungu. Intinya, izin ke Google ditolak. Saya coba mendiagnosisnya dengan bantuan internet, dan ketemu penyebabnya.

Akarnya ada di satu berkas autentikasi bernama token.json

Waktu pertama kali menyambungkan program ke Google Sheets, saya memakai cara autentikasi yang paling banyak muncul di tutorial: OAuth untuk aplikasi desktop. Prosesnya terasa masuk akal. Jalankan program, browser terbuka, saya login dengan akun Google, klik izinkan, selesai. Aplikasi lalu menyimpan hasilnya ke sebuah berkas bernama token.json.

Berkas itulah yang belakangan jadi sumber masalah.

Isinya adalah izin sementara atas nama akun Google yang dipakai untuk login. Pada berkas milik saya, izin itu punya tanggal habis setiap tujuh hari. Jadi harus saya perbarui terus. Kalau tidak saya perbarui, aplikasi di hari kedelapan akan berhenti di tengah jalan. Cara memperbaruinya adalah dengan menghapus berkas token.json yang lama, lalu login kembali menggunakan akun Google yang sama. Singkat cerita, selama beberapa waktu, saya terus memperbarui token.json tersebut secara manual tiap tujuh hari.

Empat langkah yang terjadi di hari kedelapan sampai robot berhenti jalan
Urutan yang terulang tiap tujuh hari. Gambar ini diagram buatan saya sendiri, bukan tangkapan layar.

Berkas token itu kebetulan masih saya simpan, dan waktu saya periksa lagi untuk memperkuat bukti di tulisan ini, statusnya memang masih kedaluwarsa.

Tangkapan layar isi berkas token.json lama, baris expiry tertulis 21 Mei 2026 dan refresh token tersedia
Tangkapan layar isi berkas token lama saya. Di baris expiry tertulis 21 Mei 2026, tanggal terakhir berkas itu masih sah, dan itu memang hari terakhir saya memakainya.

Jalan keluarnya, autentikasi memakai Service Account

Pertanyaan berikutnya tinggal satu, jenis izin seperti apa yang tidak memerlukan aksi dari manusia. Jadi seperti biasa, saya memakai Claude Code untuk mencari jalan keluarnya. Hasilnya, metode autentikasi yang cocok untuk aplikasi saya ternyata bukan OAuth, melainkan Service Account.

Service Account ini juga disediakan oleh Google. Biasanya berbentuk panjang dan berakhiran .iam.gserviceaccount.com, dan akun itu tidak pernah perlu login berkali-kali.

Perbedaan intinya ada di sini. Sistem autentikasi OAuth mewajibkan penggunanya selalu login dengan akun sendiri. Secara harfiah, sistem OAuth ini bertanya “apakah manusia ini mengizinkan program tersebut? Jika iya, maka manusia ini akan login menggunakan akunnya”, dan izin itu memang dirancang bisa dicabut atau habis masa berlakunya untuk mencegah terjadinya hal yang tidak diinginkan seperti akun diretas. Contoh yang paling sering kita temui adalah aplikasi pihak ketiga yang minta izin membuka Google Drive atau Google Foto milik Anda sendiri yang sifatnya privasi, lengkap dengan layar izin yang menampilkan nama akun Anda di atasnya.

Sedangkan sistem autentikasi Service Account bukan untuk manusia, melainkan untuk sistem atau aplikasi. Jadi Service Account tidak mewajibkan siapa pun login, karena proses autentikasinya sudah dikerjakan oleh sistem itu sendiri. Secara harfiahnya, Service Account bertanya “apakah program ini memang punya kuncinya? Jika ya, maka aplikasi lanjut berjalan”, dan kunci itu secara bawaan tidak punya masa berlaku, jadi tidak perlu login berulang. Contoh aplikasi yang menggunakan Service Account adalah aplikasi skrip otomatis yang mengambil data harian dari Google Drive ke server internal perusahaan yang boleh diakses oleh beberapa orang (ini mirip seperti aplikasi yang saya buat).

Perbedaan OAuth dan Service Account, diringkas

Semua yang saya jelaskan di atas, dalam satu tampilan.

Aspek OAuth Service Account
Dipakai atas namaManusia pemilik akunProgram atau sistem
Cara memberi izinOrang login dan menekan izinkanProgram memakai berkas kunci
Masa berlaku izinAda, perlu diperbaruiTidak ada, secara bawaan
Perlu orang saat jalanYa, sekali di awalTidak
Kalau bocorTercatat di akun Google, bisa dicabutTercatat di Cloud Console, berlaku sampai dihapus
Cocok untukAplikasi untuk orangProgram yang jalan sendiri

Cara memakai Service Account

Empat langkah dasarnya

Cara memakainya juga cukup sederhana:

  1. Aktifkan Google Sheets API di proyek Google Cloud yang dipakai. Tanpa ini program tetap ditolak walaupun sheet-nya sudah dibagikan.
  2. Buat Service Account di Google Cloud Console, lalu unduh kuncinya berupa satu berkas JSON.
  3. Salin alamat email Service Account itu.
  4. Buka Google Sheets yang mau dibaca, klik Bagikan, tempel alamat email tadi, beri akses Viewer.

Langkah keempat itu yang paling sering terlewat, dan tanpa itu program akan bilang sheet-nya tidak ditemukan, padahal sebenarnya cuma belum diberi izin. Service Account tidak otomatis bisa melihat berkas milik Anda. Akun itu harus diundang, sama seperti mengundang rekan kerja.

Hambatan yang mungkin Anda temui

Ada satu hambatan yang tidak ada di daftar itu, dan saya temukan sendiri. Waktu pertama kali mencoba, saya membuatnya di akun organisasi, dan tombol pembuatan kuncinya tidak bisa ditekan sama sekali. Penyebabnya ternyata bukan kesalahan saya. Google memasang aturan keamanan bawaan yang memblokir pembuatan kunci Service Account pada organisasi yang dibuat sejak Mei 2024. Jadi kalau Anda memakai akun organisasi kantor lalu menemukan tombol itu mati, itu memang disengaja, bukan Anda yang keliru. Pindahlah ke akun pribadi. Pada kasus saya, saya akhirnya membuat akun pribadi khusus untuk keperluan kantor.

Satu hal yang harus ikut berubah: cara menyimpan kuncinya

Ada sisi lain dari kunci yang tidak pernah kedaluwarsa, dan saya rasa tidak jujur kalau tidak menyebutnya.

Justru karena kunci itu tidak punya masa berlaku, berkas JSON itu jadi barang yang harus dijaga. Kalau token.json bocor, izinnya masih tercatat di akun Google saya, jadi saya bisa mencabutnya sendiri dari halaman keamanan akun. Kalau kunci Service Account bocor, kunci itu akan terus berlaku sampai ada yang mencabutnya secara sadar.

Jadi tiga kebiasaan ini saya pasang sejak awal. Berkas kuncinya tidak pernah ikut masuk ke Git, karena ini penyebab kebocoran yang paling sering terjadi di dunia nyata. Izinnya saya batasi pada yang benar-benar dibutuhkan, dalam kasus saya cukup Viewer, karena robot ini memang hanya membaca dan tidak pernah menulis. Dan Service Account-nya cuma saya undang ke sheet yang memang diperlukan, tidak ke seluruh Drive.

Dua hal lagi yang saya pelajari belakangan. Berkas kuncinya sebaiknya disimpan di luar folder proyek, karena yang paling sering terjadi bukan orang sengaja mengunggahnya, melainkan ikut terbawa waktu seluruh folder disalin. Dan untuk program yang jalan di server atau layanan milik Google sendiri, Google justru menyarankan tidak mengunduh kunci sama sekali, melainkan memakai identitas bawaan lingkungannya. Cara itu tidak berlaku untuk kasus saya karena robot ini jalan di komputer kantor biasa, tapi kalau suatu hari saya pindahkan ke server, itu yang akan saya pakai.

Kalau suatu hari kuncinya bocor, gantinya juga gampang. Buat kunci baru di Google Cloud Console, hapus yang lama, ganti berkasnya. Robotnya tidak perlu diubah sedikit pun.

Empat belas hari tanpa gagal, menurut catatan robotnya

Saya tidak mau menilai dari perasaan, jadi saya buka catatan hariannya semenjak beralih ke Service Account. Kebetulan saya bikin catatan riwayat pada aplikasi ini supaya kerusakan atau bug bisa terdeteksi. Ada empat belas berkas catatan, dari 31 Agustus sampai 13 September 2026. Angkanya saya hitung dengan skrip yang membaca semua berkas itu sekaligus, bukan dengan menghitung satu per satu.

Yang dihitung Jumlah
Hari tercatat14
Robot bangun dan jalan26 kali
Gagal, galat, atau berhentinol

Ada yang sengaja tidak saya masukkan ke tabel. Saya dulu juga menghitung berapa sesi pagi yang mengirim laporan penuh dan berapa sesi sore yang berakhir diam, tapi skrip penghitungnya memakai penanda yang berbeda untuk keduanya dan angkanya tidak pernah saya cocokkan ulang. Berkas catatannya sendiri sekarang sudah tidak ada, jadi saya tidak bisa memeriksanya lagi. Daripada memasang angka yang tidak bisa saya pertanggungjawabkan, saya pilih hanya menampilkan tiga yang masih berdiri, dan yang paling penting dari ketiganya memang baris terakhir.

Baris pertama setiap catatan selalu sama, dan baris itu yang sekarang paling saya suka:

[Auth] Koneksi ke Google Sheets berhasil via Service Account.

Tidak ada lagi langkah yang menunggu saya menekan tombol izinkan. Tulisan seperti di atas ini menandakan akses ke Google Sheets berhasil.

Kesimpulan dari pengalaman saya

Kalau saya boleh meringkas semuanya jadi satu kalimat, pertanyaannya bukan mana yang lebih bagus antara OAuth dan Service Account, melainkan siapa yang seharusnya hadir waktu program itu berjalan.

OAuth dibuat dengan asumsi ada manusia di depan layar. OAuth bertanya lebih dulu, menunggu dijawab, lalu memberi izin yang bisa dicabut kapan saja kalau terjadi apa-apa. Itu perilaku yang benar untuk aplikasi yang dipakai orang. Masalahnya, robot saya justru dirancang supaya tidak ada orangnya. Jadi selama tujuh hari pertama saya sebenarnya bukan sedang memakai alat yang salah pengaturannya, saya sedang memakai alat yang memang tidak diperuntukkan buat pekerjaan itu.

Yang saya dapat dari pindah ke Service Account bukan cuma empat belas hari tanpa gagal. Yang saya dapat adalah hilangnya satu pekerjaan rutin yang dulu diam-diam menempel ke saya setiap minggu, yaitu mengingat untuk login ulang sebelum hari kedelapan. Pekerjaan seperti itu tidak pernah kelihatan di laporan mana pun sampai pekerjaan itu terlewat sekali.

Tapi saya tidak mau menutupnya seolah semuanya beres. Kunci yang tidak pernah kedaluwarsa itu memindahkan bebannya, bukan menghapusnya. Dulu beban saya adalah mengingat, sekarang beban saya adalah menjaga satu berkas supaya tidak pernah bocor dan tidak pernah ikut terkirim ke mana-mana. Menurut saya itu pertukaran yang pantas, karena menjaga satu berkas jauh lebih mudah daripada mengandalkan ingatan manusia setiap tujuh hari. Tapi itu tetap pertukaran, bukan kemenangan gratis.

Kalau Anda sedang membangun sesuatu yang harus jalan sendiri, entah itu laporan otomatis, pencadangan berkala, atau sinkronisasi data antarsistem, pertanyaan yang saya sarankan Anda tanyakan di awal cuma satu. Waktu program ini berjalan nanti, apakah akan ada manusia yang bisa menekan tombol izinkan? Kalau jawabannya tidak, jangan tunggu sampai hari kedelapan seperti saya.

Tinggalkan komentar