Ringkasan cepat
  • Menghapus data dari tabel laporan itu mudah. Salinannya masih tersimpan di berkas ekspor, partisi mentah, dan ekspor lama yang bisa dimuat ulang.
  • Dalam demo 30 hari, 27 dari 27 permintaan hapus terverifikasi tuntas sampai lapisan mentah. Yang paling lambat selesai dalam 24,6 jam, dan rantai hash log auditnya utuh.
  • UU PDP dan PP 33/2026 tidak memberi tenggat untuk menghapus. Angka 72 jam di PoC ini adalah target internal. PP 33/2026 memberi 3 x 24 jam untuk memberitahukan penghapusan kepada subjek data, dan pemberitahuan itu belum dikirim oleh PoC ini.

Menghapus satu baris dari tabel laporan cukup dengan satu perintah. Salinan orang yang sama biasanya masih tersimpan di tempat lain: di berkas ekspor harian yang belum dibersihkan, di partisi data mentah, dan di ekspor lama yang siap dimuat ulang. Begitu ekspor lama itu dimuat ulang, datanya kembali.

Proof of concept (PoC) ini saya bangun untuk menguji pertanyaan berikut. Kalau seseorang meminta datanya dihapus, bisakah pipeline membuktikan bahwa datanya sudah hilang dari setiap lapisan, dan tetap hilang sesudah ekspor lama dimuat ulang?

Semua datanya sintetis. Pipeline ini melayani sebuah marketplace rekaan, dan tidak ada satu pun orang, perusahaan, atau catatan pelanggan sungguhan di dalamnya.

Tumpukan empat lembar kertas di meja. Dari lembar teratas, tabel laporan, satu baris sudah digunting dan diberi catatan pensil dihapus. Lewat lubangnya, baris orang yang sama masih terlihat distabilo di lembar bawah, dan tiga lembar yang menyembul di bawahnya, berkas ekspor, partisi mentah, dan ekspor lama, masing-masing masih memuat baris yang distabilo itu.

Gambar 1. Menghapus baris dari tabel laporan tidak menghapus salinannya. Orang yang sama masih ada di berkas ekspor, partisi mentah, dan ekspor lama.

Yang dibangun

Pipeline ini berjalan sekali sehari. Setiap hari sumber mengirim ekspor JSON yang sengaja dibuat kotor: pesanan dan event webhook ganda, zona waktu yang bercampur (WIB, WITA, WIT, UTC), lima format nomor telepon, serta spasi dan huruf kapital yang tercecer. Pipeline memuatnya ke Parquet secara idempoten, mencocokkan checksum dengan manifes ekspor dan skema dengan kontrak data, lalu mengolahnya dengan dbt di DuckDB menjadi tabel analitik. Setiap run menjalankan 61 uji.

Data mengalir lewat lima lapisan.

Lapisan Data pribadi Dibaca oleh
landing ya, apa adanya dari ekspor proses ingest; dibuang setelah 7 hari atau saat ada permintaan hapus
raw ya staging dbt, job penghapusan
staging ya, sudah dibersihkan pipeline saja
analyst pseudonim dan atribut yang digeneralisasi analis, dasbor
support tersamar; pelanggan yang sudah dihapus disaring layanan pelanggan

Berkas gudang datanya tidak menyimpan data pribadi dalam bentuk tabel, karena staging dan support hanya view di atas raw. Satu uji memindai setiap kolom teks di setiap tabel terhadap setiap nilai identitas yang pernah diekspor sumber. Uji itu juga dijalankan terhadap staging, yang memang berisi identitas, untuk memastikan pemindainya sanggup menemukan apa yang dicarinya.

Langkah yang sama bisa dijalankan dari baris perintah, dari Airflow 3 (satu task per langkah), dan dari CI GitHub Actions.

Yang diminta undang-undang

