Skip to content
Development Practice

Data Classification: How to Implement It Technically

17 min read

Most data classification schemes die in a spreadsheet. This guide shows how to implement classification so it actually works: a two-dimensional scheme of sensitivity tiers plus handling overlays, expressed as one taxonomy in three places (database metadata, a code attribute, and a documented inventory), and held in lockstep by a coverage test that fails the build. Once classification is machine-readable, it drives real controls: field masking, non-production obfuscation, retention, and erasure are written once against the label rather than re-implemented per table. We cover the scheme, the enforcement, the SQL Server and Azure infrastructure, and the controls classification unlocks. It is the technical backbone of data protection by design.

Why most data classification fails

Almost every organisation has a data classification policy. Very few have data classification that does anything. The policy names some tiers, a governance team maps a handful of systems, the document goes into a shared drive, and the code carries on with no idea which of its columns hold a child’s medical notes and which hold a product identifier.

The failure mode is always the same. Classification lives in a document, the system lives in code, and the two never meet. A developer adding a field has no signal that it is sensitive, no control fires differently because of the label, and six months later the spreadsheet is a work of fiction.

Classification that works has three properties the spreadsheet version lacks. It is machine-readable, so code and infrastructure can act on it. It is enforced, so it cannot silently fall out of date. And it drives real controls, so the label is load-bearing rather than decorative. The rest of this guide is how to build all three.

A classification scheme with two dimensions

A single sensitivity level is not enough, because two fields can be equally damaging to expose for entirely different reasons, and those reasons pull in different controls. The workable design uses two orthogonal dimensions.

Sensitivity tiers

The first dimension is a tier that records how damaging exposure would be. Four levels cover most systems:

  • Public. Data that can be shared freely, such as a published article or a public price list.
  • Internal. Non-personal operational data such as configuration or reference values, damaging only in aggregate.
  • Confidential. Most personal and commercial data: names, contact details, account information.
  • Restricted. The highest-risk categories: special-category data such as health, children’s data, financial instruments, and secrets.

Handling overlays

The second dimension is a set of overlays that record why a field needs care, and pull in specific handling. A field can carry more than one:

  • Special-category data, meaning health, biometric, or other Article 9 data that needs a specific lawful condition.
  • Children’s data, which raises the stakes on everything from consent to retention.
  • Safeguarding data, such as welfare notes or background-check status.
  • Financial-instrument data, such as a bank account and sort code.
  • Secret, for credentials, keys, and tokens.
  • Free text, for unstructured fields that might contain any of the above, so they default to the highest plausible tier.

The combining rule

The rule that ties the two dimensions together is that an asset takes the highest tier any of its fields or overlays demands. A table that is mostly confidential but holds one restricted column is a restricted table. This “highest tier wins” rule is what lets you reason about a whole record, a whole export, or a whole backup from the classification of its parts.

One taxonomy, three expressions, one enforcing test

The single most important implementation decision is to express the taxonomy once and represent it in three places that a test keeps in lockstep. This is what stops classification drifting.

Database metadata

The database is where engine-level tooling looks, so the classification has to live there. SQL Server and Azure SQL support native sensitivity labels applied with the ADD SENSITIVITY CLASSIFICATION statement. Each classified column gets a label, an information type such as Health, Financial, or Contact Info, and a rank from low to critical. These populate the sys.sensitivity_classifications system view.

Because a native label carries only one dimension, store the overlays alongside as an extended property on the column, for example a space-separated set of overlay codes. A small reusable procedure that idempotently adds or updates that extended property keeps the overlay handling consistent across every table.

Code attribute

The application needs the classification too, so it can drive redaction, export, and erasure. The pattern is a simple attribute on each sensitive property, for example a [ClassifiedData(label, overlays)] annotation carrying the tier and the overlay flags. The attribute exposes the label and overlay codes so the same object drives every classification-aware control, rather than each control keeping its own list of sensitive fields.

