Attribute-Based Access Control: How It Works, When to Use It

Guilliano Molaire Guilliano Molaire 9 min read

Last updated: July 2026

Attribute-based access control (ABAC) decides whether to allow a request by evaluating attributes of the user, the resource, the action, and the environment against policy at the moment of the request. NIST SP 800-162 defines the model, and its standout benefit is that policies keep working “without prior knowledge of who will need access.” In practice, most teams in 2026 don’t replace roles with attributes. They layer attribute checks on top of a small set of roles.

What is attribute-based access control?

NIST SP 800-162 defines ABAC as an authorization model that grants or denies operations by evaluating attributes from four categories against policy:

Category What it describes Examples
Subject The user or service making the request Department, clearance level, job title, employment type
Object (resource) The thing being accessed Classification, owner, data type, project
Operation (action) What the subject wants to do Read, write, approve, delete, export
Environment The context of the request Time of day, source network, device posture, location

A policy then ties these together: “members of the finance department with clearance level secret or higher can view financial reports during business hours.” Nobody assigned those users to a “finance-report-viewers” group. The system checks the attributes when the request arrives.

That’s the property NIST highlights: policies work “without prior knowledge of who will need access.” Hire a new analyst tomorrow, set her department and clearance correctly, and every relevant policy already applies to her. Under pure role-based access control, someone has to remember to grant the right roles, and someone else has to remember to revoke them.

The trade is that access is computed, not stored. There is no list sitting in a database that says who can see the finance reports. That single design decision explains most of what follows, including why ABAC never took over the world.

The ABAC revolution that never happened

Here’s the part most ABAC articles skip. In 2013, Gartner predicted that 70% of enterprises would use ABAC as their dominant access control mechanism by 2020, up from under 5% at the time.

It didn’t happen. Not even close. RBAC remained the dominant model through 2020 and remains dominant today, and the 2026 norm is a hybrid: coarse-grained roles for the big buckets, attribute checks for the fine-grained and contextual decisions inside them.

Why did the prediction miss? A few honest reasons:

  • Audits got harder, not easier. With roles, “who can access this?” is a query. With attributes, the true answer is “run every possible combination of attributes through the policy engine and see.” Auditors, understandably, hate that answer.
  • Attribute quality is a full-time job. ABAC is only as good as the data feeding it. If HR’s department field is stale, your access decisions are stale. Many organizations discovered their identity data wasn’t clean enough to bet security on.
  • Roles were good enough. For a majority of applications, five roles cover 95% of cases. The remaining 5% got handled with one-off checks in application code, which is ugly but ships.

None of this makes ABAC bad. It makes ABAC a tool with a specific shape, best applied where context genuinely matters, rather than a wholesale replacement for roles. Keep that in mind whenever a vendor pitch implies otherwise.

ABAC vs RBAC vs ReBAC: which model fits?

The current landscape has three serious contenders, and each wins in a different scenario:

Model How access is decided Strengths Weaknesses
RBAC Pre-assigned roles; effectively an O(1) lookup Fast, simple, trivially auditable Role explosion once you need more than roughly 5-10 role variants
ABAC Computed at request time from attributes Context-aware rules, no role sprawl, policies survive org changes Access is computed rather than stored, so enumerating “who has access” for audits is hard
ReBAC Relationships between subjects and objects (the Google Zanzibar model, implemented by SpiceDB and OpenFGA) Per-object sharing at scale, Google-Docs-style permissions Extra infrastructure and real operational weight

Gartner’s current guidance frames the modern authorization decision as a choice among “Cedar, OPA, XACML and Zanzibar”, which is really a choice among ABAC policy languages (the first three) and ReBAC (the last one). That framing is useful: the question is no longer “roles or attributes?” but “which policy engine, and for which decisions?”

A practical rule of thumb:

  • Users share individual objects with each other (documents, folders, boards): ReBAC.
  • Decisions depend on context like time, clearance, department, or device: ABAC.
  • Everything else: a small set of roles, kept small on purpose.

Most real systems end up using two of the three.

Which policy engine should you use in 2026?

The engine landscape shifted noticeably in the last year, so it’s worth a current snapshot. Both Styra and Oso have published detailed comparisons; here’s the short version.

