Next-Generation Access Control (NGAC): one graph to express them all
Next-generation access control explained: the NIST standard (INCITS 565, born from the Policy Machine) that models users, attributes, objects, and policies as a single directed graph and computes access as a privilege path through it. How NGAC's assignments, associations, prohibitions, and obligations take in RBAC, ABAC, and ReBAC under one formal framework, how a decision is derived from the graph, how it differs from XACML, and why its efficient review queries and deterministic evaluation matter even though adoption is still early.
Three engines and a question nobody can answer
By the end of the year, Sara’s company has three authorization systems. Job-based access lives in RBAC groups in the directory. The data classification team runs attribute rules that keep Confidential documents away from anyone without clearance. And the collaboration platform has its own relationship graph for sharing. Each works. Then an auditor asks a simple question: “Who, today, can read roadmap.md, and under which of your policies?” Answering it means querying three systems with three data models, joining the results by hand, and hoping the glue code between them does what everyone thinks it does.
The previous articles each championed a different basis for access: owners, labels, roles, attributes, and relationships. Each was strongest for one shape of problem and clumsy for the others, and real systems end up combining two or three of them, stitched together in application code, exactly like Sara’s company. That leaves a question hanging over this whole part of the domain: is there one formal structure general enough to express roles, attributes, and relationships at once, so you don’t have to bolt separate engines together? Next-generation access control (NGAC) is the standards community’s answer, an attempt to unify the models rather than add another.
NGAC’s bet is radical in its simplicity: model everything as one directed graph. Users, the attributes that group them, objects, the attributes that group those, and the policies themselves all become nodes, and the ways they relate become edges. An access decision is then neither a rule match nor a role lookup but a question about the graph: is there a privilege path from this user to this object, granted by an association and not cut by a prohibition? Where ReBAC put relationships between resources into a graph, NGAC puts the entire policy, subjects, objects, attributes, grants, and denials, into one graph, and derives every decision from its structure. That generality is the whole idea, and it’s why NGAC presents itself not as a rival to RBAC or ABAC but as a framework in which they’re special cases.
Whether NGAC becomes the dominant way to build authorization is still open; its tooling and adoption lag behind its ideas. But as a way to understand how roles, attributes, and relationships relate to one another, it’s hard to beat, and its influence on modern authorization thinking is already deep.
From the Policy Machine to a standard
NGAC is the standardized form of years of NIST research called the Policy Machine, led by David Ferraiolo, the same researcher whose name is on the original RBAC model of the 1990s. Having helped formalize RBAC, Ferraiolo and colleagues spent the 2000s on a deeper question: instead of building a new mechanism for each type of policy, could there be one general-purpose access-control mechanism whose behavior is entirely determined by configurable data? The Policy Machine was their answer, a machine whose “program” is a graph, so that RBAC, ABAC, multilevel security, and their combinations become different configurations of the same engine rather than different engines.
That research was standardized as NGAC, first as INCITS 499 in 2013 and then as the revised INCITS 565, with supporting NIST publications fleshing out the model, including work on combining access-control policies. NIST also publishes a reference implementation of the Policy Machine, and a handful of commercial products have adopted the approach. The lineage matters: NGAC comes from the same intellectual tradition as RBAC, extended by two decades of thinking about how to generalize it, which is exactly why it can present roles as one configuration among many.
Everything is a node
NGAC’s vocabulary is small, and learning it is most of learning NGAC.
| Element or relation | Symbol | Role in the graph |
|---|---|---|
| User | U | A subject that makes requests (a person or a service) |
| User attribute | UA | A container grouping users (a role, department, clearance, team) |
| Object | O | A protected resource (a file, record, endpoint) |
| Object attribute | OA | A container grouping objects (a folder, classification, project) |
| Operation | op | An action that can be performed (read, write, delete) |
| Policy class | PC | A named policy the graph belongs to; several can coexist |
| Assignment | → | Places an element inside a container (containment edge) |
| Association | ⇒ | Grants operations from a UA to an OA (the grant edge) |
| Prohibition | ⊘ | Denies operations from a user or UA over objects (the deny edge) |
| Obligation | ⟳ | An event-triggered rule that changes the graph automatically |
Three of these edges do the real work. An assignment is pure containment: user:sara → UA:engineer says Sara is in the engineer attribute, and object:roadmap → OA:research-docs says the roadmap is in the research-docs attribute. Assignments chain, so attributes contain attributes, UA:engineer → UA:staff and OA:research-docs → OA:company-files, building the two hierarchies, one for users and one for objects, that give the graph its shape. An association is the grant that bridges the two sides: UA:engineer ⇒ {read, write} ⇒ OA:research-docs means anyone contained in engineer may read and write anything contained in research-docs. A prohibition is the explicit exception: UA:engineer ⊘ {delete} OA:company-files withholds delete regardless of any association that would otherwise grant it. That’s the whole grammar, containers, grants, and denials over containers, and remarkably it’s enough to express the models of the previous articles.
How a decision is computed
Given the graph, deciding a request, user, operation, object, “may Sara read roadmap.md?”, is a well-defined search, and its determinism is a big part of NGAC’s appeal. The engine does three things. It collects the attribute containers the user reaches by following assignments upward: Sara, engineer, staff. It collects the containers the object reaches: roadmap, research-docs, company-files. And it looks for an association whose source is one of the user’s containers, whose target is one of the object’s containers, and whose operations include the one requested; here engineer ⇒ {read, write} ⇒ research-docs matches. If such a privilege path exists and no prohibition removes the operation, the request is permitted; otherwise it’s denied.
flowchart LR
accTitle: How NGAC derives an access decision from the policy graph
accDescr: The decision procedure begins with a request naming a user, an operation, and an object. The first step follows assignment edges upward from the user to collect all user attributes that contain the user, such as engineer and staff. The second step follows assignment edges upward from the object to collect all object attributes that contain the object, such as research docs and company files. The third step searches for an association whose source is one of the collected user attributes and whose target is one of the collected object attributes and whose operation set includes the requested operation, for example engineer to research-docs. If no such association exists, the result is deny. If one exists, a fourth step checks whether any prohibition removes the requested operation for this user over this object. If a prohibition applies, the result is deny; otherwise the result is permit.
R["Request: user sara, op read, object roadmap"] --> UA["Collect user attributes above sara:<br/>engineer, staff"]
R --> OA["Collect object attributes above roadmap:<br/>research-docs, company-files"]
UA --> A{"Association linking a user attr to an object attr<br/>that includes read?<br/>e.g. engineer to research-docs"}
OA --> A
A -->|no| D1["DENY, no privilege path"]
A -->|yes| P{"Any prohibition removes read here?"}
P -->|yes| D2["DENY, prohibition wins"]
P -->|no| PERMIT["PERMIT, privilege path survives"]Two properties of this procedure are NGAC’s headline advantages. It’s deterministic and bounded: there’s no ambiguity about rule order and no subtlety in combining algorithms, because the answer is a function of the graph and its cost grows with the graph’s size, not with an ever-growing heap of independently written rules. And the same graph answers review queries as naturally as it answers access requests. “What can Sara access?” means collecting her user attributes, following every association out of them, and listing the object attributes and their contents she reaches. “Who can delete this record?” is the mirror image. Those per-user and per-object questions are what auditors and access certification programs live on, and RBAC and especially ABAC answer them only by expensive enumeration, the reverse-query problem. In NGAC they’re native traversals, because access is structural rather than computed by opaque rules. The auditor’s question to Sara’s company would be one traversal.
One graph, several policies
A subtle but powerful feature is the policy class. The same graph can contain several policies at once, each rooted in its own policy class, and an element can be assigned up into more than one of them. The rule that ties them together is strict: a request is granted only if it’s granted under every policy class that governs the object. That’s how NGAC expresses coexisting, independently written policies. A role policy, a data classification policy, and a project confidentiality policy can all live in one graph, and access requires satisfying all of them, exactly like the overlapping concerns of real governance.
Real organizations never have just one policy. Legal wants classification rules, a business unit wants role rules, a project wants need-to-know rules, and access should require passing all three. In most models you’d hand-code that intersection, which is precisely the glue code between Sara’s three systems. In NGAC it’s built in, because each concern is a policy class and the decision procedure already requires every governing class to grant.
The cleanest way to see NGAC is as a chameleon. Make user attributes behave like roles and limit associations accordingly, and the graph is an RBAC system. Let associations run between rich user and object attributes, and it’s ABAC. Use assignments to model containment and relationships between resources, and it approaches ReBAC. NGAC doesn’t ask you to abandon the mental models of the earlier articles; it asks you to see them as presets of one general machine. That reframing is the most valuable idea in this article, whether or not you ever deploy NGAC.
The earlier models, inside NGAC
The claim is easy to make and worth making concrete. Take RBAC first. A role is just a user attribute grouping users, and a permission is an association from that attribute to an object attribute. UA:manager ⇒ {approve} ⇒ OA:expenses is exactly the role-grants-permission structure of the RBAC article; UA:senior-manager → UA:manager is a role hierarchy expressed as containment; and constrained RBAC’s separation-of-duties rule becomes a prohibition. In NGAC’s terms, RBAC is the special case in which user attributes are named after jobs and access flows only through associations.
Now ABAC. Where RBAC used a handful of role-shaped attributes, ABAC uses many descriptive ones, department, clearance, region, project, and NGAC represents each as its own user or object attribute container, with associations between the ones that should grant access. “Engineers in the research project may read research documents” is an association from the intersection of UA:engineer and UA:research-project to OA:research-docs. The attribute-driven decisions of the ABAC article become associations over attribute containers, while ABAC’s environmental conditions, time and risk, attach as constraints, the same seam ReBAC ran into. ReBAC, finally, is approached by using assignments to model containment and ownership between resources: a document assigned into a folder’s object attribute inherits the folder’s associations, which is the folder-tree inheritance ReBAC expressed with tuple-to-userset. Three models, one graph, three configurations.
Obligations: policy that rewrites itself
One element sets NGAC apart from most models: the obligation, an event-response rule of the form “when this event happens, automatically perform these administrative operations on the graph.” Because administrative actions in NGAC, creating assignments, associations, and prohibitions, are themselves operations the model can express, an obligation can change the policy in response to events. “When a user opens a case, give them access to that case’s records; when they close it, take it away” becomes a pair of obligations that add and remove assignments automatically, with no workflow outside the model. That lets NGAC express dynamic, history-dependent policies, separation of duties that reacts to what a user has already done, emergency grants that expire on their own, access scoped to a workflow, inside the model rather than in surrounding code. It’s the same instinct as the obligations in PBAC, generalized into a policy that can administer itself.
NGAC and XACML: two roads to fine-grained authorization
NGAC is best understood next to XACML, the other major standard for fine-grained, attribute-aware authorization, covered in the next article. They pursue the same goal by opposite means.
| Dimension | XACML | NGAC |
|---|---|---|
| Policy form | Rules in a language (target, condition, effect) | A directed graph of relations |
| Evaluation | Match the request against rules, combine results | Walk the graph for a privilege path |
| Combining logic | Explicit combining algorithms resolve conflicts | Deterministic; prohibitions override grants |
| Review queries | Expensive, evaluated against many subjects | Native traversals (“what can X access?”) |
| Multiple policies | Policy sets with combining algorithms | Policy classes; access needs all of them |
| Maturity and tooling | Older, broader historical adoption | Newer, thinner tooling, growing |
In short, XACML computes decisions from rules while NGAC reads them from structure. XACML’s approach of rules plus combining algorithms is enormously flexible but can become hard to reason about: with many policies and combining algorithms, “what does this actually decide, and why?” gets genuinely difficult, and answering “what can this user reach?” means evaluating the whole rule set against them. NGAC’s graph makes evaluation deterministic and review queries cheap, at the cost of a younger ecosystem and the discipline of thinking in graphs. Neither is simply better; they’re different shapes of the same ambition.
NGAC in practice
Because NGAC is a standard rather than a product, using it means adopting an implementation of the model, and the same functional architecture appears in all of them, the architecture the next article formalizes. A policy decision point answers requests by walking the graph, a policy enforcement point in each application asks and enforces, a policy administration point is where the graph is written, and, specific to NGAC’s obligations, an event processing point watches for events and fires the administrative operations obligations describe. NIST publishes an open reference implementation of the Policy Machine so the model can be studied and exercised directly, and a small number of commercial platforms build on or align with the standard. The ecosystem is clearly younger and narrower than the one around OPA and Rego or Zanzibar-style engines, the honest counterweight to NGAC’s conceptual elegance.
Where does NGAC realistically fit today? It’s most compelling in environments that already think in attributes and need access that can be proven and reviewed: government, defense, healthcare, and large regulated companies, the settings where MAC and formal models found their home. There, answering “exactly who can reach this record, and under which policies?” by reading a graph is worth real investment, and the determinism reassures auditors in a way a pile of combinable rules doesn’t. For a typical web application reaching for authorization today, a Zanzibar-style engine or an OPA policy will usually have more community, more examples, and an easier start. NGAC is the model to understand everywhere and deploy selectively, which is how a unifying framework tends to enter the world: ideas first, infrastructure later.
Strengths and honest limits
NGAC’s strengths follow from its design. It’s genuinely general, one framework for role, attribute, and relationship policy, so you can mix them without switching engines. Its evaluation is deterministic and analyzable, avoiding the combining-algorithm ambiguity that makes large rule sets hard to trust. Its review queries are efficient, a real operational gift, since certification, “who can touch this?”, and “what can they reach?” are the questions governance actually asks. And prohibitions and obligations let it express denials and dynamic, self-modifying policy that many models can’t state at all.
The limits are just as real. Adoption and tooling are still early: compared with the ecosystems around RBAC, OPA, or Zanzibar-style engines, NGAC has fewer production implementations, fewer libraries, and a smaller community, so choosing it means building more yourself. There’s a conceptual learning curve, because thinking in assignments, associations, and prohibitions over attribute containers is unfamiliar, and a badly modeled graph can produce a security bug like any other mechanism. And running the graph at scale, keeping it correct as attributes and assignments change and evaluating it with low latency, is its own engineering problem, the same tension between freshness and performance this whole part of the domain keeps circling.
Generality also isn’t the same as simplicity. A framework general enough to be RBAC, ABAC, and ReBAC at once is unavoidably more abstract than any of them, and that abstraction is paid for in modeling care and tooling. NGAC’s value isn’t that it’s simpler than the models it includes; it’s that it gives you one coherent structure and one decision procedure instead of three engines stitched together. Whether that trade is worth it depends on how much your real policy spans the models. The more it does, the more NGAC’s unification pays off; the less it does, the better a single specialized model will serve you.
Sara’s roadmap, one last time
The graph in the figure is the example, so trace the decision end to end. Sara is assigned to UA:engineer, which is assigned to UA:staff; roadmap.md is assigned to OA:research-docs, which is assigned to OA:company-files. The association engineer ⇒ {read, write} ⇒ research-docs grants read and write across those containers. When Sara asks to read roadmap.md, the engine collects her attributes, engineer and staff, collects the object’s, research-docs and company-files, finds the association linking engineer to research-docs with read in its set, checks that no prohibition removes it, and permits. When she asks to delete it, no association grants delete, and the broader company-files container also carries the prohibition engineer ⊘ {delete}, so the request is denied twice over. Every earlier model reached the same answer; NGAC reaches it by reading the graph’s structure.
Now add a second policy class, a classification policy, over the same objects, with its own association granting read on research-docs only to UA:cleared. Reading roadmap.md now requires satisfying both policy classes: Sara has to be an engineer, under the role policy, and cleared, under the classification policy. That’s RBAC and a classification model composing in one graph with no glue code, the exact situation that left Sara’s company with three systems and an unanswerable audit question. And because obligations can add assignments in response to events, “cleared” could be granted automatically when Sara completes a training course, letting the policy evolve without an administrator. That’s what one model for all of them buys: not less thinking, but one place for all of it.
Recap
Next-generation access control unifies the earlier models in one graph. Users, user attributes, objects, object attributes, and policies are nodes; assignments, associations, and prohibitions are edges; and a decision is a search for a privilege path from user to object. The grammar is small and expressive: assignments build user and object hierarchies, an association grants operations from a user attribute to an object attribute, and a prohibition takes them away and overrides grants. It takes in RBAC, ABAC, and ReBAC as configurations of one framework, the standardized form of NIST’s Policy Machine (INCITS 565), from the same lineage as RBAC. Deterministic evaluation and native review queries are its standout advantages, policy classes let several policies coexist with access requiring all of them, and obligations let the policy change itself in response to events. And adoption and tooling are still early, and generality costs abstraction, so for now NGAC is most valuable as a unifying way to think about authorization, even where it isn’t the engine you deploy.
Three questions to test yourself
- Define assignment, association, and prohibition in NGAC, and use all three to write the graph edges that would let engineers read and write research documents but never delete company files. Which edge type carries the set of operations, and which overrides the others?
- Explain how NGAC answers “what can this user access?” as a graph traversal, and why the same question is expensive in ABAC. Why does that make NGAC attractive for access certification and audit?
- NGAC claims to include RBAC, ABAC, and ReBAC. Pick two of them and describe concretely what you’d configure in an NGAC graph to make it behave like each, and explain what NGAC’s generality costs you in return.
Hands-on exercises
- Model a two-policy graph on paper. Draw an NGAC graph with one role-style policy class (an
engineeruser attribute granted read and write on aresearch-docsobject attribute) and one classification policy class (acleareduser attribute granted read on the same objects). Put a user in both, and trace why a request is permitted only when both policy classes grant it. - Add a prohibition and an obligation. Extend your graph with a prohibition denying delete on a
company-filescontainer, and describe an obligation of the form “when a user is assigned toengineer, automatically assign them tostaff.” Explain how each changes the decisions the graph produces. - Compare a decision with XACML. Take one access rule and express it twice, once as an NGAC association plus any prohibition, and once as an XACML-style rule with a target, condition, and effect. List what becomes easy in each, focusing on how you’d answer “who can do this?” in both.
Frequently asked questions
What is Next-Generation Access Control (NGAC)?
Next-generation access control is a standardized access-control framework (ANSI/INCITS 565, developed from NIST's Policy Machine) that represents users, user attributes, objects, object attributes, and policies as elements of a single directed graph, and computes an access decision by finding a privilege path from the requesting user to the target object through that graph. Assignment edges place elements into attribute containers, association edges grant operations between attribute sets, and prohibitions take access away. Because roles, attributes, and relationships can all be expressed with the same graph structure, NGAC is designed as a general framework that includes RBAC, ABAC, and ReBAC rather than competing with them.
How does NGAC differ from XACML?
Both are standards for fine-grained, attribute-aware authorization, but they take different shapes. XACML expresses policy as rules written in a language and evaluated by matching a request against them; NGAC expresses policy as a directed graph of relations and evaluates by walking it. In practice, NGAC's evaluation is deterministic and bounded by the graph rather than by rule-combining logic, it can answer review questions efficiently, such as what a user can access and who can access an object, and one NGAC graph can hold several coexisting policies as separate policy classes. XACML has broader historical tooling; NGAC offers a more analyzable, unified data model.
What are assignments, associations, and prohibitions in NGAC?
They're the three core edge types of the NGAC graph. An assignment places one element inside another, a user into a user attribute or an object into an object attribute, forming containment hierarchies; assignments give NGAC its structure. An association is the grant: it connects a user attribute to an object attribute with a set of operations, meaning members of this user attribute may perform these operations on members of this object attribute. A prohibition explicitly withholds operations from a user or attribute over some set of objects, and prohibitions override grants, letting NGAC express exceptions that purely grant-based models can't.
Does NGAC replace RBAC and ABAC?
Not by competing on the same axis. NGAC is better understood as a general framework in which RBAC and ABAC are special cases. Model user attributes as roles and you have RBAC inside NGAC; model them as arbitrary attributes with associations between attribute containers and you have ABAC inside NGAC; model containment and relationships as assignments and you get close to ReBAC. NGAC aims to be the one formal structure that can express all of them at once, so an organization can mix role, attribute, and relationship rules in one policy without switching engines. Whether it replaces the others in practice depends on tooling and adoption, which are still maturing.
What is the Policy Machine?
The Policy Machine is the NIST research model, led by David Ferraiolo and colleagues, that NGAC standardizes. It introduced the idea of a general-purpose access-control mechanism whose behavior is entirely set by a configurable graph of users, attributes, objects, operations, associations, prohibitions, and obligations, so that different access-control policies (RBAC, ABAC, multilevel, and combinations) are just different configurations of the same machine rather than different mechanisms. NGAC (INCITS 499 and later INCITS 565) is the standardized form of the Policy Machine's model, and NIST provides a reference implementation.