Checklist Kepatuhan UU PDP untuk Fitur AI di Indonesia

Foto oleh Leonid Dzhepko via Wikimedia Commons (CC BY 3.0)
Ya. Pasal 16 ayat 1 Undang-Undang Nomor 27 Tahun 2022 mendefinisikan pemrosesan termasuk penganalisisan, transfer, penyebarluasan dan pengungkapan, dan sebuah prompt yang memuat data pelanggan adalah ketiganya sekaligus. Mengirimkannya ke provider di luar Indonesia juga merupakan transfer lintas negara menurut Pasal 56, jadi Anda butuh dasar pemrosesan sekaligus rute transfer yang bisa dijelaskan.
Perlakukan sebagai pertanyaan terpisah, karena tujuannya memang berbeda. Pasal 28 mewajibkan pemrosesan dilakukan sesuai tujuannya, dan memperbaiki model bersama bukan tujuan yang sama dengan menangani satu tiket pelanggan. Pada sebagian besar desain, tujuan kedua itu harus bersandar pada persetujuan eksplisit, dan Pasal 21 mengatur apa saja yang wajib disampaikan dalam pemberitahuannya.
Belum tentu, karena region penyimpanan dan region pemrosesan adalah dua pengaturan berbeda. Tabel data residency OpenAI mencantumkan Singapura dengan regional storage didukung tetapi regional processing tidak didukung, sedangkan di Azure deployment type Global boleh diproses di geography mana pun tempat model itu berjalan. Baca deployment type-nya dulu, lalu putuskan tingkat Pasal 56 mana yang sebenarnya Anda pakai.
Tulis satu fungsi penghapusan yang tahu semua tempat penyimpanan yang pernah dijangkau data itu: tabel Anda, prompt log dan response log, koleksi vektor, serta file atau objek yang Anda buat di sisi provider. Menghapus baris asal tidak menghapus embedding turunannya, dan payload di sebelah vektor biasanya masih memuat teks aslinya. Salinan abuse monitoring milik provider dan bobot model hasil fine-tune berada di luar jangkauan fungsi itu, jadi catat keduanya alih-alih berpura-pura sudah terjangkau.
Sering kali ya. Pasal 34 mewajibkan penilaian bila pemrosesan berpotensi risiko tinggi dan menyebut pemicu seperti pengambilan keputusan otomatis berdampak signifikan, pemrosesan skala besar, evaluasi atau penskoran sistematis, penggabungan kelompok data, dan penggunaan teknologi baru. Fitur yang mengirim data pelanggan ke sebuah model biasanya cocok dengan setidaknya satu pemicu, jadi rencanakan penilaiannya sebagai bagian dari rilis, bukan sebagai reaksi atas keluhan.