XACML is the canonical ABAC standard and the language NIST’s work grew up alongside. It’s also XML-heavy and aging. New projects rarely pick it, though it remains entrenched in government and finance.

Open Policy Agent (OPA) became the de facto general-purpose policy engine, with its Rego language used everywhere from Kubernetes admission control to API authorization. Its future is genuinely uncertain right now: Apple hired OPA’s core maintainers in August 2025, and Styra’s enterprise offering is sunsetting. OPA is open source and isn’t going away tomorrow, but “who steers this project?” is a fair question to ask before adopting it in 2026.

Cedar is AWS’s policy language, open sourced and designed to be readable and formally verifiable. Of the modern options, it’s the one where a security reviewer can look at a policy and actually understand it. If you’re starting fresh with policy-as-code, Cedar is the pragmatic default.

Zanzibar-style engines (SpiceDB, OpenFGA) solve ReBAC rather than ABAC, as covered above. Pick one when per-object sharing is the actual problem.

And then there’s the option this post cares most about: if you already run Keycloak for authentication, you already have an ABAC-capable authorization engine and might not need any of the above.

How does Keycloak implement ABAC?

Keycloak ships a full authorization services engine alongside its identity features. If Keycloak itself is new to you, start with our complete Keycloak guide; this section assumes you know what a realm and a client are.

The model, per the official authorization services guide, chains five concepts:

  1. Resources and scopes. A resource is a thing you protect (an API endpoint, a document type). Scopes are the actions on it (view, edit, delete).
  2. Policies. The conditions: “user has claim X,” “time is within Y,” “user is in group Z.” Policies are reusable and know nothing about specific resources.
  3. Permissions. The glue that says “this resource (or scope) requires these policies.”
  4. Decision strategy. How multiple policies combine: Unanimous (all must pass), Affirmative (at least one must pass), or Consensus (majority wins).
  5. Policy enforcer. The enforcement point (PEP) running on your resource server. It intercepts requests and asks Keycloak for decisions, with three modes: Enforcing (deny unless explicitly allowed), Permissive (allow unless explicitly denied), and Disabled (evaluate nothing, useful during rollout).

Under the hood, granted permissions travel in an RPT (requesting party token), a special access token your resource server obtains through the UMA Protection API. If you want to see what actually lands in your tokens, paste one into our JWT token analyzer.

The attribute-driven policy types are where ABAC happens:

  • Regex policies match a regular expression against a claim in the token. This is the no-code ABAC path, and it’s underrated.
  • Time policies restrict decisions to date ranges, hours, or days.
  • Group policies check group membership, useful in hybrid setups.
  • Aggregated policies bundle other policies with their own decision strategy, so you can build “finance AND cleared AND business hours” as one reusable unit.

One honest caveat for anyone following older tutorials: JavaScript policies can read identity and contextual attributes (for example kc.client.network.ip_address for the caller’s IP), but in Keycloak 26.x they cannot be uploaded through the admin console by default. Script policies must ship inside a deployed JAR as a script provider. Plenty of blog posts still show the old upload flow; it won’t work on a current server.

One policy, three ways: Cedar, Rego, and Keycloak

Definitions are cheap. Here’s the same real policy expressed in the three systems you’re most likely to evaluate, so you can judge readability and operational cost yourself.

The policy: finance department members with clearance level secret or higher may view financial reports, during business hours only.

Cedar

// clearance: 1 = confidential, 2 = secret, 3 = top-secret
permit (
  principal,
  action == Action::"view",
  resource in Folder::"finance-reports"
) when {
  principal.department == "finance" &&
  principal.clearance >= 2 &&
  context.hour >= 9 &&
  context.hour < 17
};

Readable enough that a non-engineer could review it, which is Cedar’s whole pitch. The context record (including the hour) is supplied by your application with each authorization request.

OPA and Rego

package authz

import rego.v1

clearance_rank := {"confidential": 1, "secret": 2, "top-secret": 3}

default allow := false

allow if {
  input.subject.department == "finance"
  clearance_rank[input.subject.clearance] >= 2
  business_hours
}

business_hours if {
  hour := time.clock([time.now_ns(), "UTC"])[0]
  hour >= 9
  hour < 17
}