Lima ketentuan UU No. 27 Tahun 2022 tentang Pelindungan Data Pribadi membentuk rancangan ini:

  • Pasal 8: Subjek Data Pribadi berhak “mengakhiri pemrosesan, menghapus, dan/atau memusnahkan Data Pribadi tentang dirinya”.
  • Pasal 43 ayat (1) huruf c: Pengendali Data Pribadi wajib menghapus Data Pribadi dalam hal “terdapat permintaan dari Subjek Data Pribadi”.
  • Pasal 16 ayat (2) huruf g: Data Pribadi dimusnahkan dan/atau dihapus “setelah masa retensi berakhir atau berdasarkan permintaan Subjek Data Pribadi, kecuali ditentukan lain oleh peraturan perundang-undangan”.
  • Pasal 16 ayat (2) huruf h: pemrosesan “dilakukan secara bertanggung jawab dan dapat dibuktikan secara jelas”.
  • Pasal 45: pengendali wajib memberitahukan penghapusan dan/atau pemusnahan Data Pribadi kepada Subjek Data Pribadi.

Bagi pipeline, huruf h yang paling berat. Skrip apa pun bisa menghapus. Untuk membuktikan bahwa penghapusan sudah terjadi di semua lapisan, pipeline harus dirancang untuk itu sejak awal.

Peraturan Pemerintah Nomor 33 Tahun 2026, peraturan pelaksana UU PDP yang berlaku mulai 16 Januari 2027, merinci sembilan langkah minimal penghapusan dan pemusnahan dalam Pasal 86 ayat (2). Empat di antaranya punya padanan di PoC ini. Kebijakan penghapusan per entitas menentukan data yang dihapus (huruf a) sekaligus metodenya (huruf d): profil pelanggan dihapus, sedangkan kolom identitas di pesanannya dikosongkan. Pemindaian raw dan landing menemukan tempat data itu tersimpan (huruf b). Partisi raw ditulis ulang dan hari landing dibuang (huruf e), walaupun salinan di cadangan dan ruang kosong disk berada di luar cakupan PoC ini.

Dua langkah baru terpenuhi sebagian. Huruf g meminta audit berkala, sedangkan pemindaian ulang di PoC ini hanya dijalankan sekali sesudah setiap penghapusan. Log audit mencatat setiap penghapusan, tetapi PoC ini tidak menentukan apakah log itu cukup sebagai berita acara (huruf f). Tiga langkah belum ada sama sekali: pemisahan data sebelum dihapus supaya tidak ada yang terhapus tanpa sengaja (huruf c), pelaporan ke Lembaga kalau terjadi kegagalan selama proses (huruf h), dan evaluasi kebijakan penghapusan secara berkala (huruf i).

Perjalanan satu permintaan hapus

  1. Permintaan datang lewat ekspor erasure_requests dan dimuat seperti entitas lain. Catatan permintaannya tetap disimpan, karena catatan itulah bukti bahwa permintaan pernah diajukan.
  2. Pseudonim pelanggan dimasukkan ke daftar tekan (suppression list). Setiap ingest berikutnya menolak baris milik pseudonim di daftar itu, sehingga ekspor lama yang dimuat ulang tidak bisa mengembalikan datanya.
  3. Partisi raw ditulis ulang. Baris profil pelanggan dihapus. Baris pesanannya tetap disimpan, tetapi kolom identitasnya dikosongkan, karena Pasal 16 membuka kemungkinan aturan lain mewajibkan catatan transaksi disimpan. Aturan mana dan berapa lama, PoC ini tidak menentukannya.
  4. Hari-hari landing yang memuat pelanggan itu dibuang, tetapi baru setelah raw memegang salinan hari tersebut dengan checksum yang sama dengan manifes ekspor.
  5. raw dan landing dipindai ulang. Jumlah temuan beserta status complete atau partial dicatat ke log audit. Setiap entri log dirantai ke entri sebelumnya dengan SHA-256, dan orangnya hanya disebut lewat pseudonim. Uji memastikan bahwa pengubahan log terdeteksi.
  6. Build dbt berikutnya mengubah pelanggan itu menjadi nisan (tombstone) di dim_customers: pseudonimnya tetap, atributnya kosong, dan is_erased bernilai benar. Di tabel layanan pelanggan, ia tidak muncul lagi.