Foto oleh Leonid Dzhepko via Wikimedia Commons (CC BY 3.0)
Ringkasan Utama
Menurut UU PDP, Undang-Undang Nomor 27 Tahun 2022, mengirim data pelanggan ke model provider adalah pemrosesan dan sering kali juga transfer lintas negara. Karena itu setiap fitur AI butuh dasar pemrosesan sendiri, rute transfer yang terdokumentasi menurut Pasal 56, redaction di batas prompt, dan jalur penghapusan yang menjangkau log provider serta embeddings.
Fiturnya hanya tiga baris. Ambil isi tiket support dari tabel tickets, minta model membuat ringkasannya, lalu simpan ringkasan itu di sebelah tiket. Code review-nya selesai dalam satu pagi karena memang tidak ada yang perlu ditinjau: tidak ada tabel baru, tidak ada endpoint baru, tidak ada dependency baru. Pertanyaan yang menghentikannya justru datang dari orang yang sama sekali tidak membaca diff-nya. Teks keluhan itu berakhir di negara mana, dan siapa yang menyimpan salinannya?
Saya engineer, bukan pengacara, dan tulisan ini bukan nasihat hukum - keputusan yang membawa risiko tetap harus dibawa ke penasihat hukum. Yang ada di bawah ini adalah checklist yang sekarang saya jalankan sebelum sebuah fitur AI menyentuh data pribadi orang Indonesia, disusun berdasarkan teks Undang-Undang Nomor 27 Tahun 2022 dan dokumentasi retensi yang memang dipublikasikan para provider. Saya berasumsi Anda sudah tahu bentuk umum UU PDP. Panduan developer yang lebih umum di situs ini sudah membahas consent management, enkripsi dan notifikasi kebocoran, jadi saya tidak akan mengulangnya; tulisan ini khusus tentang permukaan baru yang dibawa fitur AI.
Pasal 16 ayat 1 mendefinisikan pemrosesan sebagai sebuah daftar, dan daftar itu lebih panjang daripada dugaan kebanyakan engineer. Isinya pemerolehan dan pengumpulan, pengolahan dan penganalisisan, penyimpanan, perbaikan dan pembaruan, penampilan, pengumuman, transfer, penyebarluasan atau pengungkapan, serta penghapusan atau pemusnahan. Dua entri dalam daftar itulah alasan fitur AI bukan fitur CRUD biasa.
Di situlah seluruh perbedaannya. Checklist kepatuhan database punya baris untuk tabel, backup, enkripsi at rest dan access log. Tidak ada barisnya untuk request HTTPS keluar yang membawa kalimat milik pelanggan ke perusahaan di yurisdiksi lain, karena waktu checklist itu ditulis, aplikasi bisnis biasa memang tidak rutin melakukannya. Sekarang aplikasi seperti itu melakukannya satu kali per tiket.
Pasal 20 ayat 1 menyatakan Pengendali Data Pribadi wajib memiliki dasar pemrosesan, dan ayat 2 menyebut enam pilihan: persetujuan eksplisit untuk satu atau beberapa tujuan tertentu, pemenuhan kewajiban perjanjian atau permintaan sebelum perjanjian dibuat, kewajiban hukum, pelindungan kepentingan vital, pelaksanaan tugas untuk kepentingan umum, dan kepentingan sah lainnya yang ditimbang terhadap hak Subjek Data Pribadi. Anda memilih satu per tujuan, bukan satu per sistem.
Menjalankan inference atas sebuah tiket support supaya agent yang menanganinya mendapat ringkasan masih masuk akal disebut tujuan yang sama dengan penanganan tiket itu, sehingga dasar perjanjian atau kepentingan sah yang sudah Anda pakai bisa menaunginya. Memakai tiket yang sama sebagai training data untuk model yang Anda fine-tune adalah tujuan yang berbeda sama sekali - kalimat pelanggan berhenti menjadi input bagi kasusnya sendiri dan berubah menjadi aset yang memperbaiki produk Anda untuk semua orang lain. Pasal 28 mewajibkan pemrosesan dilakukan sesuai tujuannya, jadi penggunaan kedua ini butuh jawabannya sendiri, dan pada sebagian besar desain jawabannya harus persetujuan. Pasal 21 lalu menyebut apa saja yang wajib disampaikan: legalitas pemrosesan, tujuannya, jenis dan relevansi data, jangka waktu retensi dokumen yang memuatnya, jangka waktu pemrosesan, dan hak Subjek Data Pribadi.
Konsekuensi praktisnya, kalimat kami sudah punya persetujuan hampir tidak pernah menjadi jawaban lengkap untuk fitur yang melakukan training. Tulis kedua pertanyaan itu terpisah. Dan ketika pertanyaan kedua ternyata sulit, sadari bahwa Anda boleh menjawabnya dengan tidak - training di atas teks pelanggan itu opsional dengan cara yang tidak berlaku untuk inference, dan menolaknya menghapus kewajiban, bukan menundanya.
Pasal 56 menyusun uji bertingkat untuk mengirim data pribadi ke luar wilayah hukum Indonesia, dan tingkatnya berurutan: Anda baru sampai ke tingkat kedua karena yang pertama gagal, dan ke tingkat ketiga karena keduanya gagal.
| Tingkat | Yang diwajibkan Pasal 56 | Artinya untuk fitur AI hari ini |
|---|---|---|
| Ayat 2 | Negara tempat kedudukan penerima punya tingkat pelindungan data pribadi setara atau lebih tinggi dari undang-undang ini | Belum ada daftar adequacy yang diterbitkan, jadi tidak ada yang bisa Anda tunjuk begitu saja |
| Ayat 3 | Jika tidak terpenuhi, harus ada pelindungan data pribadi yang memadai dan bersifat mengikat | Jalur kontrak. Data processing agreement dengan klausul transfer yang nyata, dan hampir semua model provider bermuara ke sini |
| Ayat 4 | Jika keduanya tidak terpenuhi, persetujuan Subjek Data Pribadi | Dialog persetujuan pada setiap ringkasan tiket bukan desain yang akan dirilis orang dua kali |
Ayat 5 menyerahkan rinciannya kepada Peraturan Pemerintah. Mahkamah Konstitusi meninjau kerangka ini dalam Putusan 137 PUU-XXIII 2025 yang dibacakan pada Januari 2026 dan menguatkannya, sekaligus menegaskan bahwa penilaian adequacy berada di ranah eksekutif, bukan parlemen. Itu menjawab siapa yang memutuskan. Itu tidak menghasilkan daftarnya, dan selama daftar itu belum ada, posisi paling jujur bagi sebagian besar tim di Indonesia adalah mengakui bahwa mereka bersandar pada ayat 3 dan sebaiknya sanggup menjelaskan pengamannya dengan lantang.
Menjelaskannya berarti menyebut di mana inference terjadi, dan di sinilah engineer sering terjebak, karena dokumentasi vendor memisahkan dua hal yang terdengar seperti satu. Data residency controls milik OpenAI mencantumkan Singapura sebagai sg.api.openai.com dengan regional storage didukung tetapi regional processing tidak didukung - hanya Amerika Serikat dan Eropa yang saat ini mendukung keduanya, dan Indonesia sama sekali tidak ada di daftar itu. Azure menarik garis yang sama dari sisi sebaliknya: prompt dan response diproses di dalam geography yang dipilih pelanggan kecuali deployment type-nya Global atau DataZone, dan deployment Global boleh diproses di geography mana pun tempat model itu tersedia. Memilih region penyimpanan terdekat lalu menganggap token-nya ikut berhenti di sana adalah kesalahannya.
Baca deployment type Anda sebelum membaca data processing agreement. Deployment Global di Azure, atau request tanpa prefix domain regional di OpenAI, berarti Anda tidak bisa menjawab pertanyaan yang diajukan Pasal 56 ayat 2, karena Anda tidak tahu negara mana yang menjalankan inference-nya. Konfigurasinya bisa diubah dalam satu sore. Pengungkapannya tidak bisa ditarik kembali.

Pasal 27 mewajibkan pemrosesan dilakukan secara terbatas dan spesifik, sah secara hukum, dan transparan. Di batas prompt, kalimat itu berhenti menjadi abstraksi dan berubah menjadi keputusan serialisasi. Yang praktis adalah men-stringify seluruh record, karena cuma satu ekspresi dan model memang membaca lebih baik dengan konteks. Yang patuh adalah allowlist per field, karena hanya versi itulah yang bisa Anda ceritakan dengan jujur di dalam record pemrosesan.
// Wrong: the whole row leaves, including columns nobody asked for.
const prompt = "Summarise this complaint:\n" + JSON.stringify(ticket);
// ticket also carries nik, phone, address, internal notes and an audit trail.
// Right: a field allowlist you can quote in the processing record, plus
// redaction for the free text you genuinely cannot drop.
const AI_SUMMARY_FIELDS = ["subject", "body", "productCode", "createdAt"] as const;
const REDACTIONS: Array<[RegExp, string]> = [
[/\b\d{16}\b/g, "[NIK]"], // 16-digit Indonesian national ID
[/\b(?:\+62|0)8\d{8,11}\b/g, "[PHONE]"], // Indonesian mobile numbers
[/\b[\w.+-]+@[\w-]+\.[\w.]{2,}\b/g, "[EMAIL]"],
];
const redact = (text: string) =>
REDACTIONS.reduce((s, [re, tag]) => s.replace(re, tag), text);
// The allowlist is the contract. Adding a field is a change to the
// processing record, not a one-line commit.
export function summaryPayload(ticket: Ticket) {
return Object.fromEntries(
AI_SUMMARY_FIELDS.map((f) => {
const v = ticket[f];
return [f, typeof v === "string" ? redact(v) : v];
}),
);
}Dua hal yang perlu Anda tahu sebelum bersandar pada ini. Redaction bukan pengganti allowlist - regular expression yang meleset pada format nomor telepon tak lazim tetap mengirim nomor itu, sementara field yang memang tidak pernah dipilih tidak mungkin bocor sama sekali. Dan allowlist itulah yang membuat catatan Pasal 31 bisa ditulis: Anda dapat menyebut persis kategori data pribadi mana yang keluar dari sistem untuk fitur ini, kalimat yang mustahil ditulis siapa pun kalau payload-nya adalah apa pun yang kebetulan dikembalikan ORM.
Letakkan allowlist di modul yang sama dengan client provider, dan jangan export apa pun selain itu. Kalau satu-satunya jalan menuju model adalah fungsi yang menerima payload yang sudah dipersempit, developer berikutnya tidak bisa melebarkan pengungkapan tanpa sengaja, dan diff yang melebarkannya dengan sengaja justru menjadi diff yang benar-benar dilihat reviewer.
Pasal 43 ayat 1 mewajibkan penghapusan ketika data tidak lagi diperlukan untuk tujuannya, ketika persetujuan ditarik, ketika Subjek Data Pribadi memintanya, atau ketika data diperoleh secara melawan hukum. Pasal 44 mengatur pemusnahan, dan penjelasan resminya mendefinisikan memusnahkan sebagai tindakan menghilangkan, melenyapkan atau menghancurkan data pribadi sehingga tidak lagi dapat dipakai mengidentifikasi Subjek Data Pribadi. Itu definisi tentang hasil akhir, bukan tentang satu perintah DELETE, dan kalimat itulah yang membuat penyimpanan sebuah fitur AI jadi merepotkan. Tiga tempat penyimpanan biasanya terlupakan.
Bagian yang merepotkan bukan keberadaan penyimpanan-penyimpanan itu. Yang merepotkan adalah masing-masing dibuat oleh bagian kode yang berbeda, pada waktu yang berbeda, sering oleh orang yang berbeda, sementara rutin penghapusannya ditulis sekali oleh siapa pun yang membangun yang pertama dan jarang ditengok lagi.
Mulai dari haknya dulu, karena tenggatnya pendek. Pasal 7 memberi Subjek Data Pribadi hak akses dan salinan datanya, dan Pasal 32 ayat 2 mewajibkan akses itu diberikan paling lambat 3 x 24 jam sejak permintaan diterima. Pasal 30 ayat 1 memberi tenggat 3 x 24 jam yang sama untuk memperbaiki data yang tidak akurat. Pasal 8 memberi hak mengakhiri pemrosesan, menghapus dan memusnahkan. Pasal 10 ayat 1 memberi hak mengajukan keberatan atas keputusan yang hanya didasarkan pada pemrosesan otomatis, termasuk pemrofilan, yang menimbulkan akibat hukum atau dampak signifikan - hak yang ada justru karena fitur seperti yang sedang Anda rilis.
// One function knows every store that ever saw this subject's data.
// The list grows; the function is the only place that has to know.
async function eraseSubject(subjectId: string) {
await db.transaction(async (tx) => {
await tx.delete(tickets).where(eq(tickets.customerId, subjectId));
await tx.delete(aiPromptLog).where(eq(aiPromptLog.subjectId, subjectId));
await tx.delete(aiResponseLog).where(eq(aiResponseLog.subjectId, subjectId));
});
// Embeddings are derived personal data. Deleting the source row does not
// touch them, and the payload stored beside the vector still holds the text.
await qdrant.delete("tickets", {
filter: { must: [{ key: "subjectId", match: { value: subjectId } }] },
});
// Provider-side objects you created yourself: files, vector stores,
// stored responses. These are yours to delete and nobody else's job.
for (const fileId of await listProviderFiles(subjectId)) {
await openai.files.del(fileId);
}
// What this function CANNOT reach. Record it, because Article 45 makes you
// tell the data subject that deletion happened, and this is the footnote.
await eraseAudit.record(subjectId, [
"provider abuse-monitoring copies",
"weights of any model fine-tuned on this text",
]);
}Pasal 45 kemudian mewajibkan Anda memberitahukan kepada Subjek Data Pribadi bahwa penghapusan atau pemusnahan itu sudah dilakukan, dan ternyata itu forcing function yang berguna. Anda tidak bisa mengirim pemberitahuan itu dengan jujur selama Anda tahu ada model hasil fine-tune yang masih membawa teks orang tersebut di dalam bobotnya.
Hak akses menurut Pasal 7 berbentuk sama dan layak dipikirkan terpisah. Anda bisa menjawab permintaan akses untuk database, log dan vector store Anda, karena ketiganya bisa di-query per subjek. Anda tidak bisa menjawabnya untuk sekumpulan bobot model - model hasil fine-tune tidak punya index, tidak punya baris untuk dikembalikan, dan tidak punya cara andal untuk menyatakan apakah teks orang tertentu ikut memengaruhinya. Ketimpangan itulah argumen praktis terkuat untuk tidak melakukan training di atas data pribadi sama sekali: ia mengubah pekerjaan teknis dua jam menjadi pekerjaan yang tidak terjawab, secara permanen.