More powerful, and more to learn. Rego is a query language, not an if-statement language, and that mental shift is the main adoption cost teams report.

Keycloak, no custom code

The same policy in Keycloak uses only built-in pieces:

  1. Store the attributes. Give each user department and clearance attributes via user management (the User Profile configuration makes these first-class fields).
  2. Get them into the token. Add User Attribute protocol mappers to your client so department and clearance appear as claims in the access token.
  3. Regex policy #1: target claim department, pattern ^finance$.
  4. Regex policy #2: target claim clearance, pattern ^(secret|top-secret)$.
  5. Time policy: hour range 9 to 17.
  6. Permission: create a scope permission on the financial-reports resource with the view scope, attach all three policies, and set the decision strategy to Unanimous so every condition must hold.

The policy enforcer on your API then blocks or allows requests with zero authorization code in your application. That’s a genuine ABAC deployment using nothing but the admin console.

The trade-offs are real, though. Keycloak’s policy model lives in the admin console rather than in git, so you don’t get code review and versioning the way Cedar and Rego give you out of the box (exporting authorization settings as JSON helps, but it isn’t the same workflow). Complex logic pushes you toward script providers and JAR deployments. For policy-heavy platforms, a dedicated engine earns its keep. For teams already running Keycloak that need attribute checks on a handful of APIs, the built-in engine is the shortest path by far.

When should you actually use ABAC?

Given the history above, the honest recommendation is narrower than most vendors offer. Reach for ABAC when:

  • Context changes the answer. Time, location, device, or clearance genuinely alter who should get in. Roles can’t express “only during business hours.”
  • Role explosion has already started. If you’re minting roles like finance-viewer-emea-contractor, attributes will dissolve that combinatorial mess.
  • Your attribute data is trustworthy. ABAC inherits the quality of your identity data. If user attributes come from a reliable HR feed or a disciplined provisioning process, you’re fine. If they’re hand-edited and stale, fix that first.

Stick with roles, or add ReBAC instead, when access is fundamentally about membership or about individual users sharing individual objects. And expect to run a hybrid: roles for the broad strokes, attributes for the contextual rules, exactly the pattern the industry converged on after the 70%-by-2020 prediction fizzled.

If you’d like the Keycloak version of this without operating the cluster yourself, that’s what we run at Skycloak, and the docs cover the authorization features in depth.

Frequently asked questions

What is attribute-based access control in simple terms?

ABAC is authorization by if-statements over facts instead of membership lists. When a request arrives, the system checks facts (attributes) about the user, the resource, the action, and the context against policy, and allows or denies on the spot. Nobody pre-assigns access; the policy computes it fresh each time.

What is the difference between ABAC and RBAC?

RBAC stores access decisions ahead of time as role assignments, making checks fast and audits easy. ABAC computes decisions at request time from attributes, which handles context (time, clearance, department) that roles can’t express, at the cost of making “who has access to this?” hard to answer. Most organizations run both together.

What are the four attribute categories in ABAC per NIST?

NIST SP 800-162 defines four: subject attributes (who is asking, such as department or clearance), object or resource attributes (what is being accessed, such as classification), operation attributes (the action, such as read or delete), and environment attributes (the context, such as time of day or source network).

Is ABAC better than RBAC for large organizations?

Not automatically, and history backs that up: Gartner’s 2013 prediction that 70% of enterprises would run ABAC by 2020 never materialized. Large organizations benefit from ABAC where contextual rules and role explosion are real problems, but RBAC’s auditability keeps it the backbone. The winning pattern at scale is hybrid, not replacement.

How do you implement ABAC in Keycloak?

Store attributes on users, map them into token claims with protocol mappers, then build policies in Keycloak’s authorization services: regex policies match claims, time policies bound hours, and aggregated policies combine them under a Unanimous, Affirmative, or Consensus strategy. A policy enforcer on your resource server then enforces the resulting permissions via RPT tokens, with no authorization code in your app.

Tired of running Keycloak yourself?

Skycloak runs real upstream Keycloak for you with a 99.99% SLA. No fork, no lock-in, just managed Keycloak that stays patched and on call so you don't have to.

Guilliano Molaire
Written by
Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Start Free Trial Talk to Sales
© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman