Crosshire
Access & ABAC
Govern16 Access & ABAC · 3 of 4

What an exemption actually grants

The most expensive misreading in a permissions concept: treating an exempted principal as someone who sees one unmasked column, when what they hold is a route to the whole table.

Stand 29.07.2026

#What EXCEPT buys, and what it costs

What
EXCEPT is not a lower privilege level. It is a full bypass of the policy for that principal, on every covered table, for every covered column. There is no partial exemption.
The same operation, two identities
Operation on gold.dim_customerSubject to the policyNamed in EXCEPT
SELECT email'***'the address
VERSION AS OF 42 / TIMESTAMP AS OFquery fails — policies cannot be evaluated against a historical snapshotthe address, at that version
CREATE TABLE … DEEP CLONE / SHALLOW CLONEunsupported, failssucceeds — and the clone is a new securable
Delta Sharing as share ownershare creation blockedshares the unmasked column
Building a materialized view over the tablepipeline failsmaterialises unmasked values
The same logic applies to a clone. A policy attaches to a securable — a catalog, a schema, a table. Clone dwh_prod.gold.dim_customer into a schema the policy does not cover and the copy is unprotected, whatever the source was.
A share has a second edge on top of that. Table sharing is WITH HISTORY by default on DBR 16.2+, and schema sharing always is — so an exempted share owner ships not only today's unmasked column but every earlier version of it. Wherever an erasure redacted a value in place, the pre-redaction version travels with the share unless somebody wrote WITHOUT HISTORY explicitly.
Why
"The column is masked" and "they cannot get the data" are different statements, and permissions concepts routinely assert the first while meaning the second. That gap is where a data-protection review finds its finding: backup, clone, time travel and pipeline identities all need an exemption to function, every one of those exemptions is total, and the list of them is the real answer to who can read customer email.
Doing it
  • Enumerate every principal in every EXCEPT clause into one table in the permissions conceptPut the operation that forced the exemption next to it.
  • Tag the outputs of exempted pipelines, not just the sourcesThe materialized view, the aggregate, the export table.
  • Decide where clones may land, and make the target schema covered by the same policies as the source
  • Check whether anything depends on time travel before the policy lands, because it will stop workingA restore runbook, a reconciliation query.
Embedding it
  • Have the team try a time-travel query against a protected table without an exemptionThe failure is the lesson; explaining it is not.
  • Ask them to name every exempted principal from memory in month threeIf they cannot, the list is too long and the control is theatre.
  • Make removing an exemption a normal ticket, and do one togetherThe list can then shrink and not only grow.
  • Get the data-protection officer to read the exemption table rather than the policy DDLIt is the artefact that answers their question.
Defaults
  • One documented exemption table, reviewed quarterly, with an owner per row
  • Exempt service principals, never people, for machine operations
  • Outputs of exempted pipelines carry the same governed tags as their inputs
  • Clone and export targets live inside the policy's scope, or the export does not happen
Gotchas
  • Adding a service principal to EXCEPT to fix a failing jobIt fixes the job and removes protection from everything that job touches, and it looks like a one-word edit in a pull request.
  • Time travel silently leaving the toolboxNobody notices until an incident, when the query that would have shown yesterday's state fails on a table that is now protected.
  • A materialized view or aggregate built from tagged sources but never tagged itselfThe mask holds on dim_customer and the same email sits unmasked one table downstream — which is where BI reads.
  • Treating masking as anonymisationIt is neither; see the classification route, where the difference decides whether the data is in scope at all.
  • Sharing a protected table from an exempted identity without writing WITHOUT HISTORYHistory is the default, so the recipient gets the versions from before the redaction — the erasure you performed is still readable on the other side of the share, and nothing in the share definition looks wrong.
Platform facts on this page verified 29.07.2026 against the official documentation. Volatile claims are anchored to the currency register. This is section 3 of 4 in 16 Access & ABAC.