Pasal 31 hanya satu kalimat: Pengendali Data Pribadi wajib melakukan perekaman terhadap seluruh kegiatan pemrosesan data pribadi. Seluruhnya. Pasal 47 mewajibkan Pengendali bertanggung jawab atas pemrosesan sekaligus mampu menunjukkan pertanggungjawaban itu, yaitu prinsip akuntabilitas yang punya gigi. Pasal 34 menambahkan penilaian dampak pelindungan data pribadi bila pemrosesan berpotensi risiko tinggi, dan daftar pemicunya terbaca seperti deskripsi sebuah fitur AI - pengambilan keputusan otomatis dengan akibat hukum atau dampak signifikan, pemrosesan dalam skala besar, evaluasi, penskoran atau pemantauan sistematis, pencocokan atau penggabungan kelompok data, dan penggunaan teknologi baru.
# processing-records/ai-ticket-summary.yaml
# One file per AI feature, in the repo, reviewed in the same pull request
# that changes the prompt.
feature: ai-ticket-summary
purpose: Summarise an inbound support ticket for the agent handling it
lawful_basis: contract # Art 20(2)(b) - handling the customer's own ticket
training_on_this_data: false # a separate purpose, deliberately not taken
data_sent:
fields: [subject, body, productCode, createdAt]
redacted_in_body: [nik, phone, email]
never_sent: [name, address, nik, payment_history]
provider:
endpoint: TODO
storage_region: TODO
inference_region_guaranteed: false # storage region is NOT processing region
transfer_basis: Art 56(3) binding safeguards, DPA signed TODO
provider_retention: abuse-monitoring logs, 30 days by default
our_stores:
prompt_log: 30 days, erased by eraseSubject
response_log: 30 days, erased by eraseSubject
embeddings: qdrant collection tickets, erased by eraseSubject
unreachable_by_erasure:
- provider abuse-monitoring copies
dpia_required: true # Art 34(2)(f) - use of new technologyMenyimpan catatan itu di dalam repository dan bukan di spreadsheet adalah satu-satunya versi yang tetap benar. Prompt berubah lewat pull request, catatannya berubah lewat pull request yang sama, dan reviewer yang melihat ada field baru di allowlist adalah reviewer yang sama yang melihat catatannya belum ikut diperbarui. Ketika akhirnya ada yang bertanya data pribadi apa yang dikirim fitur ini ke luar negeri dan atas dasar apa, jawabannya adalah sebuah file dengan riwayat git di belakangnya, bukan sebuah rapat.
Aturan yang saya bawa sekarang cukup pendek untuk diucapkan saat review: perlakukan prompt sebagai batas sistem. Semua yang melewatinya adalah pengungkapan yang Anda pilih untuk lakukan, kepada pihak yang harus Anda sebut namanya, di negara yang harus Anda identifikasi, ke dalam log yang sebagian besar tidak bisa Anda jangkau lagi setelahnya. Bangun fiturnya dengan cara itu dan pertanyaan UU PDP berhenti menjadi gerbang di ujung, lalu berubah menjadi dua file kecil yang memang akan Anda tulis - allowlist dan catatannya.
Sumber