Semua kontrol yang kita bangun di section ini — RBAC, enkripsi, masking — menghadapi satu pertanyaan praktis saat diterapkan: aturan mana yang berlaku untuk tabel dan kolom yang mana? TokoKita menyimpan ratusan kolom, dari deskripsi produk yang boleh dilihat siapa pun sampai NIK pelanggan yang harus dilindungi berlapis. Klasifikasi data menjawab dengan memberi label sensitivitas yang seragam: setiap aset diberi tingkat, dan setiap tingkat membawa aturan penanganan baku. Chapter ini menetapkan empat tingkat klasifikasi TokoKita, membangun skrip yang mengusulkan tingkat secara otomatis dari nama kolom dan pola nilainya, lalu menuangkan aturan penanganan per tingkat ke dalam tabel kebijakan.

Empat Tingkat Klasifikasi #

TingkatSiapa yang boleh melihatContoh aset TokoKita
Publicsiapa punkatalog produk, halaman promo, deskripsi barang
Internalseluruh karyawanlog operasional, metrik internal, kode pipeline
Confidentialtim tertentu dengan kebutuhan kerjariwayat pesanan, alamat kirim, email dan telepon pelanggan
Restrictedsedikit orang dengan alasan kuat, tercatatNIK, nomor kartu pembayaran, password_hash

Urutan tersebut menaik dalam kepekaan dan menurun dalam jumlah pemegang akses. Skema empat tingkat ini adalah pola yang umum di industri; kerangka luas seperti NIST Cybersecurity Framework menempatkan aktivitas seperti ini pada fungsi Identify — mengenal aset dan datanya sebelum mengamankan.

Klasifikasi Otomatis: Nama Kolom dan Pola Nilai #

Memberi label ratusan kolom secara manual lambat dan mudah terlewat. Skrip berikut memakai dua sinyal yang tersedia di setiap warehouse: nama kolom (nik, email, total_bayar) dan pola nilai contoh (16 digit untuk NIK, format email, angka uang). Kombinasi keduanya menghasilkan usulan tingkat untuk setiap kolom:

python
"""Demo ch7: klasifikasi otomatis kolom warehouse dari nama kolom + pola nilai."""
import re

# Skema mini warehouse TokoKita: (tabel, kolom, contoh nilai)
SKEMA = [
    ("produk", "nama_produk", "Kopi Gayo 250g"),
    ("produk", "harga", "75000"),
    ("pelanggan", "email", "[email protected]"),
    ("pelanggan", "nik", "3201234567890001"),
    ("pelanggan", "telepon", "081234567890"),
    ("pelanggan", "password_hash", "pbkdf2_sha256$600000$abcd1234"),
    ("pesanan", "alamat_kirim", "Jl. Merdeka No. 10, Bandung"),
    ("pesanan", "total_bayar", "245000"),
    ("produk", "deskripsi", "Biji kopi arabika dari Gayo, Aceh"),
]

# Sinyal dari nama kolom: kata kunci -> tingkat klasifikasi
KATA_KUNCI = {
    "nik": "Restricted",
    "password": "Restricted",
    "kartu": "Restricted",
    "email": "Confidential",
    "telepon": "Confidential",
    "alamat": "Confidential",
    "total": "Internal",
    "harga": "Internal",
    "nama": "Public",
    "deskripsi": "Public",
}

# Sinyal dari nilai: pola regex -> tingkat klasifikasi
POLA_NILAI = [
    (re.compile(r"^\d{16}$"), "Restricted"),                      # NIK 16 digit
    (re.compile(r"^[\w.+-]+@[\w-]+\.[\w.]+$"), "Confidential"),   # alamat email
    (re.compile(r"^0\d{9,12}$"), "Confidential"),                 # nomor telepon
    (re.compile(r"^\d+(\.\d{1,2})?$"), "Internal"),              # angka uang
]

TINGKAT_URUT = ["Public", "Internal", "Confidential", "Restricted"]


def klasifikasi_kolom(kolom: str, nilai: str) -> tuple[str, str]:
    """Kembalikan (tingkat usulan, sinyal yang memicu)."""
    kandidat: dict[str, str] = {}
    for kata, tingkat in KATA_KUNCI.items():
        if kata in kolom:
            kandidat[tingkat] = f"nama kolom mengandung '{kata}'"
    for pola, tingkat in POLA_NILAI:
        if pola.match(nilai):
            kandidat[tingkat] = "nilai cocok pola " + pola.pattern
    if not kandidat:
        return "Internal", "tidak ada sinyal, ambil default aman"
    # Pilih tingkat paling ketat di antara semua sinyal
    paling_ketat = max(kandidat, key=TINGKAT_URUT.index)
    return paling_ketat, kandidat[paling_ketat]


print(f"{'tabel':11}{'kolom':15}{'usulan':14}{'sinyal'}")
for tabel, kolom, nilai in SKEMA:
    tingkat, sinyal = klasifikasi_kolom(kolom, nilai)
    print(f"{tabel:11}{kolom:15}{tingkat:14}{sinyal}")

Output yang Dihasilkan:

text
tabel      kolom          usulan        sinyal
produk     nama_produk    Public        nama kolom mengandung 'nama'
produk     harga          Internal      nilai cocok pola ^\d+(\.\d{1,2})?$
pelanggan  email          Confidential  nilai cocok pola ^[\w.+-]+@[\w-]+\.[\w.]+$
pelanggan  nik            Restricted    nilai cocok pola ^\d{16}$
pelanggan  telepon        Confidential  nilai cocok pola ^0\d{9,12}$
pelanggan  password_hash  Restricted    nama kolom mengandung 'password'
pesanan    alamat_kirim   Confidential  nama kolom mengandung 'alamat'
pesanan    total_bayar    Internal      nilai cocok pola ^\d+(\.\d{1,2})?$
produk     deskripsi      Public        nama kolom mengandung 'deskripsi'

Mari kita telaah baris-baris kode di atas:

  1. Baris 5-15 (SKEMA): satu baris per kolom memuat nama kolom dan contoh nilai — struktur yang mudah diisi dari information_schema database sungguhan saat skala naik.
  2. Baris 32-37 (POLA_NILAI): pola regex berusaha menangkap bentuk data pribadi dari isinya; pola NIK 16 digit dan format email adalah dua contoh paling menonjol di data pelanggan Indonesia.
  3. Baris 51-52 (default): kolom tanpa sinyal apa pun diusulkan Internal, bukan Public — kegagalan deteksi jatuh ke arah yang lebih aman.
  4. Baris 54 (max(..., key=TINGKAT_URUT.index)): bila beberapa sinyal bersaing, kolom nik misalnya, tingkat paling ketat yang menang — prinsip yang sama dengan menaruh peringatan tertinggi saat ragu.

Perhatikan dua baris menarik pada keluaran: password_hash terdeteksi Restricted dari namanya meskipun isinya sudah berupa hash, dan total_bayar dianggap Internal dari polanya — dua contoh bahwa usulan otomatis adalah titik awal diskusi, bukan putusan akhir.

Usulan Bukan Keputusan Akhir #

Skrip di atas menghasilkan usulan; keputusan klasifikasi tetap milik pemilik data — orang yang memahami konteks bisnis kolom tersebut. Alur yang sehat berjalan dua tahap: skrip mengusulkan tingkat untuk seluruh schema, lalu pemilik data meninjau dan mengesahkan hasilnya. Hasil yang disahkan kemudian dicatat sebagai metadata agar query, pipeline, dan pembuat kebijakan dapat membacanya — pekerjaan yang bersinggungan dengan Chapter Data Catalog dan Data Ownership di ujung section ini.

Aturan Penanganan per Tingkat #

Label baru berarti apa-apa bila tidak membawa konsekuensi. Setiap tingkat harus terikat pada aturan penanganan yang bisa diperiksa otomatis:

TingkatEncryption at restEnvironment non-prodRetensiAkses
Publicopsionalbebastidak dibatasisiapa pun
Internalbawaan platformbebassesuai kebijakanseluruh karyawan
Confidentialwajibwajib masking atau tokenisasiterbatas dan ditinjaurole RBAC tertentu
Restrictedwajib dengan kunci terkelola KMSdilarang memakai data aslisependek mungkinper individu, tercatat

Dua kolom di kanan adalah tempat klasifikasi bertemu chapter-chapter sebelumnya: “wajib masking” merujuk teknik dari Masking dan Tokenization, “role RBAC tertentu” merujuk matriks dari Role-Based Access Control, dan penyimpanan kunci mengikuti Secrets Management. Bila data Restricted berpindah tabel lewat pipeline, jejak perpindahannya perlu bisa ditelusuri — kemampuan yang dibahas pada Chapter Data Lineage dan Provenance.

Klasifikasi juga menentukan nasib data di ujung umurnya: data Confidential dan Restricted tidak boleh disimpan selamanya hanya karena tidak ada yang berani menghapusnya. Berapa lama data boleh hidup, atas dasar hukum apa, dan bagaimana penghapusannya dijalankan adalah pokok bahasan Chapter Privasi dan Retensi Data.