Policy-as-Code for AI Data Access: How Platform Engineering Teams Are Replacing Manual Access Reviews

Policy-as-Code for AI Data Access: How Platform Engineering Teams Are Replacing Manual Access Reviews

Ticket queues cannot keep pace with AI teams and agent pipelines requesting data. Policy-as-code moves the access decision to query time, tied to classification tags instead of table names, with a step-by-step comparison, an RBAC vs. ABAC vs. tag table, and a worked example.

By

Billy Allocca

Table of Contents

Policy-as-Code for AI Data Access: How Platform Engineering Teams Are Replacing Manual Access Reviews

Policy-as-code for AI data access is the practice of writing data access rules as versioned, machine-readable policy that the data platform evaluates at query time, so a request from an analyst, a training pipeline, or an AI agent is allowed, filtered, or masked automatically based on the requester's attributes and the data's classification tags, with every decision logged.

Manual approval already fails at human request volume. In StrongDM's 2022 survey of 600 DevOps professionals, 57 percent of organizations said infrastructure access requests take days or weeks to approve, and 52 percent of development teams had missed a deadline because of access delays [1]. An IBM analysis published in March 2026 put the typical turnaround for a data request at one to four weeks [2]. AI teams multiply the queue: CyberArk's 2025 identity security survey counted 82 machine identities for every human identity and named AI as the largest creator of new identities with privileged access in 2025 [3].

The platform teams absorbing this load are becoming the norm. Gartner projects that by 2026, 80 percent of large software engineering organizations will run platform engineering teams as internal providers of reusable services, up from 45 percent in 2022 [4]. Those teams inherit data access governance, and codified policy is the only model that lets them carry it without adding reviewers.

If you want the architectural argument for why the access boundary for humans and AI has to be one layer, read the companion post One Governance Model for Data and AI.

Why Does Ticket-Based Data Access Approval Break Under AI Workloads?

Ticket-based approval breaks because it grants named objects to named people, and AI workloads change both sides of that pairing faster than a reviewer can read. A ticket-based access review is a workflow in which a requester files for a specific table or bucket, a data owner inspects the request, and an administrator grants a static permission. That model assumes a stable set of requesters and tables and a request rate a human can process.

An AI feature team violates every assumption. A retrieval pipeline touches dozens of tables in its first week and adds more as embeddings improve. A retraining job needs the same tables under a service identity that did not exist last quarter. An agent requests data on behalf of whichever user triggered it, at 2 a.m., across domains. Each case generates a ticket that asks a reviewer to recall column sensitivity from memory. StrongDM found that 55 percent of IT, security, and DevOps staff keep backdoor access to systems and 53 percent share credentials across teams, which is what a two-week front door produces [1].

Step

Ticket-based access review

Policy-as-code

1. Request

Engineer files a ticket naming tables and a justification

Engineer's role and the dataset's tags already exist; the request is the query itself

2. Triage

Platform team routes the ticket to a data owner

Policy engine evaluates the request in milliseconds against the rule set

3. Review

Owner reads the ticket, checks which columns hold PII, asks follow-up questions

Rules encode the PII decision once; classification tags carry it per column

4. Approval

Owner approves, often with conditions typed into a comment

Decision is allow, deny, filter, or mask, returned as structured output

5. Provisioning

Admin writes a grant in the warehouse, another in object storage, another in Spark

Enforcement points across engines read the same decision

6. Audit

Ticket ID and grant are reconciled manually during quarterly certification

Every decision is logged with subject, resource, tags, and outcome at request time

7. Change

New table added to the dataset triggers a new ticket cycle

New table inherits the dataset's tags and is governed on creation

8. Revocation

Grant persists until someone remembers to remove it

Access ends when the attribute or tag that granted it changes

Elapsed time is measured in weeks on the left and milliseconds on the right, and the right column produces its audit evidence as a byproduct of operating.

What Does Policy-as-Code Look Like for a Data Estate?

Policy-as-code for data means the access rule lives in a text file under version control, is evaluated by an engine separate from the systems that enforce it, and returns a decision those systems apply. HashiCorp's Sentinel documentation defines the general idea as "writing code in a high-level language to manage and automate policies" so that "version control, automated testing, and automated deployment" apply to policy as they apply to software [5].

