DEV Community

Cover image for Keamanan Data Tamu Penginapan: Form Reservasi Patuh UU PDP dengan 6 Field Saja
Mightyblue
Mightyblue

Posted on

Keamanan Data Tamu Penginapan: Form Reservasi Patuh UU PDP dengan 6 Field Saja

Ada satu hal yang jarang dibahas saat membangun website penginapan kecil: form reservasinya hampir selalu meminta terlalu banyak.

Nomor KTP. Alamat rumah lengkap. Nama pasangan. Kadang foto identitas, diunggah ke folder yang bisa diakses siapa saja karena tidak ada yang pernah mengecek permission-nya.

Padahal regulasinya sedang bergerak cepat. Pemerintah kini sedang memfinalisasi pembentukan otoritas pelindungan data pribadi yang akan bekerja independen dan melaporkan hasilnya langsung kepada presiden.

Artinya pengawasan tidak akan berhenti di korporasi besar saja.

Dan di sinilah persoalannya jadi milik kita yang menulis kodenya: keamanan data tamu penginapan ternyata bukan urusan tim legal, melainkan urusan skema database dan cron job.


Ini bukan kekhawatiran yang dikarang-karang.

Kajian hukum di SHS Web of Conferences yang membedah reformasi lembaga pengawas pelindungan data pribadi di Indonesia menyimpulkan bahwa selama otoritas independen belum berdiri, fungsi pengawasan berjalan setengah hati — dan insiden kebocoran terus berulang.

Begitu lembaga itu benar-benar aktif, jarak antara "belum pernah ditegur" dan "sedang diaudit" akan menyempit drastis.

Saya mengangkat tema ini karena hampir semua tutorial form reservasi di internet berhenti di validasi input dan styling. Nyaris tidak ada yang membahas retensi, consent log, atau apa yang terjadi pada satu baris data enam bulan setelah tamu check-out. Padahal justru di situlah risiko sebenarnya menumpuk.


Yang akan Anda baca di bawah bukan ringkasan pasal.

Ini catatan implementasi: field mana yang dibuang, tabel apa yang ditambahkan, dan job apa yang harus berjalan tiap malam supaya data lama tidak menumpuk jadi liabilitas.

Semuanya bisa dikerjakan tanpa vendor compliance, tanpa DPO, dan tanpa menaikkan biaya hosting satu rupiah pun.

Kesimpulan yang akan Anda temui di akhir: kepatuhan UU PDP pada skala penginapan kecil bukan soal menambah halaman kebijakan privasi, melainkan soal mengurangi. Kurangi field, kurangi masa simpan, kurangi akses. Tiga pengurangan itu menyelesaikan sekitar 80% kewajiban teknis — dan sisanya hanya butuh satu tabel append-only serta satu cron job.

1. Apa yang Sebenarnya Diminta UU PDP dari Sebuah Form

Sebelum menyentuh kode, ada baiknya memisahkan mana kewajiban yang benar-benar menyentuh sistem dan mana yang cukup diselesaikan dokumen. Banyak developer melewatkan langkah ini, lalu berakhir menyalin template kebijakan privasi dari situs lain — sesuatu yang sama sekali tidak mengurangi risiko teknis apa pun.

Kewajiban yang Turun Langsung ke Kode

  • Purpose limitation — setiap field harus punya tujuan yang dinyatakan sebelum data dikumpulkan
  • Data minimization — dilarang mengumpulkan data yang tidak dibutuhkan untuk tujuan itu
  • Consent yang spesifik dan dapat dibuktikan — bukan satu checkbox untuk segalanya
  • Hak penghapusan — harus ada jalur teknis untuk menghapus, bukan sekadar janji
  • Retensi terbatas — data tidak boleh disimpan selamanya "kalau-kalau butuh"
  • Notifikasi insiden 3x24 jam — mustahil dipenuhi kalau Anda tidak tahu data apa saja yang tersimpan

Empat dari enam poin itu adalah keputusan skema, bukan keputusan legal.

Salah Kaprah: "Kami Kecil, Jadi Tidak Kena"

Undang-undangnya tidak mengenal ambang batas omzet atau jumlah kamar.