Documented inventory

The third expression is for humans: a register of every classified column, its label, its overlays, and the reason. Auditors, data protection officers, and new engineers read this. On its own a document rots, which is why the test matters.

The coverage test that fails the build

The mechanism that makes classification reliable is a bidirectional coverage test that runs on every push. It builds the data model, reads the database classification scripts, and asserts both directions:

  • Every column classified in the database has a matching code attribute with the same label and overlays.
  • Every property carrying the code attribute has a database classification entry.

A developer who adds a sensitive column without classifying it, or classifies it in one place but not the other, breaks the build. This is the difference between a classification policy and a classification contract. The document cannot drift from the code, because the test will not let it.

The Azure and SQL Server infrastructure

Classification is not only an application concern. The point of putting labels in the database engine is that infrastructure can act on them, which is where a lot of the compliance value comes from.

  • SQL auditing can log the sensitivity rank of the data a query returned, so you have a record of who touched restricted data, not just who ran a query. Route the audit stream to a log analytics workspace for retention and alerting.
  • Data discovery and classification scanners, including Microsoft Defender for SQL, read the labels to inventory sensitive columns and flag unclassified ones, giving you continuous coverage beyond the build-time test.
  • Blob index tags carry the classification with stored files. When a document is uploaded, tag it with its label and overlays so storage-side tooling can find every restricted file without opening any of them.
  • Transparent data encryption and encrypted, private object storage protect the classified data at rest as a baseline under everything above.

Deploy wiring that stays idempotent

Classification scripts should run as a distinct metadata phase of the schema deployment, after tables, indexes, and procedures exist. Guard them so they run only on engines that support sensitivity classification, and write them to be idempotent, because re-applying a label should overwrite cleanly rather than fail. A useful side effect of scripting classification against real columns is that renaming or dropping a classified column without updating its script breaks the deploy, which is another safety net against silent drift.

What machine-readable classification unlocks

The reason to do all this is that once classification is machine-readable, the controls that depend on it are written once against the label rather than re-implemented per table. This is where the investment pays back.

Field-level masking

Redaction reads the label and the caller’s permissions and decides whether to mask a field. Because the rule is driven by the classification, adding a new sensitive column brings it under redaction automatically once it is labelled, rather than requiring a change to every query that returns it.

Non-production obfuscation

A generic obfuscator can reflect over the classification attributes and blank every classified field, so a record copied to a test environment carries no real personal data. For imported legacy data, a deterministic anonymiser seeded from a stable hash produces realistic but fake values while keeping foreign keys consistent, so the system still behaves correctly on synthetic data. Either way, the classification is what tells the obfuscator which fields to touch.

Retention and erasure

Retention and erasure need to know which columns hold personal data so they can anonymise or delete it. Driving this from the classification means a retention sweep reaches every classified column, and a coverage test can even assert that every classified table is covered by a retention rule or an explicitly documented exemption. The retention and erasure guide covers that engine in depth.

Storage and blob discovery

Classified files carry their label as a blob index tag, so a data-loss-prevention or discovery tool can enumerate every restricted document across storage without reading content. Classification turns “where is our sensitive data” from a research project into a query.

Classifying deliberately, not everything

A common mistake is to over-classify, which is as damaging as under-classifying. If every column is restricted, nothing is, because the label stops carrying information and teams start ignoring it.

Classify the data that genuinely needs it: personal data, special-category data, safeguarding data, financial instruments, and secrets. Do not classify enumerations, status flags, surrogate keys, or foreign keys that carry no personal meaning. The goal is a scheme where a restricted label is a real signal that triggers real handling, not a blanket that everyone learns to look past.

There is one subtlety worth handling explicitly. When a requirement deliberately exposes classified data at a lower tier, for example a staff photo that is confidential being published to a public website, do not silently reclassify it. Keep the source at its true tier, model the exposure as a separate, revocable consent decision, and gate the public surface on that consent at serve time. The data is still what it is; only one rendered copy is public.

