{"post":{"slug":"authorization-explained-2026","title":"Authorization explained in 2026: RBAC, ABAC, and ReBAC compared","excerpt":"Authorization determines what authenticated users can actually do. This is the 2026 guide to RBAC, ABAC, and relationship-based access control.","category":"code","date":"March 24, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">A</span>uthorization answers a different question than authentication. Authentication asks \"who are you?\" — authorization asks \"what are you allowed to do?\" Most security incidents involve authorization failures, not authentication failures, because authorization is harder to model correctly and easier to get wrong at the edges. Here is how the three dominant models work in 2026.\n\n## What changed in 2026\n\n- **ReBAC went mainstream.** OpenFGA (open-sourced by Okta/Auth0) and Google Zanzibar-inspired systems became accessible enough for mid-size teams, not just hyperscalers.\n- **OPA (Open Policy Agent) became the standard** for infrastructure and Kubernetes authorization; WASM-compiled Rego policies now run at the edge.\n- **Fine-grained authorization** emerged as a product category — platforms like Permit.io, Oso, and Cerbos abstract the storage and evaluation layer so engineers focus on policy, not plumbing.\n- **JWT claims alone are insufficient** — teams realized embedding roles in tokens without a server-side check creates stale authorization; the token might say `admin` after a demotion.\n\n## The three models\n\n### RBAC — Role-Based Access Control\n\nUsers are assigned **roles**; roles have **permissions**; permissions gate actions on resources.\n\n```python\n# Simple RBAC check\ndef can_do(user_roles: list[str], required_permission: str, permissions_map: dict) -> bool:\n    for role in user_roles:\n        if required_permission in permissions_map.get(role, []):\n            return True\n    return False\n\npermissions_map = {\n    \"admin\":  [\"post:create\", \"post:delete\", \"post:read\"],\n    \"editor\": [\"post:create\", \"post:read\"],\n    \"viewer\": [\"post:read\"],\n}\n\ncan_do([\"editor\"], \"post:delete\", permissions_map)  # False\n```\n\n**Fits:** SaaS applications with a fixed tier structure (free/pro/admin), internal tools, most CMSes.\n\n**Breaks down:** when permissions depend on the *specific resource instance* (\"edit your own posts but not others\") or on context (time, location, risk score).\n\n### ABAC — Attribute-Based Access Control\n\nPolicy is expressed as conditions over **attributes** of the user, the resource, the action, and the environment.\n\n```\nALLOW IF\n  user.clearance_level >= resource.classification AND\n  user.department == resource.department AND\n  env.time BETWEEN 09:00 AND 18:00\n```\n\nExtremely expressive. Used in healthcare (HIPAA-driven row-level data access) and government systems. In 2026, OPA with Rego is the most common ABAC implementation outside bespoke systems.\n\n**Fits:** compliance-heavy domains, multi-tenant SaaS with complex tenant isolation rules.\n\n**Breaks down:** when attributes alone cannot capture graph-shaped relationships (\"can you see this comment because you're in the workspace that owns the document?\").\n\n### ReBAC — Relationship-Based Access Control\n\nPermission is derived from the **relationship graph** between users and objects. Inspired by Google Zanzibar.\n\n```\n# OpenFGA schema fragment\ntype document\n  relations\n    define owner: [user]\n    define editor: [user] or owner\n    define viewer: [user] or editor or member from workspace\n\ntype workspace\n  relations\n    define member: [user]\n```\n\nChecking \"can user:alice view document:42?\" traverses the graph: Alice → member of workspace:eng → workspace owns document:42 → viewer permission granted.\n\n**Fits:** collaborative tools (Notion, Google Docs model), folder hierarchies, social graphs, any data where \"who can see this?\" depends on ownership chains.\n\n## Model comparison\n\n| Model | Expressiveness | Complexity | Best for |\n| --- | --- | --- | --- |\n| RBAC | Low | Low | Fixed roles, SaaS tiers |\n| ABAC | High | High | Contextual, compliance-heavy rules |\n| ReBAC | High (for graphs) | Medium-High | Hierarchies, collaborative data |\n| ACL (per-resource list) | High | Very High | Rarely; too granular to manage |\n\n## How to pick\n\n1. **New app, unknown future requirements?** Start with RBAC. Add resource ownership checks (a lightweight ReBAC pattern) when users need per-resource control.\n2. **Complex tenant isolation or regulatory rules?** ABAC via OPA. Write policies as code, version them, test them.\n3. **Documents, folders, workspaces, or social graphs?** ReBAC via OpenFGA or a Zanzibar-compatible store.\n4. **Mixed requirements?** Layer them: RBAC for coarse-grained role checks, ReBAC for resource-level decisions.\n\n## Enforcing correctly\n\nAlways enforce at the **service layer**, not just the UI:\n\n```python\n# FastAPI middleware example\n@app.get(\"/posts/{post_id}\")\nasync def get_post(post_id: int, current_user: User = Depends(get_current_user)):\n    post = db.get(post_id)\n    if not authz.can(current_user, \"read\", post):\n        raise HTTPException(status_code=403, detail=\"Forbidden\")\n    return post\n```\n\nThe check must happen in the API handler or a data-access layer — not only in the frontend. Hiding a button does not prevent a direct API call.\n\n## Common mistakes\n\n**Embedding mutable roles in JWTs.** Tokens are cached. A demoted admin still carries the old role claim until the token expires. Validate roles from the database on sensitive operations, or use short-lived tokens.\n\n**Using RBAC when per-resource ownership is needed.** Adding `can_edit_own_posts` as a role permission leads to role explosion. Use a resource ownership check instead.\n\n**Policy drift.** Authorization logic scattered across route handlers, middleware, and data access. Centralize in a policy module or external engine.\n\n**No authorization tests.** Test that `editor` cannot call `delete`, that cross-tenant reads fail, that demotions take effect. Auth logic bugs are silent until exploited.\n\n**Returning 404 instead of 403 for security.** Returning 404 for unauthorized resources leaks information about existence. Return 403 Forbidden unless you intentionally want to hide resource existence (valid in some designs).\n\n## What to skip\n\n- **Rolling a custom policy engine** for non-trivial rules — Casbin, OpenFGA, and OPA handle edge cases you will miss.\n- **Storing permissions entirely in JWTs** without a server-side check for high-stakes actions.\n- **ACL per-resource lists** at scale — they become unmanageable past a few thousand resources.\n\n## FAQ\n\n**What is the difference between authorization and access control?**\nThey are often used interchangeably. \"Access control\" is the broader concept; \"authorization\" is the decision step that enforces it.\n\n**Should authorization logic live in the database or the application?**\nBoth layers should enforce it. Row-level security in Postgres is a strong safety net; application-layer checks give you better error messages and business logic context.\n\n**How do I handle authorization in microservices?**\nUse a centralized policy decision point (OPA sidecar, or an external authz service) and make each service call it. Avoid duplicating policy logic across services.\n\n**Is RBAC enough for a multi-tenant SaaS?**\nOften yes, if you scope roles per tenant. The common gap is per-resource ownership — add a simple \"is this user the owner?\" check alongside RBAC and you cover most cases.\n\n## Where to go next\n\n- [API authentication explained in 2026](/blog/api-authentication-explained-2026)\n- [Cookies vs tokens explained in 2026](/blog/cookies-vs-tokens-explained-2026)\n- [How to handle secrets in 2026](/blog/how-to-handle-secrets-2026)","hue":313,"metaTitle":"Authorization Explained 2026: RBAC, ABAC, ReBAC Guide","metaDescription":"Authorization in 2026: RBAC vs ABAC vs ReBAC explained with real examples. Pick the right model, enforce at the right layer, avoid common mistakes.","keywords":["authorization explained 2026","rbac vs abac","relationship-based access control","rebac explained","open fga authorization","casbin authorization","api authorization 2026","access control patterns","permission system design","role-based access control 2026"],"tldr":["**RBAC (role-based) is the right starting point** — assign roles to users, attach permissions to roles; it covers 80% of applications with minimal complexity.","**ABAC (attribute-based) handles context-dependent rules** — \"allow if user.department == resource.department AND time is business hours\" — but policy maintenance grows quickly.","**ReBAC (relationship-based) is required for social or hierarchical data** — \"can edit if user is owner OR member of the document's workspace\" maps naturally to a graph.","**Enforce at the data layer, not just the UI** — hiding a button is not authorization; the API must reject unauthorized requests regardless of client state.","**Skip:** building a custom authorization engine; Casbin, OpenFGA, or OPA handle the hard parts and are battle-tested."],"readTime":"5 min read","wordCount":1020},"related":[{"slug":"what-is-authentication-vs-authorization-2026","title":"Authentication vs authorization in 2026: who you are vs what you can do","excerpt":"Authentication proves who you are; authorization decides what you are allowed to do. This guide explains the difference, how they work together, and why mixing them up causes security holes.","category":"code","date":"May 25, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":0},{"slug":"least-privilege-iam-2026","title":"Least Privilege IAM: Narrowing Permissions Safely","excerpt":"Broad permissions get granted to unblock someone and never get narrowed. Here is a practical method for reducing them using observed usage rather than guesswork.","category":"code","date":"August 11, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":6},{"slug":"dependency-injection-explained-2026","title":"Dependency injection explained in 2026: from concept to production","excerpt":"Dependency injection is the pattern behind every testable, maintainable service. This 2026 guide covers the concept, DI containers, and when to skip them entirely.","category":"code","date":"March 10, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":320}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"api-rate-limiting-2026","title":"API rate limiting in 2026: algorithms, patterns, and implementation","excerpt":"Rate limiting protects your API from abuse and keeps costs predictable, but the wrong algorithm causes thundering-herd failures. Here is the 2026 guide.","category":"code","date":"March 24, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":306},"older":{"slug":"best-ai-data-analysis-tools-2026","title":"Best AI data analysis tools in 2026: from spreadsheets to code-first platforms","excerpt":"AI data analysis tools in 2026 range from chat-over-CSV products to full agentic pipelines. Here is what each does well and where each breaks down.","category":"ai","date":"March 24, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":200}}