The engine most platform teams know is Open Policy Agent (OPA), a general-purpose policy engine that "decouples policy decision-making from policy enforcement": a service queries OPA with JSON input and receives a decision back [6]. Policies are written in Rego, OPA's declarative language, which "lets you express desired rules and decisions as code" [7]. Infrastructure teams already run this pattern through OPA Gatekeeper, "a validating and mutating webhook that enforces CRD-based policies executed by Open Policy Agent" at Kubernetes admission [8]. The data-layer equivalent exists: Trino's OPA access control plugin sends each request's identity and target resource to OPA and applies the returned decision, including row filtering and column masking [9].

Attribute-based access control (ABAC) is the authorization model these engines implement. NIST SP 800-162 defines it as a method in which authorization "is determined by evaluating attributes associated with the subject, object, requested operations, and, in some cases, environment conditions against policy" [10]. Data classification supplies the object attributes: a label such as PII or PCI attached to a table or column in a catalog like DataHub, where tags apply at the dataset level or to individual schema fields [11].

A data access policy qualifies as policy-as-code when it meets every item on this list:

  • The rule is stored as text in a repository with history, diffs, and pull-request review.

  • The rule references subject attributes (role, team, tenant) and object attributes (classification tags), never individual usernames or table names.

  • The rule is evaluated per request, at query time, by an engine that returns allow, deny, filter, or mask.

  • The same rule governs every engine that can reach the data, so a Spark job and a Trino query and a direct object read see identical outcomes.

  • The evaluation is logged with enough detail that an auditor can replay why a specific request was allowed.

  • The rule can be tested against sample requests in CI before it reaches production.

What Is the Difference Between RBAC, ABAC, and Tag-Driven Classification?

The three models take different inputs, and the input determines how many policies you maintain. Role-based access control (RBAC) assigns permissions to roles and roles to users, which works until roles multiplied by tables outgrows anyone's ability to review the grid; NIST SP 800-162 notes that RBAC needs a new role or permission each time a new combination of need and object appears [10].

Dimension

RBAC

ABAC

Tag-driven classification

Decision input

Subject's role

Subject, object, action, and environment attributes

Subject's role or attributes mapped to the object's classification tag

Where the rule lives

Per-object grant tables in each engine

Central policy engine evaluated at request time

Central policy engine plus tags in the data catalog

Policy count grows with

Roles multiplied by objects

Number of distinct rules, independent of object count

Number of tags multiplied by roles, independent of object count

New table added

New grants required in every engine

Governed if its attributes are known to the engine

Governed the moment it inherits the dataset's tag

Column masking

Manual view or per-engine masking policy

Expressed as a rule on column attributes

Expressed once per tag (for example, mask any column tagged PII for non-privileged roles)

Audit answer to "who could see this column"

Reconstruct from grants across engines

Query the policy log

Query the policy log and the tag history

Typical failure

Role explosion and stale grants

Attribute sources drift or are incomplete

Untagged assets fall through to default rules

Apache Ranger implements the third column directly. It evaluates tag policies before resource policies, and "a single authorization policy for a tag can be used to authorize access to resources across various Hadoop components, which eliminates the need to create separate policies in each component" [12]. If any tag policy denies, the request is denied; only when no tag policy applies does Ranger fall back to a resource-based policy [12]. Ranger also carries the masking and row-filter primitives tag rules need, including partial masks, nullification, and custom expressions [13].

What Happens When an AI Team Requests Customer Transaction Data in Each Model?

The same request produces a weeks-long approval in one model and a masked result set in the other. Assume a fraud-detection team wants to train on payments.transactions, which holds card numbers, customer IDs, merchant IDs, amounts, and timestamps, and later wants an agent to query the same table on behalf of analysts.

Stage

Ticket-based model

Policy-as-code model

Day 0, the ask

Team lead files a ticket for read access to payments.transactions, citing the fraud project

Team's service identity already carries role fraud-ml; the transactions dataset already carries tags PCI on card columns, PII on customer ID, and Financial at the table level

Day 0 to 3, triage

Platform team identifies the payments data owner and forwards the ticket

Not applicable; a policy already states that role fraud-ml may read Financial tables with PCI columns hashed and PII columns tokenized

Day 3 to 10, review

Owner asks whether the team needs raw card numbers, waits for a reply, consults security about tokenization

Not applicable; the masking decision was made once when the PCI tag policy was written and reviewed in a pull request

Day 10 to 14, provisioning

Admin creates a masked view in the warehouse, grants the role in Spark separately, and opens a bucket policy for the training job's object reads