Hasil demo 30 hari ekspor (seed 42, tanggal rekaan 1 sampai 30 Januari 2026):

  • 27 dari 27 permintaan hapus terverifikasi tuntas. Yang paling lambat selesai dalam 24,6 jam.
  • Rantai hash log audit utuh di seluruh 27 entrinya.
  • 27 hari landing dibuang: satu karena masa retensinya habis, sisanya karena permintaan hapus. Tiga hari terakhir masih disimpan untuk pemuatan ulang.

Cetakan log audit berisi 27 entri penghapusan dari demo, semuanya berstatus complete. Hash tiap entri dilingkari pensil bersama prev_hash entri berikutnya, sehingga lingkarannya saling mengait menjadi rantai dari atas ke bawah. Entri yang paling lambat, 24,59 jam, distabilo, dengan catatan bahwa rantai hash log audit utuh di seluruh 27 entrinya.

Gambar 2. Log audit demo, 27 entri. Hash setiap entri tercatat lagi sebagai prev_hash entri berikutnya, sehingga pengubahan satu entri terdeteksi. Yang distabilo adalah entri paling lambat, 24,59 jam.

Dari mana angka 72 jam

Pasal 43 tidak menyebut berapa lama penghapusan boleh berlangsung, dan Pasal 45 juga tidak. Tenggat 3 x 24 jam baru muncul di pasal-pasal tetangganya:

  • Pasal 30 ayat (1): memperbarui dan/atau memperbaiki Data Pribadi.
  • Pasal 32 ayat (2): memberi akses kepada Subjek Data Pribadi.
  • Pasal 40 ayat (2): menghentikan pemrosesan setelah persetujuan ditarik kembali.
  • Pasal 41 ayat (1): menunda dan membatasi pemrosesan.
  • Pasal 46 ayat (1): menyampaikan pemberitahuan tertulis bila terjadi kegagalan Pelindungan Data Pribadi.

PP 33/2026 mengulang pola itu. Tenggat 3 x 24 jam dipasang untuk memperbaiki data (Pasal 71), memberi akses (Pasal 77), menghentikan pemrosesan setelah persetujuan ditarik (Pasal 92), serta menunda dan membatasi pemrosesan (Pasal 99). Untuk penghapusan, Pasal 87 ayat (6) hanya mensyaratkan bahwa penghapusan dilakukan setelah permohonan subjek data terverifikasi. Tenggat 3 x 24 jam baru muncul pada pemberitahuannya. Kalau penghapusan dilakukan atas permintaan subjek data, pengendali memberitahukannya setelah penghapusan (Pasal 87 ayat (4)), paling lambat 3 x 24 jam (Pasal 87 ayat (5)). Rincian mekanismenya diserahkan ke Peraturan Lembaga (Pasal 89), sementara per September 2026 Lembaga PDP sendiri belum terbentuk.

GDPR memberi ruang yang lebih longgar. Pasal 12 ayat (3) meminta pengendali memberi tahu subjek data tindakan yang diambil atas permintaannya tanpa penundaan yang tidak semestinya, paling lambat satu bulan sejak permintaan diterima. Bila perlu, tenggat itu bisa diperpanjang dua bulan lagi.

Karena itu, PoC ini memakai 72 jam sebagai target internal untuk menuntaskan penghapusan (ERASURE_TARGET_HOURS). Angka itu tidak dikutip sebagai kewajiban dari Pasal 43 atau dari PP 33/2026. Setiap entri log mencatat hours_to_fulfil, dan ops.pipeline_runs menghitung permintaan yang melewati target. Dalam demo, permintaan yang datang pada siang hari dipenuhi oleh run pukul 01.00 WIB berikutnya, sehingga yang paling lambat selesai dalam 24,6 jam.

