PDP: allowlist + HMAC, audit trail ≠ log operasional
Cara membersihkan log sistem yang terhubung ke SATUSEHAT, dan cara tetap bisa menjawab siapa mengakses data pasien
AuditEvent) dipisah dari log operasional, lalu merangkai seluruh modul PDP dalam jawaban ±90 detik:
kenapa → apa → di mana bocornya → bagaimana.
Di lesson 0024 dan 0025 Anda sudah tahu field mana yang 🔴, 🟡, 🟢 dan di mana biasanya bocor. Lesson ini menjawab bagaimana mencegahnya, lalu menutup modul dengan jawaban lisan 90 detik.
4. Bagaimana: allowlist di sumber, HMAC untuk korelasi (±6 menit)
| Teknik | Kapan | Catatan |
|---|---|---|
| Drop (default) | semua 🔴 | OWASP: "Never log data unless it is legally sanctioned." [1] |
| HMAC | 🟡 ID untuk korelasi | Bukan hash polos: hash ID "reversible in practice if the input space is small and predictable". [2] Secret HMAC di secret manager, terpisah dari log. |
| Potong | tanggal, IP | OTel: simpan hanya tahun atau tahun-bulan; buang oktet terakhir IPv4. [2] |
Dua prinsip. Allowlist, bukan denylist: resource FHIR bisa mendapat extension atau field baru kapan saja; denylist meloloskan apa pun yang belum pernah Anda bayangkan. Redaction processor di OTel Collector bekerja dengan cara ini: menghapus atribut "that don't match a list of allowed attributes". [2] Di sumber, bukan hanya di collector: data yang sudah keluar dari proses Node sudah melewati jaringan, buffer, dan mungkin vendor pihak ketiga.
// Hanya untuk dibaca: log handler FHIR dengan allowlist + HMAC (pino)
import pino from "pino";
import { createHmac } from "node:crypto";
const pseudo = (id: string) => // 🟡 ID korelasi, bukan nomor IHS mentah
createHmac("sha256", process.env.LOG_HMAC_KEY!).update(id).digest("hex").slice(0, 16);
const logger = pino({
redact: { paths: ["req.headers.authorization", "req.headers.cookie"], remove: true }, // jaring pengaman
});
// allowlist: HANYA field ini yang boleh keluar dari handler
logger.info({
route: "GET /Patient", // template, tanpa query string
resourceType: "Patient",
status: res.status,
durationMs,
patientRef: patientId ? pseudo(patientId) : undefined,
issueCodes: outcome?.issue?.map(i => i.code), // bukan diagnostics
}, "fhir request");
// ❌ logger.info(`search pasien ${nik}`) : redact tidak menyentuh isi string
Latihan 5 — Teknik
5. Audit trail ≠ log operasional (±4 menit)
Pertanyaan lanjutan yang hampir pasti datang: "Kalau log bersih, bagaimana tahu siapa membuka data pasien X?" Jawabannya dua jalur dengan tujuan berbeda.
| Log operasional | Audit trail | |
|---|---|---|
| Menjawab | kenapa lambat, kenapa error | siapa mengakses pasien mana, kapan, aksi apa |
| Identitas | tidak ada; ID hanya HMAC | ada, memang wajib |
| Bentuk | pino / OTel / Sentry | AuditEvent FHIR atau store setara |
| Proteksi | akses tim engineering, retensi pendek | append-only, akses terbatas |
AuditEvent ditujukan untuk "maintenance of security audit log information". Server umumnya tidak menerima update atau delete atasnya, dan aksesnya "typically be limited to security, privacy, or other system administration purposes". [3]
Dasar hukumnya: UU PDP Pasal 31 mewajibkan "perekaman terhadap seluruh kegiatan pemrosesan Data Pribadi" [4], dan UU Kesehatan Pasal 347 ayat (2) menyebut kebijakan hak akses dan audit berkala untuk Sistem Informasi Kesehatan. [5]
Latihan 6 — Audit vs log
Latihan 7 — Jawab lisan (±7 menit)
Pasang timer, jawab dengan suara keras seolah sedang interview, baru buka jawaban contoh. Soal terakhir adalah jawaban penutup modul PDP yang merangkai lesson 0024–0026; ulangi sampai lancar.
"Kalau log tidak boleh berisi identitas pasien, bagaimana Anda tahu siapa yang mengakses data pasien X?" (60 detik)
Bandingkan dengan jawaban contoh dan checklist-nya
"Itu dua kebutuhan berbeda, jadi dua jalur. Log operasional untuk debugging dan performa: tanpa identitas, ID pasien hanya dalam bentuk HMAC, retensi pendek, aksesnya tim engineering.
Audit trail untuk akuntabilitas: setiap akses ke data pasien dicatat sebagai AuditEvent, yaitu siapa, pasien mana, aksi apa, kapan, dari mana.
Store-nya append-only, tidak bisa di-update atau di-delete, dan hanya bisa dibaca tim keamanan atau privasi.
UU PDP Pasal 31 memang mewajibkan perekaman seluruh kegiatan pemrosesan, dan UU Kesehatan Pasal 347 menyebut audit berkala.
Jadi audit justru berisi identitas, tapi dilindungi seketat rekam medisnya. Kalau saya perlu menelusuri error untuk pasien X, saya hitung HMAC dari ID-nya lalu cari di log operasional."
Checklist: apakah Anda menyebut…
- dua kebutuhan berbeda: operasional vs akuntabilitas?
- log operasional: tanpa identitas, HMAC, retensi pendek?
- audit:
AuditEventberisi siapa, pasien mana, aksi, kapan? - audit append-only (tidak bisa update/delete), akses terbatas?
- dasar: UU PDP Pasal 31 (rekam kegiatan pemrosesan)?
- menelusuri pasien di log lewat HMAC dari ID-nya?
Lulus kalau minimal 4 dari 6.
"Data apa saja yang tidak boleh muncul di log atau monitoring sistem yang terhubung ke SATUSEHAT?" (90 detik)
Bandingkan dengan jawaban contoh dan checklist-nya
"Kenapa dulu: data kesehatan adalah data pribadi spesifik menurut UU PDP Pasal 4, isi rekam medis wajib dirahasiakan menurut Permenkes 24/2022, bahkan setelah pasien meninggal,
dan kalau bocor kami wajib memberi tahu pasien dan lembaga dalam 3×24 jam. Yang saya drop ada tiga kelompok.
Satu, identitas: NIK, KK, paspor, nomor rekam medis, nama, telepon, alamat, tanggal lahir lengkap.
Dua, isi klinis: diagnosis ICD-10 di Condition, hasil lab di Observation.value, obat KFA, catatan, dan narrative text.div.
Tiga, kredensial: client_secret dan bearer token SATUSEHAT. Logical id dan nomor IHS boleh masuk sebagai HMAC untuk korelasi.
Yang aman: resourceType, interaksi, status, latensi, issue.code.
Bocornya sering bukan dari body, tapi dari query search di URL, OperationOutcome.diagnostics, atribut trace, dan Sentry.
Caranya: allowlist di sumber, bukan denylist; dan siapa-mengakses-siapa dicatat di audit trail terpisah, bukan di log biasa."
Checklist: apakah Anda menyebut…
- kenapa: data kesehatan = data spesifik (UU PDP Pasal 4) + rahasia rekam medis (Permenkes 24/2022)?
- identitas: NIK/KK/paspor, No. RM, nama, telecom, alamat, tanggal lahir?
- isi klinis: diagnosis, hasil lab, obat, narrative
text.div? - kredensial:
client_secretdan bearer token? - di mana bocor: query search,
diagnostics, trace/Sentry? - bagaimana: allowlist + HMAC untuk ID korelasi, audit trail terpisah?
Lulus kalau minimal 4 dari 6.
Istilah: GLOSSARY.md (bagian "Pelindungan data pribadi") · Sumber: RESOURCES.md
Ada yang belum jelas? Tanyakan ke saya (agent) di terminal, misalnya: "apa beda pengendali dan prosesor kalau perusahaan saya vendor SIMRS?", "bagaimana mengonfigurasi OTel Collector supaya url.query dibuang?", atau "kalau pasien minta datanya dihapus, apakah log juga harus dihapus?"
Sumber (semua diakses 2026-10-27): [1] OWASP Logging Cheat Sheet · [2] OpenTelemetry: Handling sensitive data · [3] FHIR R4 AuditEvent · [4] UU No. 27 Tahun 2022 tentang Pelindungan Data Pribadi (PDF, BPK) · [5] UU No. 17 Tahun 2023 tentang Kesehatan (PDF, BPK)