Yang membedakan hanyalah tingkat kewajaran pengamanan yang diharapkan. Penginapan dengan 12 kamar tidak dituntut punya SIEM. Tapi tetap dituntut tidak menyimpan scan KTP di folder /uploads yang bisa diindeks Google.

Perbedaan itu penting. Standar yang berlaku adalah proporsionalitas, bukan pengecualian.

2. Data Minimization: Memangkas Sampai Tersisa Enam Field

Cara paling cepat memperbaiki keamanan data tamu penginapan adalah dengan tidak mengumpulkannya sejak awal. Data yang tidak pernah masuk database tidak bisa bocor, tidak perlu dienkripsi, tidak perlu diaudit, dan tidak muncul dalam laporan insiden. Prinsip ini terdengar sepele, tapi efeknya paling besar dibanding kontrol lain mana pun.

Metode Audit "Untuk Apa Data Ini?"

Ambil form reservasi Anda sekarang. Untuk setiap field, jawab tiga pertanyaan berturut-turut:

  1. Proses operasional mana yang berhenti kalau field ini tidak ada?
  2. Bisakah proses itu berjalan dengan data yang lebih kasar? (kota, bukan alamat lengkap)
  3. Kapan data ini berhenti berguna?

Kalau pertanyaan pertama tidak punya jawaban konkret, field-nya dibuang. Tanpa diskusi.

Saya menjalankan audit ini pada form reservasi Lafa Park, penginapan berkonsep syariah di Cikarang Timur yang melayani keluarga, komunitas, dan pekerja proyek kawasan industri. Form awalnya punya sebelas field. Setelah audit, tersisa enam.

Tabel Keputusan Field

Field Tujuan Operasional Putusan Masa Retensi
Nama pemesan Identifikasi saat check-in Simpan 90 hari pasca check-out
Nomor WhatsApp Konfirmasi & perubahan jadwal Simpan 90 hari pasca check-out
Tanggal menginap Inti transaksi Simpan 90 hari pasca check-out
Jumlah tamu Alokasi kamar & sarapan Simpan 90 hari pasca check-out
Tipe kamar Inti transaksi Simpan 90 hari pasca check-out
Catatan khusus Aksesibilitas, alergi Simpan, opsional 30 hari pasca check-out
Alamat lengkap Tidak ada Hapus
Nomor KTP / NIK Tidak ada pada tahap booking Hapus
Upload foto identitas Tidak ada Hapus
Email Duplikasi kanal WhatsApp Hapus
Tanggal lahir Tidak ada Hapus

Lima field terakhir itu adalah lima cara berbeda untuk kehilangan tidur di malam hari.

Progressive Disclosure untuk Data yang Memang Wajib

Beberapa data identitas memang wajib dikumpulkan saat tamu tiba, sesuai ketentuan pencatatan tamu.

Kuncinya: kumpulkan di tempat dan waktu yang tepat. Data identitas dicatat di resepsionis, di sistem yang terpisah, dengan akses terbatas — bukan lewat form publik yang dilempar ke inbox WhatsApp dan mengendap di galeri ponsel karyawan selama bertahun-tahun.

Pisahkan data booking dari data check-in. Keduanya punya siklus hidup dan permukaan serangan yang sama sekali berbeda.

3. Consent Log: Persetujuan yang Bisa Dibuktikan

Checkbox "Saya setuju" tanpa jejak apa pun secara hukum sama nilainya dengan tidak ada persetujuan. Ketika regulator bertanya kapan tamu menyetujui dan menyetujui versi teks yang mana, jawaban "ada checkbox di form kami" tidak menyelesaikan apa-apa. Yang dibutuhkan adalah catatan yang tidak bisa diubah setelah dibuat.

Struktur Tabel Minimal

CREATE TABLE consent_events (
  id            BIGSERIAL PRIMARY KEY,
  booking_ref   TEXT        NOT NULL,
  purpose       TEXT        NOT NULL,  -- 'reservasi' | 'promosi'
  policy_version TEXT       NOT NULL,  -- '2026-03-11'
  granted       BOOLEAN     NOT NULL,
  occurred_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
  ip_hash       TEXT,                  -- SHA-256, bukan IP mentah
  user_agent    TEXT
);