Where to start

If you are retrofitting classification into an existing system, or designing it into a new one, sequence it like this:

  1. Define the scheme. Agree the tiers and overlays, and write down the combining rule.
  2. Classify the highest-risk data first. Special-category, children’s, financial, and secret columns before anything else.
  3. Express it in the database and the code. Native sensitivity labels plus a code attribute, from the same taxonomy.
  4. Add the coverage test. This is what turns the scheme from documentation into a contract.
  5. Wire one control to the label. Masking or obfuscation is a good first, because it proves the classification is load-bearing.
  6. Turn on the infrastructure. SQL auditing, data discovery, and blob tags, so sensitivity is visible to your tooling.

Data classification is unglamorous, and it is the control that makes the others possible. Get it machine-readable and enforced, and masking, retention, erasure, and breach response all become tractable. Leave it in a spreadsheet, and none of them can be trusted. If you want classification designed into a build so it drives real controls from the start, book a consultation or read how we approach data protection by design.

Frequently asked questions

What is data classification in software terms?
Data classification is the practice of labelling every piece of data by how sensitive it is and why, so the system can apply the right controls automatically. In software terms it means tagging columns, fields, and files with a machine-readable label, for example a sensitivity tier from public to restricted plus overlays such as special-category or children's data. Once the label lives in code and in the database, redaction, export, retention, and erasure can be driven from the classification rather than hand-coded per query.
What are the levels of a data classification scheme?
A common scheme uses four tiers: public data that can be shared freely, internal data such as non-personal configuration, confidential data covering most personal and commercial information, and restricted data for the highest-risk categories such as health data, children's data, financial instruments, and secrets. Tiers are usually combined with handling overlays that record why a field is sensitive, so a single field can be both restricted and flagged as special-category health data. An asset takes the highest tier any of its fields requires.
How do you stop a data classification scheme going out of date?
By enforcing it with a test that fails the build. The scheme should exist as one taxonomy expressed in three places: database metadata, a code attribute on each sensitive field, and a human-readable inventory. A bidirectional coverage test asserts that every classified column has a matching code attribute and every attribute has a database entry, so a developer cannot add a sensitive field without classifying it everywhere. The classification stops being documentation and becomes an enforced contract.
What are SQL Server sensitivity labels?
SQL Server and Azure SQL support native data sensitivity labels applied with the ADD SENSITIVITY CLASSIFICATION statement. Each classified column gets a label, an information type such as Health or Financial, and a rank from low to critical, stored in the sys.sensitivity_classifications system view. Downstream tooling reads these labels: SQL auditing can log the sensitivity rank of data a query returned, data-discovery scanners can inventory sensitive columns, and data-loss-prevention tools can act on them. Classifying in the engine makes sensitivity machine-readable to infrastructure, not just to the application.
How does data classification drive redaction and erasure?
When each sensitive field carries a machine-readable label, controls can be written once and applied everywhere the label appears. Redaction reads the label and the caller's permissions to decide whether to mask a field. Non-production obfuscation reflects over the labels and blanks every classified field. Erasure and retention use the labels to know which columns hold personal data that must be anonymised or deleted. Without machine-readable classification, each of these has to be re-implemented per table, which is where gaps and mistakes creep in.
Where should data classification live, in the database or the code?
In both, kept in sync. The database needs the classification so engine-level tooling such as SQL auditing, data discovery, and data-loss prevention can act on it. The application needs it so redaction, export, obfuscation, and erasure can be driven from the same labels. The reliable pattern is a single taxonomy expressed as database metadata, a code attribute, and a documented inventory, with a coverage test that fails the build if the three drift apart. One source of truth, three representations, one enforcing test.

Ready to transform your software?

Let's talk about your project. Contact us for a free consultation and see how we can deliver a business-critical solution at startup speed.