Policy as code stores rules in a policy language and evaluates them with external data at decision time, which is flexible for complex logic and ABAC-style policies. Policy as data stores the access relationships and rules centrally, which suits large-scale ReBAC and hierarchical permissions. The choice depends on whether logic flexibility or relationship-centric centralization matters more.
Why This Matters for Security Teams
policy as code and policy as data solve different governance problems, so choosing the wrong model usually shows up later as friction, exceptions, or brittle workarounds. Policy as code is strongest when the decision logic itself must be versioned, reviewed, tested, and expressed with conditionals. Policy as data is stronger when the organisation needs a central, queryable store of relationships and entitlements that many systems can consume consistently.
For security teams, the practical difference is control shape. Code-centric policy makes change review closer to software engineering, while data-centric policy makes authoring and administration closer to access governance. That distinction affects who can safely change policy, how quickly changes propagate, and how easily auditors can reconstruct a decision path. It also affects whether the organisation can keep logic simple enough for human review.
In practice, many security teams discover the mismatch only after policy exceptions start accumulating faster than the policy model can absorb them.
How It Works in Practice
Policy as code usually means the rule set is written in a formal language, stored in source control, and evaluated at decision time against live context. That makes it well suited to conditions such as environment, time, request attributes, resource sensitivity, or risk signals that must be combined dynamically. It is especially useful when the same logic needs to be reused across multiple enforcement points and changes must go through the same review process as application code.
Policy as data, by contrast, keeps the decision inputs and relationship graph in a central store. The engine may still evaluate rules, but the important point is that the policy content is primarily declarative, not procedural. That helps when the core problem is not complex branching logic but scale, consistency, and relationship-centric access control. Common examples include large permission hierarchies, delegated administration, and relationship-based access patterns where the question is, “who is related to what, and with what level of access?”
A useful way to separate the two is:
- Use policy as code when the decision depends on logic, conditions, and testable expression.
- Use policy as data when the decision depends on centrally managed relationships, grants, or hierarchies.
- Use both when you need a data model for access state and a code layer for contextual decision logic.
In both cases, the operational risk is drift: rules that are technically correct but inconsistent with reality because the data model, enforcement points, or review process are not aligned. For example, policy data can become stale if relationship updates are delayed, while policy code can become difficult to trust if it accumulates special cases that no one can reason about quickly. These controls tend to break down when ownership is split between engineering and governance teams without a single change and review path.
Common Variations and Edge Cases
Tighter policy centralisation often increases admin overhead, requiring organisations to balance consistency against the cost of change. In mature environments, the best answer is often hybrid rather than absolute: code for logic, data for relationships, and strict boundaries between the two.
One common edge case is “policy as code” that still depends on static reference data. In that model, the code may be the authoritative decision layer, but the actual business meaning lives in a separate dataset. Another is “policy as data” that becomes effectively procedural because the team keeps adding exception logic to compensate for missing expressiveness. At that point, the organisation has not chosen a pure model, it has created a fragile hybrid.
Governance maturity matters as much as architecture. If business owners need to update entitlements frequently, policy as data often reduces operational friction. If security teams need deterministic, reviewable logic for complex authorisation conditions, policy as code is usually the safer fit. Best practice is evolving toward clearer separation of decision logic, data ownership, and enforcement boundaries rather than trying to force one model to do everything.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
NIST CSF 2.0, CIS Controls v8 and NIST SP 800-63 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST CSF 2.0 | GV — Govern | Policy models affect governance, ownership, and change control. |
| Recommendation — Define policy ownership, review authority, and change governance for the chosen model. | ||
| CIS Controls v8 | 6 — Access Control Management | Policy as code or data ultimately governs who can access what. |
| Recommendation — Maintain centralized access control records and remove stale entitlements promptly. | ||
| NIST SP 800-63 | 4.1 — Digital Identity and Authenticator Assurance | Policy decisions often depend on identity assurance and authentication context. |
| Recommendation — Bind access decisions to the required assurance level and authenticator strength. | ||
Practitioner Guidance
What to prioritise: Decide whether the harder problem is expressing logic or maintaining authoritative relationship state. If the main challenge is conditional decisioning, start with code-based policy; if the main challenge is entitlement sprawl, start with a data model that can be governed centrally.
What to verify: Check whether policy changes can be tested before deployment, whether non-technical owners can safely update relationship data, and whether every enforcement point reads from the same source of truth. If you cannot answer those three questions cleanly, the model is likely to fail in production.
Decision rule: If a policy change would be risky to express as branching logic, keep it out of code and model it as data. If a policy change would be risky to approve without explicit conditional review, keep it in code and subject it to software controls.
Practitioner takeaway: The right model is the one that makes the most important decision path easiest to audit, hardest to drift, and simplest to change without creating hidden exceptions.
Related resources from NHI Mgmt Group
- What is the difference between attack surface management and NHI governance?
- What is the difference between reviewing human access and reviewing NHIs?
- What is the difference between role-based access and API key governance for NHI security?
- What is the difference between human IAM controls and NHI governance?
Deepen Your Knowledge
Reviewed and updated by the NHIMG editorial team on September 16, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org