Waarom Databricks PII Detectie Uniek is
Terwijl veel bedrijven handmatige scripts of third-party tools gebruiken voor PII detectie, biedt Databricks dit ingebouwd in het platform. Via Unity Catalog en Delta Live Tables heb je enterprise-grade PII detectie zonder extra kosten of complexe integraties.
Key Differentiators van Databricks PII Detectie
- Geïntegreerd in Unity Catalog: Centrale metadata management met PII tagging
- Automatische Scanning: Real-time PII detectie tijdens data ingestion
- Lineage Tracking: Volledige data lineage met PII flow tracking
- Policy Enforcement: Automatische policy enforcement op PII data
- Geen Extra Kosten: Onderdeel van Unity Catalog (Premium tier)
Databricks PII Detectie Architecture
Unity Catalog
- Centrale Metadata: Catalogus van alle data assets
- PII Tags: Automatische tagging van PII kolommen
- Access Policies: RBAC op PII geclassificeerde data
- Audit Logging: Wie heeft PII data bekeken?
Delta Live Tables
- Declaratieve Pipelines: ETL met ingebouwde quality checks
- PII Expectations: Data quality expectations voor PII
- Automatische Masking: Real-time PII masking in pipelines
- Monitoring: PII detectie metrics en alerts
Built-in PII Scanner
- Pre-trained Models: ML models voor PII detectie
- NLP-based Detection: Context-aware PII scanning
- Custom Patterns : Aanpasbare regex patterns
- Batch & Streaming: Real-time en batch scanning
Praktische Implementatie: PII Detectie in Databricks
Optie 1: Automatische PII Detectie met Unity Catalog
SQL: PII Kolommen Taggen in Unity Catalog
-- Stap 1: Enable Unity Catalog PII detectie
ALTER CATALOG main ENABLE PII_DETECTION = true;
-- Stap 2: Scan bestaande tabel voor PII
ALTER TABLE main.default.klant_data
SET TBLPROPERTIES ('pii_scan' = 'true');
-- Stap 3: Bekijk PII detectie resultaten
SELECT * FROM system.information_schema.column_pii_tags
WHERE table_catalog = 'main'
AND table_schema = 'default'
AND table_name = 'klant_data';
-- Resultaat:
-- | column_name | pii_type | confidence | suggested_tag |
-- |-------------|---------------|------------|------------------|
-- | bsn | ID_NUMBER | 0.98 | SENSITIVE_PII |
-- | email | EMAIL_ADDRESS | 0.95 | IDENTIFIER |
-- | naam | PERSON_NAME | 0.90 | IDENTIFIER |
-- | telefoon | PHONE_NUMBER | 0.92 | CONTACT_INFO |
-- Stap 4: Apply PII tags automatisch
CALL system.apply_pii_tags(
catalog_name => 'main',
schema_name => 'default',
table_name => 'klant_data',
auto_tag => true
);
-- Stap 5: Bekijk toegepaste tags
DESCRIBE TABLE EXTENDED main.default.klant_data;
Python: Programmatische PII Detectie
from databricks.sdk import WorkspaceClient
from databricks.sdk.service import catalog
import pandas as pd
class DatabricksPIIDetector:
"""PII detectie met Databricks Unity Catalog"""
def __init__(self, workspace_url, token):
self.w = WorkspaceClient(host=workspace_url, token=token)
def scan_table_for_pii(self, catalog_name, schema_name, table_name):
"""Scan een tabel voor PII met Unity Catalog"""
# Start PII scan
scan_request = catalog.ScanRequest(
table_name=f"{catalog_name}.{schema_name}.{table_name}",
scan_type="PII_DETECTION"
)
scan_result = self.w.catalog_scans.create(scan_request)
# Wacht op resultaat
while scan_result.state not in ['COMPLETED', 'FAILED']:
scan_result = self.w.catalog_scans.get(scan_result.scan_id)
time.sleep(2)
# Haal PII resultaten op
if scan_result.state == 'COMPLETED':
pii_findings = self.w.catalog_scans.get_pii_findings(scan_result.scan_id)
# Converteer naar DataFrame voor analyse
findings_df = pd.DataFrame([
{
'column': finding.column_name,
'pii_type': finding.pii_type,
'confidence': finding.confidence_score,
'sample_value': finding.sample_value,
'suggested_action': self._get_suggested_action(finding.pii_type)
}
for finding in pii_findings.findings
])
return findings_df
def _get_suggested_action(self, pii_type):
"""Bepaal aanbevolen actie gebaseerd op PII type"""
actions = {
'ID_NUMBER': 'MASK_OR_ENCRYPT', # BSN, paspoort, etc.
'EMAIL_ADDRESS': 'PSEUDONYMIZE',
'PHONE_NUMBER': 'MASK_PARTIAL',
'PERSON_NAME': 'PSEUDONYMIZE_IF_SENSITIVE',
'LOCATION': 'GENERALIZE',
'CREDIT_CARD': 'ENCRYPT_OR_TOKENIZE',
'IBAN': 'MASK_FULL'
}
return actions.get(pii_type, 'REVIEW_MANUALLY')
def apply_pii_policy(self, catalog_name, schema_name, table_name, findings_df):
"""Pas PII policies toe gebaseerd op detectie resultaten"""
for _, row in findings_df.iterrows():
if row['confidence'] > 0.8: # Alleen hoge confidence
# Creëër column mask policy
mask_policy = catalog.MaskingPolicy(
name=f"mask_{row['pii_type'].lower()}",
function_name="MASK",
function_params={"mask_char": "X"}
)
# Apply policy to column
self.w.catalog_tables.set_column_mask(
table_name=f"{catalog_name}.{schema_name}.{table_name}",
column_name=row['column'],
policy_name=mask_policy.name
)
print(f"Applied mask policy to column: {row['column']}")
# Gebruik
detector = DatabricksPIIDetector(
workspace_url="https://your-workspace.cloud.databricks.com",
token="your-personal-access-token"
)
# Scan voor PII
findings = detector.scan_table_for_pii("main", "default", "klant_data")
# Toon resultaten
print(f"Found {len(findings)} PII columns")
print(findings)
# Pas policies toe
detector.apply_pii_policy("main", "default", "klant_data", findings)
Delta Live Tables: PII-aware ETL Pipelines
Declaratieve PII Pipeline met DLT
Python DLT Pipeline met PII Detectie
import dlt
from pyspark.sql.functions import *
from pyspark.sql.types import *
from databricks.feature_store import PIIDetection
# Initialize PII detector
pii_detector = PIIDetection()
@dlt.table(
name="bron_klant_data",
comment="Bron klant data met PII detectie",
table_properties={
"quality": "bronze",
"pii_scan_enabled": "true"
}
)
def bron_klant_data():
"""Laad bron data en detecteer PII"""
df = spark.read.format("csv") \
.option("header", "true") \
.load("/mnt/bron/klanten/*.csv")
# Voeg PII detectie metadata toe
df_with_pii = pii_detector.detect(df)
return df_with_pii
@dlt.table(
name="gemaskeerde_klant_data",
comment="Klant data met gemaskeerde PII",
table_properties={
"quality": "silver",
"pii_masked": "true"
}
)
@dlt.expect_or_drop("valid_bsn", "bsn RLIKE '^[0-9]{9}$' OR bsn IS NULL")
@dlt.expect_or_drop("valid_email", "email LIKE '%@%' OR email IS NULL")
def gemaskeerde_klant_data():
"""Mask PII voor interne gebruik"""
df = dlt.read("bron_klant_data")
# Mask PII kolommen
df_masked = df \
.withColumn("bsn_masked",
when(col("pii_tag") == "SENSITIVE_PII",
regexp_replace(col("bsn"), r"\d", "X"))
.otherwise(col("bsn"))) \
.withColumn("email_masked",
when(col("pii_tag") == "IDENTIFIER",
regexp_replace(col("email"), r"(?<=.).(?=.*@)", "*"))
.otherwise(col("email"))) \
.withColumn("telefoon_masked",
when(col("pii_tag") == "CONTACT_INFO",
regexp_replace(col("telefoon"), r"\d{6}", "******"))
.otherwise(col("telefoon")))
return df_masked
@dlt.table(
name="geaggregeerde_analyses",
comment="Geaggregeerde data zonder PII voor analytics",
table_properties={
"quality": "gold",
"pii_removed": "true"
}
)
def geaggregeerde_analyses():
"""Geaggregeerde data zonder PII"""
df = dlt.read("gemaskeerde_klant_data")
# Aggregeer zonder PII
aggregated = df \
.groupBy(
"postcode_prefix", # Alleen eerste 2 cijfers
"leeftijdsgroep",
"klant_segment"
) \
.agg(
count("*").alias("aantal_klanten"),
sum("totaal_omzet").alias("totaal_omzet"),
avg("gemiddelde_order").alias("gemiddelde_order")
)
return aggregated
@dlt.view(
name="pii_audit_log",
comment="Audit log van PII detectie en masking"
)
def pii_audit_log():
"""Genereer audit log van PII verwerking"""
bronze = dlt.read("bron_klant_data")
audit_log = bronze \
.select(
current_timestamp().alias("audit_timestamp"),
"pii_tag",
"pii_type",
"confidence_score",
count("*").over(Window.partitionBy("pii_type")).alias("aantal_detecties")
) \
.distinct()
return audit_log
# Pipeline configuration
pipeline_config = {
"name": "PII Compliant Data Pipeline",
"storage": "/mnt/dlt/pii_pipeline",
"target": "main.default",
"configuration": {
"pipelines.enablePIIDetection": "true",
"pipelines.autoTagPII": "true",
"pipelines.piiMaskingPolicy": "auto",
"quality.expectations.enforce": "true"
},
"libraries": [
{"pypi": {"package": "databricks-feature-store"}}
],
"continuous": False,
"development": True
}
DLT PII Voordelen
- Declaratieve Syntax: Eenvoudig te begrijpen en onderhouden
- Automatische Lineage: Volledige PII flow tracking
- Built-in Quality: Expectations voor PII validatie
- Real-time Masking: PII masking tijdens pipeline execution
- Audit Logging: Automatische audit logs genereren
Pipeline Monitoring
- PII Detection Metrics: Aantal gevonden PII kolommen
- Masking Effectiveness: Percentage succesvol gemaskeerd
- Compliance Score : Automatische compliance scoring
- Alerting: Notificaties bij PII detectie issues
Automatische GDPR/AVG Compliance met Databricks
| GDPR Requirement | Databricks Feature | Implementatie | Automatisatie Niveau |
|---|---|---|---|
| Data Inventory (Artikel 30) | Unity Catalog + Lineage | Automatische catalogisering van alle data | ✅ Volledig geautomatiseerd |
| PII Detectie | Built-in PII Scanner | ML-based detectie van 50+ PII types | ✅ Volledig geautomatiseerd |
| Access Control (Artikel 32) | Unity Catalog RBAC | Fine-grained toegangscontrole op PII data | ✅ Volledig geautomatiseerd |
| Data Minimization | Delta Live Tables + Expectations | Automatische validatie van data minimalisatie | 🟡 Semi-automatisch |
| Right to Erasure (Artikel 17) | Delta Time Travel | Automatische data deletion met audit trail | ✅ Volledig geautomatiseerd |
| Audit Logging (Artikel 30) | Audit Logs + Table History | Volledige audit trail van alle PII access | ✅ Volledig geautomatiseerd |
Automatische GDPR Compliance Dashboard
-- SQL: GDPR Compliance Dashboard Query
WITH pii_inventory AS (
SELECT
tc.catalog_name,
tc.schema_name,
tc.table_name,
COUNT(DISTINCT c.column_name) as total_columns,
SUM(CASE WHEN ct.tag_name = 'SENSITIVE_PII' THEN 1 ELSE 0 END) as sensitive_pii_columns,
SUM(CASE WHEN ct.tag_name = 'IDENTIFIER' THEN 1 ELSE 0 END) as identifier_columns
FROM system.information_schema.tables tc
JOIN system.information_schema.columns c
ON tc.catalog_name = c.table_catalog
AND tc.schema_name = c.table_schema
AND tc.table_name = c.table_name
LEFT JOIN system.information_schema.column_tags ct
ON c.table_catalog = ct.catalog_name
AND c.table_schema = ct.schema_name
AND c.table_name = ct.object_name
AND c.column_name = ct.column_name
WHERE tc.table_type = 'BASE TABLE'
GROUP BY 1, 2, 3
),
access_audit AS (
SELECT
table_catalog,
table_schema,
table_name,
COUNT(DISTINCT user_name) as unique_users,
COUNT(*) as total_accesses,
MIN(event_time) as first_access,
MAX(event_time) as last_access
FROM system.access.audit
WHERE service_name = 'databricks-sql'
AND action_name IN ('SELECT', 'SHOW', 'DESCRIBE')
GROUP BY 1, 2, 3
),
compliance_score AS (
SELECT
pi.catalog_name,
pi.schema_name,
pi.table_name,
-- Bereken compliance score (0-100)
CASE
WHEN pi.sensitive_pii_columns = 0 THEN 100 -- Geen PII = perfect
WHEN aa.table_name IS NULL THEN 50 -- PII maar geen monitoring
WHEN pi.sensitive_pii_columns > 0
AND aa.unique_users <= 3 THEN 90 -- Beperkte toegang tot PII
ELSE 70 -- Default score
END as compliance_score,
-- Compliance status
CASE
WHEN pi.sensitive_pii_columns = 0 THEN 'COMPLIANT'
WHEN pi.sensitive_pii_columns > 0
AND aa.unique_users <= 3 THEN 'COMPLIANT'
ELSE 'REVIEW_REQUIRED'
END as compliance_status
FROM pii_inventory pi
LEFT JOIN access_audit aa
ON pi.catalog_name = aa.table_catalog
AND pi.schema_name = aa.table_schema
AND pi.table_name = aa.table_name
)
SELECT
catalog_name,
schema_name,
COUNT(*) as total_tables,
SUM(CASE WHEN compliance_status = 'COMPLIANT' THEN 1 ELSE 0 END) as compliant_tables,
AVG(compliance_score) as avg_compliance_score,
MIN(compliance_score) as min_compliance_score,
MAX(compliance_score) as max_compliance_score
FROM compliance_score
GROUP BY 1, 2
ORDER BY avg_compliance_score DESC;
Kosten en ROI voor MKB
Kosten Breakdown
- Unity Catalog Premium: €0.20/DBU extra
- PII Detectie: Inbegrepen bij Unity Catalog
- Delta Live Tables: €0.30/DBU (pipeline compute)
- Storage: €0.02/GB/maand (Delta format)
- Totaal MKB Maand: €500-€2.000
ROI Berekenen
- Handmatige PII Scanning: 20 uur/maand × €100 = €2.000
- GDPR Consultancy: €5.000-€20.000/jaar
- Boete Risico: €50.000+ per incident
- Totaal Besparing: €7.000-€25.000/jaar
- ROI Periode: 3-6 maanden
Niet-Financiële Voordelen
- Reputatiebescherming: Voorkom datalekken
- Klantvertrouwen: Bewijs van compliance
- Operational Efficiency: Minder handmatig werk
- Scalability: Automatisch meegroeien met data
MKB Implementatie Tips
- Start Small: Begin met 1-2 kritieke tabellen
- Use Auto-tagging: Laat Unity Catalog automatisch tags toepassen
- Implementeer gefaseerd: Bronze → Silver → Gold approach
- Monitor compliance score: Gebruik het dashboard hierboven
- Train team: Zorg dat iedereen de tools begrijpt
Best Practices voor Productie
Aanbevolen Configuratie
Unity Catalog Setup
-- 1. Enable PII detection
ALTER CATALOG main SET DBPROPERTIES (
'pii.detection.enabled' = 'true',
'pii.auto.tagging' = 'true',
'pii.retention.days' = '90'
);
-- 2. Create PII-specific schemas
CREATE SCHEMA main.sensitive_data
COMMENT 'Schema voor PII data';
CREATE SCHEMA main.analytics
COMMENT 'Schema voor gemaskeerde analytics data';
-- 3. Set default permissions
GRANT USAGE ON SCHEMA main.sensitive_data
TO ROLE data_engineers;
GRANT SELECT ON SCHEMA main.analytics
TO ROLE business_users;
DLT Pipeline Config
{
"pipeline": {
"name": "pii_compliant_pipeline",
"storage": "/mnt/dlt/production",
"target": "main.production",
"configuration": {
"pii.detection.threshold": "0.8",
"pii.masking.strategy": "partial",
"quality.enforcement": "strict",
"lineage.tracking": "full"
},
"libraries": [
{"maven": {"coordinates": "com.databricks:databricks-pii:1.0.0"}}
],
"development": false,
"continuous": true,
"photon": true
}
}
Veelgemaakte Fouten
- Te lage threshold: Te veel false positives
- Geen review proces: Blind vertrouwen op auto-tagging
- Vergeten te monitoren: Compliance score niet bijhouden
- Geen backup policy: PII data zonder retentie policy
- Shared service accounts: Geen individual accountability
Success Factoren
- Start met assessment: Eerst inventariseren, dan automatiseren
- Betrek stakeholders: Legal, compliance, business
- Implementeer iteratief: Kleine successen vieren
- Documenteer alles: Policies, procedures, exceptions
- Train continu: Regelmatige awareness training
Nederlandse Specifieke Implementatie
Nederlandse PII Patterns voor Databricks
-- Aangepaste PII patterns voor Nederlandse data
CREATE OR REPLACE FUNCTION main.default.detect_dutch_pii(value STRING)
RETURNS STRUCT
LANGUAGE PYTHON
AS $$
import re
def detect(value):
if not value:
return {'pii_type': None, 'confidence': 0.0}
# BSN (9 cijfers, mag niet met 0 beginnen)
if re.match(r'^[1-9][0-9]{8}$', str(value)):
return {'pii_type': 'BSN_NUMBER', 'confidence': 0.99}
# IBAN (NL formaat)
if re.match(r'^NL[0-9]{2}[A-Z]{4}[0-9]{10}$', str(value).replace(' ', '')):
return {'pii_type': 'IBAN_NUMBER', 'confidence': 0.98}
# Postcode (4 cijfers, 2 letters, geen 'SA', 'SD', 'SS')
if re.match(r'^[1-9][0-9]{3}\s?[A-Z]{2}$', str(value).upper()):
postcode = str(value).upper().replace(' ', '')
if postcode[4:] not in ['SA', 'SD', 'SS']: # Niet-bestaande combos
return {'pii_type': 'POSTCODE_NL', 'confidence': 0.95}
# Kenteken (huidig formaat: 8-XXX-9)
if re.match(r'^[0-9]{2}-[A-Z]{3}-[0-9]{2}$', str(value).upper()):
return {'pii_type': 'LICENSE_PLATE_NL', 'confidence': 0.90}
# KVK nummer (8 cijfers)
if re.match(r'^[0-9]{8}$', str(value)):
return {'pii_type': 'KVK_NUMBER', 'confidence': 0.92}
# BTW nummer (NL + 9 cijfers + B + 2 cijfers)
if re.match(r'^NL[0-9]{9}B[0-9]{2}$', str(value).upper()):
return {'pii_type': 'BTW_NUMBER', 'confidence': 0.97}
return {'pii_type': None, 'confidence': 0.0}
return detect(value)
$$;
-- Gebruik de functie in een query
SELECT
column_name,
main.default.detect_dutch_pii(column_name) as pii_detection
FROM (
VALUES
('123456789'), -- BSN
('NL12ABNA1234567890'), -- IBAN
('1234AB'), -- Postcode
('12-ABC-34'), -- Kenteken
('12345678'), -- KVK
('NL123456789B01') -- BTW
) AS test_data(column_name);
-- Maak een PII detection pipeline specifiek voor NL data
CREATE OR REPLACE TABLE main.production.nl_pii_inventory AS
SELECT
tc.catalog_name,
tc.schema_name,
tc.table_name,
c.column_name,
d.pii_type,
d.confidence,
CASE
WHEN d.pii_type IN ('BSN_NUMBER', 'IBAN_NUMBER') THEN 'SENSITIVE_PII'
WHEN d.pii_type IN ('POSTCODE_NL', 'KVK_NUMBER') THEN 'IDENTIFIER'
ELSE 'NON_PII'
END as classification
FROM system.information_schema.columns c
JOIN system.information_schema.tables tc
ON c.table_catalog = tc.table_catalog
AND c.table_schema = tc.table_schema
AND c.table_name = tc.table_name
CROSS JOIN LATERAL (
SELECT
main.default.detect_dutch_pii(
SUBSTR(c.data_type, 1, 50)
) as detection
) d
WHERE tc.table_schema NOT IN ('information_schema', 'system')
AND d.detection.pii_type IS NOT NULL;
Conclusie: Enterprise PII Detectie voor MKB Prijs
Samenvatting Voordelen
Technische Voordelen
- Geïntegreerd Platform: Geen complexe integraties nodig
- ML-powered Detectie: Hogere accuracy dan regex alleen
- Real-time Processing: Zowel batch als streaming
- Automatische Lineage: Volledige PII flow tracking
Business Voordelen
- GDPR Compliance: Bewijs van compliance voor auditors
- Kostenefficiënt : Minder handmatig werk, minder consultancy
- Schalbaar: Groeit automatisch met je data
- Future-proof: Regelmatige updates van Databricks
MKB Specifiek
- Betaalbaar: Enterprise features voor MKB budget
- Eenvoudig te starten: Minimaal setup nodig
- Nederlandse support: Lokale expertise beschikbaar
- Praktische templates: Direct toepasbare code
Jouw Volgende Stappen
Stap 1: Gratis Databricks Workshop
Meld je aan voor onze gratis "Databricks PII & GDPR" workshop speciaal voor MKB.
Stap 2: Proof of Concept
Start met een 30-dagen PoC op Databricks (gratis credits beschikbaar).
Stap 3: Gefaseerde Implementatie
Implementeer eerst Unity Catalog PII detectie, dan DLT pipelines.
"Met Databricks' ingebouwde PII detectie kan elk MKB-bedrijf enterprise-grade GDPR compliance bereiken zonder enterprise budget. Het is niet langer een kwestie van 'of' je PII detectie implementeert, maar 'hoe snel' je de ingebouwde tools van Databricks gaat gebruiken."