-- Append-only: tidak ada UPDATE, tidak ada DELETE.
REVOKE UPDATE, DELETE ON consent_events FROM app_user;
Enter fullscreen mode Exit fullscreen mode

Perhatikan dua detail kecil yang sering dilewatkan.

purpose disimpan per baris, bukan satu kolom boolean untuk semuanya. Persetujuan reservasi dan persetujuan promosi adalah dua peristiwa berbeda, dan tamu berhak menyetujui satu tanpa yang lain.

ip_hash, bukan ip_address. Anda butuh bukti bahwa persetujuan datang dari sesi yang konsisten — bukan alamat IP tamu selamanya.

Versioning Teks Persetujuan

Simpan teks kebijakan sebagai file bertanggal di repositori, lalu referensikan versinya di policy_version.

Ketika kebijakan berubah, versi lama tidak dihapus. Tamu yang menyetujui versi Maret 2026 harus tetap bisa ditelusuri ke teks persis yang mereka lihat saat itu.

Ini praktik yang sama dengan migrasi database. Anda tidak menimpa migrasi lama; Anda menambahkan yang baru.

Tiga Kesalahan yang Paling Sering Muncul

  • Checkbox pre-checked — secara eksplisit dianggap dark pattern dan tidak menghasilkan persetujuan yang sah
  • Consent bundling — satu checkbox untuk reservasi dan newsletter dan berbagi data ke pihak ketiga
  • Tidak ada jalur pencabutan — jika mudah memberi persetujuan tapi sulit menariknya, persetujuannya cacat

4. Retensi Otomatis: Menghapus Tanpa Harus Ingat

Retensi adalah bagian yang paling sering dijanjikan di halaman kebijakan dan paling jarang diimplementasikan di server. Kalimat "kami menyimpan data Anda selama diperlukan" muncul di ribuan situs, dan di hampir semuanya artinya adalah "selamanya". Padahal justru inilah kontrol yang paling murah dibangun.

Menentukan Masa Retensi

Patokan yang masuk akal untuk penginapan kecil:

  • Data booking aktif → sampai check-out
  • Data pasca-menginap → 90 hari (untuk komplain, sengketa, atau tamu berulang)
  • Catatan khusus tamu → 30 hari, karena sering memuat informasi kesehatan
  • Consent log → 5 tahun, karena inilah bukti kepatuhan Anda
  • Log server berisi PII → 14 hari

Angka-angka itu bukan hasil tebakan. Tuliskan alasannya di README repositori, satu baris per kebijakan. Saat audit datang, dokumen itulah yang membedakan "kami punya kebijakan retensi" dari "kami lupa menghapus".

Cron Job atau TTL Database?

Untuk skala penginapan kecil, cron job harian sudah lebih dari cukup:

-- Jalankan 02:00 WIB setiap hari
UPDATE bookings
SET guest_name  = NULL,
    guest_phone = NULL,
    guest_notes = NULL,
    anonymized_at = now()
WHERE checkout_date < (CURRENT_DATE - INTERVAL '90 days')
  AND anonymized_at IS NULL;
Enter fullscreen mode Exit fullscreen mode

Yang dipertahankan hanyalah baris statistik: tanggal, tipe kamar, jumlah tamu. Cukup untuk laporan okupansi, tidak cukup untuk mengidentifikasi siapa pun.

Anonymization, Soft Delete, atau Crypto-Shredding?

Tiga pendekatan, tiga trade-off berbeda.

Anonymization paling sederhana dan cocok untuk mayoritas kasus — itu yang dipakai di query di atas.

Soft delete justru berbahaya di konteks ini. Baris yang ditandai deleted_at tetap ada di disk, tetap ada di backup, dan tetap masuk hitungan saat insiden terjadi. Ini penghapusan yang tidak menghapus.

Crypto-shredding menjadi menarik ketika Anda punya banyak backup historis: data dienkripsi per subjek, dan penghapusan dilakukan dengan membuang kuncinya. Pendekatan teknisnya dibahas cukup rinci oleh Lee Hambley dalam Using cryptography to protect PII in GDPR protected jurisdictions — tulisan lama yang tetap relevan karena membahas arsitektur, bukan library yang berumur pendek.

