The standard approach to data governance in most organizations is document-driven: write a classification policy, assign data stewards, require annual sign-offs, and store the outputs in a SharePoint folder that nobody looks at between audits. This produces excellent paper compliance and virtually no operational change to how data is actually handled. Engineers keep building pipelines without classification metadata. DBAs keep granting broad access because narrowing it takes time. Data keeps accumulating in places the security team doesn't know about.
The alternative is treating governance as an engineering discipline with the same properties as any other: automated, observable, incrementally deployable, and fixable when it breaks. That framing changes what tools you reach for and what "success" looks like.
Why the policy document model fails
Data governance policies fail for the same reason most policies that don't integrate with developer workflow fail: they impose overhead at design time and have no enforcement at runtime. An engineer creating a new database table doesn't look up the classification policy to determine whether the table should have the "PII - High" tag applied. They build the table, write the migration, deploy it, and move on. The policy exists. The table exists. They have never met.
The problem compounds with team size. In a five-person company, you can rely on tribal knowledge: everyone knows which tables contain customer PII because everyone has been in every data model discussion. In a thirty-person engineering organization, that knowledge is no longer shared. Someone builds a feature that joins a customer ID from a non-sensitive events table to a name and email from a user profile table and stores the result in a derived table in the analytics warehouse. That derived table now contains PII. Whether anyone knows that depends entirely on whether the engineer thought to tag it, and whether tagging is part of the deployment process or a separate policy step.
Document-driven governance doesn't scale past the point where tribal knowledge breaks down. Engineering-embedded governance has to take over before you hit that wall, not after.
Classification as a code artifact, not a spreadsheet column
The first shift is making data classification machine-readable and version-controlled alongside the schemas it describes. Instead of maintaining a data dictionary in a spreadsheet where a steward manually updates classification labels, classification lives in code: in dbt model configurations, in Terraform resource tags, in table comments that are parsed by tooling, or in a dedicated data catalog that pulls metadata from your actual schemas.
A practical starting point for teams running dbt: add a required data_classification meta field to your dbt model configs. Your CI pipeline fails if a model that touches source tables tagged as pii doesn't carry its own pii classification forward. This is not perfect. A model that derives PII indirectly (joining a non-PII events table with a PII user table and exposing identifying information in the output) might not trigger the rule. But it catches the obvious cases and establishes the pattern: classification is a code property, it ships with the schema, and it is reviewable in pull requests.
The same principle applies to infrastructure. If your S3 bucket naming convention doesn't encode sensitivity, add an AWS resource tag with a standardized classification key. Your Terraform modules for common data store types can have that tag as a required input. New buckets created without a classification tag fail the plan step. Again, imperfect: someone can put an incorrect classification on the tag, and automated scanning still needs to verify what's actually in the bucket. But requiring the tag forces the classification decision to happen at creation time rather than retroactively during an audit.
Access provisioning as a first-class workflow
The second shift is integrating access requests and reviews into engineering workflow tooling rather than running them as a separate IT process. The current state in many organizations: a developer needs access to a production database for debugging. They file an IT ticket or send an email to a DBA. The access is granted with broad permissions because narrowing it is time-consuming. It is rarely revoked when the debugging is complete. Six months later, that developer has standing production database access that nobody remembers granting.
The engineering-native alternative: access requests that go through a PR or ticketing system with explicit approval gates, automatic expiration timestamps, and a review queue tied to your access review cadence. Tools like Teleport or custom-built approval workflows can implement time-limited access grants. The access is provisioned for 24 hours for the debugging session and expires automatically. If the engineer needs it longer, they request an extension with justification, which creates a review record.
For standing access (an analytics role that needs ongoing read access to a production schema, for example), the access grant lives in infrastructure-as-code and goes through your normal code review process. When the business requirement for that access changes, the IaC change removes the grant. Access deletion happens through the same engineering workflow as access creation, rather than being a separate manual cleanup process that never happens.
Connecting classification to access review
The two threads, classification and access provisioning, need to be connected to be useful for security posture. Knowing that a table is classified as PII is only actionable when combined with knowing which roles currently have SELECT on that table and whether those grants are still justified.
This is where automated discovery and access graph analysis does work that no manual process can replicate at scale. At PostQKey, when we run discovery against a data warehouse, we surface the access-to-classification relationship as a finding: table X is classified PII, roles A, B, and C have SELECT on it, role B has not been used in 90 days, role C belongs to a service account for an integration that the engineering team identifies as deprecated.
Those findings go into a remediation queue that maps to engineering owners, not security team owners. The engineering team that owns the deprecated integration is the right team to revoke the service account access. The DBA who originally granted role B's access might not know it's dormant; surfacing the usage data turns a policy debate into a concrete question: "this role hasn't queried this table in 90 days, do you still need it?"
The access review cadence question
SOC 2 and ISO 27001 require periodic access reviews. Most organizations run them quarterly or annually as a compliance activity: generate a report of who has access to what, send it to managers, collect certifications, file the outputs. The problem with pure compliance-cadenced reviews is that a lot can change between reviews, and the reviews themselves are often rubber-stamped because the volume of access grants to review is too high for managers to evaluate carefully in the time allocated.
A more operationally useful model runs continuous lightweight review rather than periodic batch review. Every time an access grant hasn't been used in 60 days, the system flags it for review by the relevant owner. Every time a new data store is connected that contains sensitive data, the access grants to that store are reviewed as part of the connection workflow. Reviews happen in smaller batches, tied to specific events or thresholds, with context about recent usage that makes the certification decision meaningful rather than reflexive.
We're not saying annual access reviews as a compliance exercise are wrong. They are a requirement, and meeting them is necessary. We're saying that if the only access review mechanism you have is the annual compliance exercise, the control is weaker than it appears because the continuous signal that would make the review meaningful is absent.
The hard part: ownership at the data object level
The practical obstacle in implementing engineering-embedded governance is ownership assignment. For the access review model to work, every sensitive data object needs an owner who can certify access decisions. In practice, ownership is fuzzy: the table was created by an engineer who has since left, is used by three teams, and nobody is clearly accountable for reviewing access to it.
Assigning ownership retrospectively is a governance project of its own. The pragmatic starting point is forward-looking: new data stores and schemas created after governance tooling is in place must have an owner assigned at creation as a mandatory field. Existing objects without clear ownership are flagged, and the team most recently associated with the object (via commit history, access logs, or pipeline lineage) is assigned interim ownership pending a review.
This is iterative. You will not get clean ownership across your entire data estate in one quarter. The goal is directional improvement: more objects with owners today than last quarter, access review completion rate trending up, stale access grants being revoked before they accumulate. Measuring those trends is itself an engineering problem, one that requires dashboards, not spreadsheets.
Where DSPM fits in the engineering governance model
Automated data discovery is the feedback loop that makes engineering-embedded governance honest. You can require classification tags at creation time. Engineers will sometimes get the classification wrong, data will move to new locations without the classification being carried forward, and derived datasets will introduce sensitivity that the source classification didn't anticipate.
DSPM's discovery and classification layer runs continuously and surfaces discrepancies: a table tagged as "Internal - Non-sensitive" in your catalog that we find contains field patterns matching social security numbers. A new schema that appeared last week with no classification tag. A bucket that receives replicated data from a PII-classified source but has no classification metadata of its own. Those findings go back into the engineering governance workflow as tasks: here is the object, here is what we found in it, here is the owner, here is the suggested classification update.
The combination is better than either component alone. Engineering governance without discovery is aspirational: you govern what you think you have. Discovery without engineering governance produces findings with no owner to act on them. Together, the discovery layer keeps the engineering governance layer honest, and the governance layer gives every discovery finding a clear path to remediation.