Not applicable; the first Spark read, Trino query, and object read are each evaluated against the same rule and return hashed card numbers and tokenized customer IDs

Week 6, scope grows

Team adds payments.chargebacks and files a second ticket; the cycle repeats

chargebacks is created inside the tagged dataset, inherits Financial and PII, and is governed on creation with no ticket

Month 3, the agent

Team requests a service account for an agent; reviewer cannot evaluate what the agent will ask, so the grant is either too broad or refused

The agent runs under the identity of the analyst who invoked it plus its own agent role; every query it issues is evaluated per request, and the agent sees the same masked columns the analyst would

Quarterly audit

Certification pulls grant lists from three systems and matches them to ticket IDs

Auditor queries the decision log for every read of PCI-tagged columns by fraud-ml and receives subject, query, outcome, and mask applied

The left column consumed about two weeks of calendar time and four people's attention before the first row was read, and it repeats for the second table. The right column consumed the time to evaluate a rule, because the decisions that used to happen inside the ticket happened once, in code, when the PCI and PII tag policies were reviewed.

Why Not Just Automate the Ticket Queue?

Automating approvals speeds up the wrong step. Workflow tools can auto-approve template matches, route by data domain, and expire grants after 90 days, and each reduces reviewer load. But the output of the fastest ticket system is still a static grant to a named object in a specific engine. It does not follow the data when a table joins the dataset, and it cannot evaluate an agent's request that did not exist when the grant was written.

The caveat runs the other way too. Policy-as-code depends on the quality of its attributes: an untagged table falls through to whatever default you set, and a role assigned too broadly in the identity provider is broad everywhere the policy engine trusts it. Classification effort moves from every ticket to the catalog, once per dataset. That trade is the only version that scales with request volume instead of headcount, and NIST's zero trust architecture reaches the same conclusion from the security side: authorization is a discrete decision made per resource request, by a policy engine, and enforced at the point of access [14].

The adjacent question of what to put in the policy for column-level protection is covered in Column-Level Security in the AI Era, and the question of what the data owner promises the consumer is covered in Data Contracts for AI. The decision log this section describes is also the access half of a provenance trail; the training-data half is covered in The Data Lineage Imperative.

NexusOne Generates Policies From Catalog Tags and Enforces Them at Query Time

NexusOne runs tag-driven policy-as-code as the mechanism of its governance layer. Identity is federated from Active Directory, Okta, LDAP, or SAML into one Keycloak layer, with users, groups, and roles scoped per tenant. Classification comes from DataHub: you tag a dataset once, at table or column level, and map roles to tags in the NexusOne portal. Policies then generate in Apache Ranger at the bucket, schema, and table level, and Ranger enforces them simultaneously across Trino, Apache Spark, Apache Kyuubi, and S3 object storage per object, so the fraud team's Spark job and an analyst's Trino query return the same hashed card column. When a table is added or a schema changes, the policies update without a ticket.

Agents inherit the same model. The AI & Data Control Plane evaluates every agent and MCP request at the boundary under the invoking identity, blocks PII and jailbreak attempts with the reason logged, applies per-role token budgets, and records each request, so one log covers humans and agents (Enterprise AI Governance: Why One Control Plane Is the Only Scalable Answer makes the case). The stack runs identically on-prem, in your cloud, hybrid, or air-gapped, on open formats such as Apache Iceberg. To walk through your own access-request backlog against this model, book an expert consultation.

Key Takeaways

  • Manual access review fails at human request rates already; 57 percent of organizations report approvals take days or weeks, and AI teams and agents multiply the request volume [1][3].

  • Policy-as-code moves the access decision to query time, where a policy engine evaluates subject attributes against data classification tags and returns allow, deny, filter, or mask.

  • Tag-driven classification keeps policy count proportional to tags multiplied by roles instead of roles multiplied by tables, so new tables are governed on creation.

  • OPA with Rego, Gatekeeper, Sentinel, and Ranger tag policies are proven implementations of the same pattern at the infrastructure and data layers.

  • Automating the ticket queue produces faster static grants; it does not produce per-request, per-engine, agent-aware enforcement.

  • NexusOne generates Ranger policies from DataHub tags and enforces them across Trino, Spark, Kyuubi, and S3 under one Keycloak identity for humans and agents.

FAQ

What Is Policy-as-Code in Data Governance for AI?