Untuk enam field dan satu database Postgres, anonymization sudah proporsional. Jangan over-engineer.

5. Panduan Implementasi: Dari Form Lama ke Form Patuh

Bagian ini bisa dieksekusi dalam satu sore. Urutannya sengaja dimulai dari yang paling menurunkan risiko, sehingga kalau Anda berhenti di tengah jalan, yang sudah dikerjakan tetap memberi manfaat terbesar. Inilah alur kerja yang saya pakai untuk membenahi keamanan data tamu penginapan pada proyek nyata.

Langkah demi Langkah

  1. Inventarisasi. Catat setiap field di form dan setiap tempat data itu mendarat: database, inbox WhatsApp, spreadsheet, folder upload. Biasanya jumlahnya mengejutkan.
  2. Pangkas field. Terapkan tabel keputusan di Bab 2. Hapus dari HTML dan dari skema database.
  3. Bersihkan data lama. Field yang baru saja dihapus masih punya isi di baris-baris lama. Jalankan UPDATE ... SET kolom = NULL sebelum DROP COLUMN.
  4. Pisahkan consent. Buat tabel consent_events yang append-only. Satu baris per tujuan.
  5. Tulis kebijakan retensi. Satu file markdown di repositori. Angka dan alasannya.
  6. Pasang cron anonymization. Uji di staging dengan data sintetis lebih dulu.
  7. Kunci akses. Nonaktifkan directory listing, batasi kredensial database ke satu akun aplikasi, aktifkan 2FA di panel hosting.
  8. Siapkan runbook insiden. Satu halaman, dibahas di Bab 6.

Skema HowTo untuk Halaman Dokumentasi

Kalau Anda mendokumentasikan prosedur ini di situs sendiri, sertakan structured data agar prosesnya terbaca mesin:

{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "Membangun Form Reservasi yang Patuh UU PDP",
  "totalTime": "PT4H",
  "step": [
    {
      "@type": "HowToStep",
      "position": 1,
      "name": "Inventarisasi aliran data",
      "text": "Petakan setiap field form dan setiap lokasi penyimpanannya."
    },
    {
      "@type": "HowToStep",
      "position": 2,
      "name": "Terapkan data minimization",
      "text": "Hapus field tanpa tujuan operasional dari HTML dan skema database."
    },
    {
      "@type": "HowToStep",
      "position": 3,
      "name": "Bangun consent log append-only",
      "text": "Catat tujuan, versi kebijakan, dan waktu persetujuan per baris."
    },
    {
      "@type": "HowToStep",
      "position": 4,
      "name": "Otomatiskan retensi",
      "text": "Jadwalkan cron harian untuk menganonimkan data melewati masa simpan."
    },
    {
      "@type": "HowToStep",
      "position": 5,
      "name": "Siapkan runbook insiden 72 jam",
      "text": "Dokumentasikan alur notifikasi sebelum insiden terjadi."
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

6. Runbook Insiden: Menyiapkan 3x24 Jam Sebelum Dibutuhkan

Kewajiban notifikasi dalam 3x24 jam sejak insiden diketahui terdengar longgar sampai Anda benar-benar mengalaminya. Tiga hari habis hanya untuk mencari tahu data apa saja yang tersimpan, siapa yang terdampak, dan siapa yang berhak mengumumkan. Runbook ini gunanya untuk memindahkan pekerjaan itu ke hari yang tenang.

Isi Minimal Satu Halaman

  • Inventaris data — tabel apa, kolom apa, PII apa. Sudah Anda buat di Langkah 1.
  • Query dampak — SQL siap pakai untuk menghitung berapa subjek yang terpapar dalam rentang waktu tertentu
  • Daftar kontak — siapa yang memutuskan, siapa yang menulis pengumuman, siapa yang bicara ke tamu
  • Template notifikasi — draf dalam Bahasa Indonesia, tinggal isi bagian spesifik insiden
  • Jam mulai — pencatat waktu "diketahui pertama kali", karena inilah titik nol hitungan 72 jam

Satu halaman. Simpan di repositori, bukan di kepala satu orang.

Notifikasi ke Subjek Data

Isinya tidak perlu panjang: data apa yang terpapar, kapan, apa risikonya bagi tamu, dan langkah apa yang sedang diambil.

Yang harus dihindari adalah menunda pengumuman sampai investigasi selesai. Regulasi menghitung sejak insiden diketahui, bukan sejak insiden dipahami sepenuhnya.

7. FAQ

Beberapa pertanyaan berikut muncul berulang kali ketika saya mendiskusikan topik ini dengan pemilik usaha maupun sesama developer. Jawabannya sengaja dibuat pendek dan operasional.

Apakah penginapan dengan di bawah 20 kamar tetap terikat UU PDP?

Ya. Undang-undangnya tidak memuat pengecualian berdasarkan ukuran usaha. Yang berbeda hanyalah ekspektasi kewajaran kontrol keamanan yang diterapkan.

Reservasi kami sepenuhnya lewat WhatsApp, apakah tetap perlu consent log?

Perlu. Kanal tidak mengubah status Anda sebagai pengendali data. Solusi praktisnya: arahkan tamu melalui satu halaman ringkas berisi persetujuan sebelum tautan wa.me dibuka, lalu catat peristiwanya.

Bagaimana memperbaiki keamanan data tamu penginapan kalau datanya sudah menumpuk bertahun-tahun di spreadsheet?

Ekspor, pangkas kolom yang tidak punya tujuan operasional, anonimkan baris di luar masa retensi, lalu hentikan penggunaan spreadsheet itu untuk data baru. Kerjakan berurutan, jangan sekaligus.

Apakah menyimpan foto KTP tamu benar-benar dilarang?

Tidak dilarang, tetapi termasuk kategori berisiko tinggi dan hampir tidak pernah dibutuhkan pada tahap booking. Kalau memang wajib untuk pencatatan tamu, kumpulkan di resepsionis, simpan terenkripsi, batasi akses, dan tetapkan masa retensi yang tegas.

Perlukah kami menunjuk Data Protection Officer?

Untuk penginapan kecil, umumnya tidak. Kewajiban DPO menyasar organisasi yang memproses data pribadi dalam skala besar atau data sensitif secara sistematis. Yang tetap wajib adalah menunjuk satu orang penanggung jawab yang tahu di mana datanya berada.

Kepatuhan yang Hidup di Repositori, Bukan di Halaman Kebijakan

Pada akhirnya, seluruh pekerjaan yang dibahas di artikel ini bermuara pada satu pergeseran cara pandang: berhenti memperlakukan privasi sebagai dokumen yang ditempel di footer, dan mulai memperlakukannya sebagai keputusan desain yang tertulis di migrasi database.

Sudut pandang itu bukan hal baru. Ann Cavoukian — mantan Information and Privacy Commissioner untuk provinsi Ontario, Kanada, dan pencetus kerangka kerja Privacy by Design yang kemudian diserap ke dalam GDPR — merumuskannya lewat satu prinsip yang sangat singkat:

"Privacy as the Default Setting."

Yang dimaksud bukan sekadar mengaktifkan opsi paling ketat. Maksudnya lebih tajam dari itu: perlindungan harus terjadi tanpa tamu perlu melakukan apa pun. Tidak ada checkbox yang harus dicari. Tidak ada pengaturan yang harus diubah. Tidak ada permintaan penghapusan yang harus diajukan.

Cron job yang menganonimkan data pada hari ke-90 adalah bentuk paling konkret dari prinsip itu di sebuah penginapan berukuran kecil. Tamu tidak pernah tahu job itu ada. Justru itulah intinya.

Dan kalau Anda memilih hanya satu hal untuk dikerjakan minggu ini, kerjakan Bab 2. Memangkas field adalah langkah termurah, tercepat, dan paling permanen dalam memperbaiki keamanan data tamu penginapan — karena data yang tidak pernah dikumpulkan tidak akan pernah bisa bocor.


Punya pengalaman membenahi form lama yang terlanjur mengumpulkan terlalu banyak data? Ceritakan pendekatan Anda di kolom komentar — terutama bagian yang paling merepotkan saat migrasi.

Top comments (0)