Free — no signup required

Fine-Grained Control: ABAC (Attribute-Based Access Control)

3 min read

When RBAC's static role model isn't flexible enough, we turn to ABAC — Attribute-Based Access Control. Where RBAC asks "what role does this user have?", ABAC asks "do the attributes of this user, this resource, and this environment satisfy our policy?"

The Three Pillars of ABAC

ABAC makes access decisions by evaluating attributes — key-value pairs describing the world — against a set of policies (logical rules).

1. Subject Attributes (Who is the user?)
Properties of the entity requesting access:
- user.department = "Finance"
- user.clearance_level = "confidential"
- user.employment_type = "contractor"

2. Resource Attributes (What are they accessing?)
Properties of the thing being accessed:
- resource.classification = "high_sensitivity"
- resource.owner_department = "Finance"
- resource.contains_pii = true

3. Environment Attributes (What is the context?)
Properties of the situation at the moment of access:
- environment.time = "02:00 UTC"
- environment.network = "corporate_vpn"
- environment.system_state = "emergency"

Writing ABAC Policies

Policies are logical expressions evaluated at runtime. A policy engine (like Open Policy Agent, AWS Cedar, or a database's row-level security engine) evaluates these expressions for every access request:

# Allow a doctor to read a patient record IF:
# - The doctor's assigned ward matches the patient's ward
# - The access is happening during business hours
# - The doctor is accessing from the hospital network

ALLOW read ON PatientRecord IF:
  user.ward == resource.ward
  AND environment.time BETWEEN "08:00" AND "20:00"
  AND environment.network == "hospital_internal"

This single policy replaces what would require dozens of RBAC roles.

RBAC vs. ABAC: Choosing the Right Tool

These models are not mutually exclusive. Most mature systems use RBAC as the foundation (for broad, stable permission categories) and layer ABAC on top (for dynamic, context-sensitive restrictions). RBAC handles "Alice is a doctor." ABAC handles "Alice can only see patients in her ward, during her shift, from the hospital network."

Dimension RBAC ABAC
Decision basis Static role membership Dynamic attribute evaluation
Flexibility Low — requires new roles for new cases High — policies handle new cases
Auditability High — "who has role X?" is simple Lower — "can Alice access this?" depends on runtime context
Implementation complexity Low High
Best for Stable, well-defined permission categories Dynamic, context-sensitive access rules

The senior engineer's insight: ABAC's power is also its danger. A policy that evaluates five attributes across three categories can produce access decisions that are nearly impossible to reason about after the fact. "Why did Alice get access to that record at 2 AM?" requires replaying the exact attribute values at that moment. Always ensure your ABAC system logs not just that access was granted, but which policy clause granted it and what attribute values were evaluated.

Interview Tip

Interviewers at companies with complex data access requirements (healthcare, finance, government) often ask: "How would you implement row-level security so users can only see their own department's data?" A weak answer describes application-level filtering. A strong answer describes ABAC implemented at the database layer using Row-Level Security (RLS) policies — for example, PostgreSQL's CREATE POLICY — so that even if the application has a bug, the database enforces the restriction. This is defense in depth: the policy is enforced at the data layer, not just the application layer.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free