Access and Privacy
Productive exactly as far as it is safe
Access and privacy in BI: least-privilege models, row-level security, PII controls, audit logs, and compliance maps — data is productive exactly as far as it is safe.
What you will learn
- Model access with least privilege and row-level security
- Define PII controls and masking
- Keep audit and compliance story clean
What is this?
Access and privacy govern who can see what, how PII is handled, and what can be audited: least-privilege roles, row-level security so a rep sees only their territory, column-level controls so PII never renders, masking for exploratory layers, audit logs tying every view to a person, and a compliance map (who, what, when) that survives a regulator's question. The principle: data is productive exactly as far as it is safe.
Why do you need it?
- A rep with every region's revenue is a privacy incident waiting to occur.
- PII on every exploratory dashboard is how breaches get discovered.
- Audit logs are what make 'who saw what' answerable after the fact.
- Access design is a first-class BI deliverable, not legal's footnote.
Mental model
A building's key ring
BI access
The office gives you keys to your floor, not the server room; a badge trail logs every door. Nobody has the master ring, and the log answers 'who was here at 2am?'. Data access is key control: least privilege per role, row/column per person, and a badge trail that survives scrutiny.
How it works
- Roles: least-privilege model — analyst, rep, leader, exec — each with its scope.
- Row-level security: per-row predicates (territory = user) baked into reports.
- Column controls: PII columns masked or excluded outside approved roles.
- Audit: every dashboard view logged with actor, artifact, time, filter.
- Compliance map: PII inventory, retention, and deletion paths; regulator-ready.
Access, controls and the audit trail.
Examples
RLS and PII story
REP role sees own territory rows only RLS predicate: territory = current_user()LEADER role sees region rows, no personal PIIEXEC role sees anonymized roll-ups; NEVER raw namesPII controls email/phone/name: - stored encrypted at rest - masked on every exploratory layer ('j***@x') - full view: two approved roles onlyAUDIT view_log(actor, artifact, ts, filter)COMPLIANCE PII inventory exportable per region; retention = 18 months, deletion verifiedLeast-privilege roles, row-level predicates, column controls for PII, an audit trail, and a compliance map.
In production
- Rep sales dashboard filters by territory automatically via RLS.
- A PII-packed ops table renders masked columns on any exploratory layer.
- Audit logs answer 'did finance see AP in April' in one query.
Best practices
- Default deny; grant scopes narrowly and review quarterly.
- RLS at the data-connector layer so every report inherits it.
- Mask PII everywhere except the two approved read roles.
- Log audits and test the subpoena story before you need it.
Common mistakes
- A 'role=everyone' snapshot that ships every PII column.
- RLS only in the dashboard, circumvented by a raw query.
- Masking by convention — a missing column stays unmasked until a blunder.
- Audit logs off because they're 'page-weight'; the breach then gets a rumor for an answer.
Debugging tips
- Reps see extra territory rows → predicate drifted from role mapping; rebuild RLS from roles.
- PII surfaced on exploratory → column-level gate missing; mask at the layer, not the chart.
- Compliance question unanswerable → no PII inventory; export one this week, not this quarter.
Interview checkpoint
Quick quiz
Row-level security should be enforced at:
PII should render freely on exploratory dashboards.