RBAC vs ABAC: Výběr správného modelu řízení přístupu

Řízení přístupu na základě rolí je jednoduché a funguje dobře pro většinu aplikací. Řízení přístupu na základě atributů ti dává jemnozrnnou kontrolu, když samotné role nestačí. Zde je popis, jak se rozhodnout.

·4 min čtení

Každá aplikace s více než jedním typem uživatele musí rozhodnout, kdo může vidět a dělat co. RBAC (Role-Based Access Control) a ABAC (Attribute-Based Access Control) jsou dva dominantní modely. Stejný problém, různé úrovně granularity.

RBAC: Role na prvním místě

V RBAC definuješ role a přiřazuješ oprávnění těmto rolím. Uživatelé dostávají role.

uživatel → role → oprávnění

Jednoduchý příklad:

type Role = 'admin' | 'editor' | 'viewer'

const permissions: Record<Role, string[]> = {
  admin: ['read', 'write', 'delete', 'manage_users'],
  editor: ['read', 'write'],
  viewer: ['read'],
}

function can(user: { role: Role }, action: string): boolean {
  return permissions[user.role].includes(action)
}

Toto se snadno rozumí, snadno implementuje a snadno audituje. “Může tento uživatel mazat příspěvky?” je jeden dotaz. Většina dashboardů, CMS platforem a SaaS produktů s jednoduchými strukturami tierů funguje dobře s RBAC.

Kdy RBAC funguje dobře:

  • Uživatelé mají jasné, stabilní role (admin, člen, host)
  • Oprávnění se čistě mapují na tyto role
  • Pravidla oprávnění nezávisí na kontextu

Kde RBAC selhává:

  • “Uživatelé mohou upravovat vlastní příspěvky, ale ne příspěvky ostatních”
  • “Manažeři mohou schvalovat výdaje do 5 000 Kč, ale ne nad to”
  • “K dokumentům mají přístup pouze uživatelé ze stejného oddělení”

Každý z těchto požaduje znát něco nad rámec jen role uživatele: kdo vlastní zdroj, jaká hodnota je zapojená, do jaké skupiny uživatel patří. RBAC to nemůže čistě vyjádřit bez vytváření exploze vysoce specifických rolí.

ABAC: Atributy všude

V ABAC jsou rozhodnutí o přístupu přijímána na základě atributů – vlastností uživatele, přistupovaného zdroje a prostředí. Nejsou žádné pevné role. Píšeš politiky, které tyto atributy vyhodnocují v čase požadavku.

politika(uživatelské atributy + atributy zdroje + prostředí) → allow/deny

Konkrétní příklad:

type User = { id: string; department: string; level: number }
type Document = { ownerId: string; department: string; classification: 'public' | 'internal' | 'restricted' }

function canAccess(user: User, doc: Document, action: 'read' | 'edit'): boolean {
  // Kdokoliv může číst veřejné dokumenty
  if (doc.classification === 'public' && action === 'read') return true

  // Interní dokumenty: pouze stejné oddělení
  if (doc.classification === 'internal' && user.department !== doc.department) return false

  // Úprava: musí být vlastník nebo senior (level >= 3)
  if (action === 'edit') return doc.ownerId === user.id || user.level >= 3

  // Omezené: senior ve stejném oddělení pouze
  if (doc.classification === 'restricted') {
    return user.department === doc.department && user.level >= 4
  }

  return false
}

Pravidla ABAC se čtou téměř jako přirozený jazyk. Můžeš vyjádřit nuancované politiky, které RBAC nemůže reprezentovat bez násobení rolí.

Kdy je ABAC správná volba:

  • Pravidla přístupu závisí na tom, kdo zdroj vlastní
  • Pravidla se liší na základě datových hodnot (sumy, data, klasifikace)
  • Uživatelé pokrývají organizace, oddělení nebo tenanty s různými pravidly
  • Máš požadavky na shodu, které vyžadují auditovatelné záznamy jemnozrnného přístupu

Porovnání vedle sebe

FaktorRBACABAC
Složitost implementaceNízkáStřední–Vysoká
Složitost pochopeníNízkáStřední
Jemnozrnná kontrolaOmezenáVynikající
VýkonRychlý (vyhledání role)Pomalejší (vyhodnocení politiky)
Auditní stopaPer rolePer rozhodnutí politiky
Vhodný proJednoduché aplikace, SaaS tieryPodniky, multi-tenant, shoda
Škáluje s rostoucími pravidlyRole se násobíPolitiky zůstávají sémantické

Nemusíš si vybrat jen jedno

Nejpragmatičtější přístup pro většinu aplikací je RBAC s kontrolami vlastnictví zdrojů vrstvených na vrcholu.

function can(user: User, action: string, resource?: { ownerId: string }): boolean {
  // Nejprve kontrola role
  if (!roleHasPermission(user.role, action)) return false

  // Kontrola vlastnictví pro operace zápisu
  if (resource && action !== 'read') {
    return user.role === 'admin' || resource.ownerId === user.id
  }

  return true
}

Toto zvládne 90% reálných případů bez plné složitosti policy engine. Přidej ABAC, když pravidla to skutečně vyžadují.

Co používám

Pro osobní projekty a early-stage SaaS: RBAC s kontrolami vlastnictví. Jednoduché, auditovatelné, hotové za odpoledne.

Pro multi-tenant systémy nebo cokoliv s požadavky na shodu: správný ABAC policy engine. Casbin je solidní pro TypeScript – podporuje oba modely a je dobře udržovaný.

Past je budovat RBAC a pak přišroubovávat ABAC požadavky dodatečně. Pokud tvá pravidla přístupu již závisí na atributech zdrojů nebo organizačním kontextu, navrhni pro to od začátku místo toho, aby ses dostal do rohu s rolemi.