Begitu PP 33/2026 berlaku, ada tenggat kedua yang harus dihitung: pemberitahuan kepada subjek data paling lambat 3 x 24 jam setelah penghapusan. PoC ini belum mengirim pemberitahuan itu.

Kekosongan tenggat yang sama muncul dalam hubungan dengan vendor. Pasal 88 PP 33/2026 mewajibkan pengendali memerintahkan penghapusan kepada prosesor sebelum memberi tahu subjek data, dan Pasal 139 ayat (2) meminta perintah itu dilaksanakan sesuai perjanjian antara keduanya. PP itu tidak menetapkan tenggat bagi prosesor, jadi tenggat tersebut hanya ada kalau ditulis di kontrak. Pembahasan kontraknya, termasuk status Lembaga PDP, ada di Dari Pasal ke Kontrak.

Pseudonim tetap data pribadi

Analis tidak melihat identitas. Kunci pelanggan diganti pseudonim HMAC-SHA256 (128 bit). Kuncinya disimpan di luar repositori dan tidak pernah ditulis ke disk, dan hal itu diuji. Tanpa kunci, run berhenti di tahap ingest. Atribut yang bisa menunjuk orang digeneralisasi menjadi bulan pendaftaran dan kelompok umur, dan uji k-anonimitas mensyaratkan setiap kelompok berisi minimal lima orang. Dalam demo, kelompok terkecil pelanggan yang berbagi jenis kelamin, kelompok umur, dan bulan pendaftaran berisi 103 orang. Uji itu juga gagal ketika memang seharusnya gagal: dengan 80 pelanggan sintetis, ia menemukan kelompok berisi kurang dari lima orang dan menghentikan build.

Meski begitu, data berpseudonim tetap data pribadi. Pasal 4 ayat (3) huruf f UU PDP menggolongkan “Data Pribadi yang dikombinasikan untuk mengidentifikasi seseorang” sebagai data pribadi yang bersifat umum. Recital 26 GDPR menyatakan bahwa data berpseudonim tetap informasi tentang orang yang dapat diidentifikasi.

Di PoC ini, fct_orders menyimpan waktu pesanan yang persis untuk setiap customer_key. Siapa pun yang mengetahui satu pesanan seseorang bisa menemukan pesanan-pesanannya yang lain. Pesanan pelanggan yang sudah dihapus pun masih berbagi satu pseudonim. Uji k-anonimitas hanya mencakup dim_customers.

Mutu data yang ikut diuji

  • 30 run harian, semuanya sukses, dengan total waktu pipeline 35 detik. Setiap run menjalankan 61 uji dbt, dan tidak satu pun gagal.
  • 38.320 baris dimuat. 104 pesanan ganda dan 301 event pembayaran ganda dibuang.
  • 2.291 dari 7.671 pesanan akan tercatat di tanggal yang salah seandainya stempel waktunya dibaca sebagai UTC, padahal seharusnya WIB.
  • Uji rekonsiliasi menangkap satu bug: run inkremental sesudah hari tanpa pesanan tidak memuat apa pun.

Yang tidak ditunjukkan PoC ini

  • Data sungguhan. Kotoran di ekspor adalah kotoran yang saya pilih untuk dibuat.
  • Pemberitahuan penghapusan kepada subjek data (Pasal 45 UU PDP, Pasal 87 PP 33/2026). Log audit sudah memuat sebagian bahannya, yaitu nomor permintaan, waktu, dan hasil. Pasal 87 ayat (2) PP 33/2026 meminta lebih, antara lain jenis data yang dihapus, alasan penghapusan, tanggal efektif, dan kontak pengendali. Pemberitahuannya tidak dikirim.
  • Verifikasi permohonan. Pasal 87 ayat (6) PP 33/2026 mensyaratkan permohonan terverifikasi sebelum penghapusan. Di PoC ini, setiap baris di ekspor erasure_requests dianggap sah.
  • Pemusnahan dalam arti PP 33/2026. PP itu membedakan penghapusan, yang membuat data tidak lagi dapat diakses selain oleh pengendali (Pasal 82 ayat (4)), dari pemusnahan, yang membuat data tidak lagi dapat dipakai untuk mengidentifikasi subjek data (Pasal 84 ayat (2)). Ekspor erasure_requests tidak membedakan keduanya, dan pesanan pelanggan yang dihapus masih disimpan dengan pseudonimnya.
  • Kontrol akses. DuckDB tidak menyediakan kontrol akses, sehingga skema di sini hanya memodelkan peran. Di BigQuery, peran ini akan menjadi dataset dengan IAM, authorized view, dan policy tag. Menegakkan akses di sistem perusahaan sungguhan adalah proyek tersendiri; lihat Kenapa “Cukup Satu Kali Login” Itu Proyek Bertahun-Tahun di Perusahaan Besar.
  • Log akses baca. Query dan tampilan dasbor oleh orang tidak tercatat, karena DuckDB tidak punya log akses. Pasal 31 meminta pengendali merekam seluruh kegiatan pemrosesan.
  • BigQuery. Makro dialek BigQuery sudah ditulis, tetapi belum pernah dijalankan di BigQuery.
  • Pemuatan ulang sesudah penghapusan. Penghapusan membuang hari landing secara utuh, sehingga 27 dari 30 hari tidak bisa lagi dimuat ulang dari landing.
  • Salinan di cadangan, snapshot, dan ruang kosong disk. Pemusnahan menurut Pasal 44 hanya dikerjakan pada berkas dan partisi.
  • Rotasi kunci. Mengganti kunci HMAC berarti mengganti semua pseudonim.
  • Skala. Job penghapusan memindai setiap partisi raw untuk setiap permintaan.
  • Airflow produksi. Tumpukan Docker Compose-nya berdiri sendiri dengan SQLite, dan callback tenggatnya hanya menulis log.
  • Nasihat hukum. Pemetaan pasal dalam PoC ini adalah bacaan seorang insinyur atas undang-undang, dan tidak dimaksudkan sebagai nasihat hukum.

Pertanyaan untuk pipeline Anda

Di mana saja salinan satu orang tersimpan, dan bagaimana tim Anda tahu bahwa semuanya sudah hilang? Kalau jawabannya berhenti di tabel laporan, penghapusan belum sampai ke lapisan mentah.

Tiga bagian PoC ini bisa ditiru tanpa mengganti tumpukan teknologi: kelas data pribadi di setiap kolom, daftar tekan yang diterapkan di setiap ingest, dan pemindaian ulang yang hasilnya dicatat di log yang pengubahannya bisa terdeteksi.

Rujukan

  1. Undang-Undang Nomor 27 Tahun 2022 tentang Pelindungan Data Pribadi. Teks per pasal: https://regulasiair.com/teks/uu-27-2022/. Teks resmi: https://peraturan.bpk.go.id/Details/229798/uu-no-27-tahun-2022.
  2. Peraturan Pemerintah Nomor 33 Tahun 2026 tentang Peraturan Pelaksanaan Undang-Undang Nomor 27 Tahun 2022 tentang Pelindungan Data Pribadi (Lembaran Negara Tahun 2026 Nomor 88). Ditetapkan 16 Juli 2026, berlaku 16 Januari 2027. Justisio: https://justisio.com/regulation/indonesia/dbwgcly3epltypka7sebq61yx.
  3. Regulation (EU) 2016/679 (General Data Protection Regulation). https://eur-lex.europa.eu/eli/reg/2016/679/oj.

Disclaimer: Tulisan ini adalah pandangan pribadi penulis sebagai praktisi profesional dan tidak mewakili sikap atau kebijakan resmi dari institusi/perusahaan tempat penulis bekerja.