Policy-as-code in data governance is the practice of writing access rules as versioned text that a policy engine evaluates at request time instead of encoding them as manual approvals and static grants. For AI workloads, the rules reference the requester's role or attributes and the data's classification tags, so a training pipeline or agent is allowed, filtered, or masked automatically. Open Policy Agent and Apache Ranger tag policies are the two most common engines for this pattern in a data estate [6][12].

How Does Automated Data Access Control Work for AI Teams and Agents?

Automated data access control gives each AI team a role and each service or agent an identity in one identity provider, tags datasets and columns with classifications in the catalog, and writes rules that map roles to tags. When a job or agent issues a query, the engine evaluates the request against those rules and returns a decision the query engine enforces, including column masking and row filtering. Because the evaluation is per request, an agent acting for a user sees exactly what that user is allowed to see, and every decision is logged.

How Should an Enterprise Enforce Data Access Policy Across Multiple Engines for AI?

Enforce the policy in one engine that every compute and storage path consults, so the same rule governs a Trino query, a Spark job, and a direct object read. Apache Ranger evaluates tag-based policies before resource-based policies and applies one tag rule across every component it protects, which removes the need to define the same rule per engine [12]. Trino also supports Open Policy Agent as its authorization engine, sending identity and resource details as JSON and applying the returned decision [9].

How Do You Replace Manual Data Access Reviews With Automation?

Start by classifying the datasets AI teams request most and tagging them at the column level for PII, PCI, or equivalent categories. Define roles in the identity provider that correspond to how teams consume data, then write rules that map each role to each tag with an explicit allow, mask, or deny outcome and review those rules in pull requests. Point every engine at the same policy decision point, and treat the decision log as the audit evidence. Tickets remain for the exceptions the rules do not cover, which is where reviewer time belongs.

References

  1. New Research: 57% of Organizations Take Days or Weeks for Infrastructure Access to be Approved (2022 Access-Productivity Gap Report), StrongDM, https://www.strongdm.com/press/organizations-take-days-or-weeks-for-infrastructure-access

  2. Data delivery delays are slowing decisions more than you think, IBM Think, https://www.ibm.com/think/insights/data-access-delays-slowing-decisions

  3. 2025 Identity Security Landscape Report, CyberArk, https://www.cyberark.com/threat-landscape/

  4. Platform Engineering, Gartner, https://www.gartner.com/en/infrastructure-and-it-operations-leaders/topics/platform-engineering

  5. Policy as Code, HashiCorp Sentinel Documentation, https://developer.hashicorp.com/sentinel/docs/concepts/policy-as-code

  6. Open Policy Agent Documentation: Introduction, Open Policy Agent, https://www.openpolicyagent.org/docs

  7. Policy Language (Rego), Open Policy Agent, https://www.openpolicyagent.org/docs/policy-language

  8. Introduction, OPA Gatekeeper Documentation, https://open-policy-agent.github.io/gatekeeper/website/docs/

  9. Open Policy Agent access control, Trino Documentation, https://trino.io/docs/current/security/opa-access-control.html

  10. NIST SP 800-162, Guide to Attribute Based Access Control (ABAC) Definition and Considerations, NIST, https://csrc.nist.gov/pubs/sp/800/162/upd2/final

  11. Tags, DataHub Documentation, https://docs.datahub.com/docs/tags

  12. Tag Based Policies, Apache Ranger Wiki, https://cwiki.apache.org/confluence/display/RANGER/Tag+Based+Policies

  13. Row-level filtering and column-masking using Apache Ranger policies in Apache Hive, Apache Ranger Wiki, https://cwiki.apache.org/confluence/display/RANGER/Row-level+filtering+and+column-masking+using+Apache+Ranger+policies+in+Apache+Hive

  14. NIST SP 800-207, Zero Trust Architecture, NIST, https://csrc.nist.gov/pubs/sp/800/207/final

ABOUT

1115 Howell Mill Rd
Suite 430,
Atlanta, GA 30318
An Insight Partners Company


Product Updates and News

@2026 NexusOne® - All rights reserved.

ABOUT

1115 Howell Mill Rd
Suite 430,
Atlanta, GA 30318
An Insight Partners Company


Product Updates and News

@2026 NexusOne® - All rights reserved.

ABOUT

1115 Howell Mill Rd
Suite 430,
Atlanta, GA 30318
An Insight Partners Company


Product Updates and News

@2026 NexusOne® - All rights reserved.