RBAC og ABAC: Dagens standard
RBAC: Den Tradisjonelle
Når du logger inn i nesten hvilket som helst system i dag, skjer det en god del bak kulissene for å finne ut ikke bare hvem du er, men hva du har lov til å gjøre. Den klart vanligste tilnærmingen er RBAC (rollebasert tilgangsstyring), som i praksis er så enkelt som at systemet konkluderer: “Ola Nordmann har logget inn, Ola har rollen kommentator, altså tillater vi at han skriver i kommentarfeltet.”
Men RBAC har ett fundamentalt problem som på engelsk kalles role explosion. Roller er såpass enkle at de i praksis bare er tekstetiketter som programmet sammenligner med det brukeren prøver å gjøre. Hvis Ola er moderator i en lukket gruppe “Gaupa” hos selskapet “Eksempel AS”, er det logisk å opprette en rolle som heter eksempel_as:gaupa:moderator. Det fungerer fint i det små, men med hundrevis av selskaper, hundrevis av grupper per selskap og tusenvis av brukere, eksploderer plutselig antallet roller du må holde styr på. Og det blir bare verre jo flere dimensjoner du legger til: tenk om hver gruppe i tillegg har egne nivåer, prosjekter eller midlertidige tilganger.
ABAC: Oppfølgeren
ABAC (attributtbasert tilgangsstyring) ble tenkt som løsningen på role explosion.
Der RBAC baserer seg på faste roller, bygger ABAC i stedet på attributter – felt og verdier knyttet til brukeren, ressursen, handlingen og miljø rundt forespørselen.
{
"navn": "Ola Nordmann",
"selskap": "eksempel_as",
"grupper": ["gaupa", "ulven"],
"moderator_i": ["gaupa"]
}
Kommentarfeltet inne i Gaupa-gruppen har på sin side attributter som forteller hvor det hører hjemme:
{
"type": "kommentarfelt",
"selskap": "eksempel_as",
"gruppe": "gaupa"
}
I stedet for å slå opp én spesifikk rolle, evaluerer systemet en regel ved hver forespørsel, for eksempel: “tillat sletting av kommentar hvis bruker.selskap == ressurs.selskap OG ressurs.gruppe finnes i bruker.moderator_i”. Én slik regel erstatter det som i RBAC ville vært en egen rolle for hver eneste kombinasjon av selskap og gruppe. Skal du legge til et nytt selskap eller en ny gruppe, trenger du ikke definere noen nye roller; attributtene faller bare på plass av seg selv.
Det fine er at disse attributtene som regel kommer fra systemer du allerede vedlikeholder: HR-systemet vet hvilket selskap Ola jobber for, gruppetjenesten vet hvilke grupper han er medlem av, identitetsleverandøren vet hvor han logger inn fra. Når Ola bytter avdeling eller mister moderatorstatusen sin i Gaupa, oppdateres attributtene ett sted, og tilgangen følger automatisk med. Du slipper å manuelt tildele og rydde opp i hundrevis av spissede roller.
Bakdelen er at ABAC er vanskeligere å gjøre oppslag av hvem som har tilganger. Med RBAC kan du alltid liste opp medlemmene av en rolle for å se hvem som har tilgang til hva; med ABAC må du resonnere om regler opp mot hvilke attributter brukerne faktisk har akkurat nå og de endrer seg ofte hele tiden. I praksis lander derfor mange på en hybrid: RBAC tar seg av de grove, stabile skillene (ansatt, admin, revisor), mens ABAC legges oppå for de finkornete, kontekstavhengige betingelsene som ellers ville drevet frem “role explosion”.
ReBAC: Relasjoner som tilgang
I naturen så assosiereres veldig mye til relasjoner, ReBAC tar utgangspunkt i akkurat dette. Istedenfor å gjøre som over med ABAC og RBAC, så spør vi heller “Har Ola en relasjon til gruppen Gaupa, som heter moderator_i?” og om “Ola -> moderator_i -> Gaupa”, så får han lov til å moderere gruppa Gaupa.
Dette er ett relativt kjent mønster som kommer fra ett Google sitt Zanzibar prosjekt og som er den samme modellen som brukes til å blant annet dele tilgang til dokumenter til andre i Google docs. Det brukes også av andre større aktører, ettersom det både forhindrer role explosion.
En av de største fordelene av ReBAC er at utover “Ola har moderator_i relasjonen til Gaupa”, så kan vi også sette opp regler som “Ola er eier_av eksempel_as, han har derfor moderetor_i tilgangen i alle grupper som ligger under eksempel_as”. Dette gjør så vi kan modellere langt mer komplekse tilgangsstyringsmodeller en det vi kunne ha presentert med RBAC og ABAC.
Selv om ReBAC er ofte lettere å rasjonalisere seg rundt, men kommer med en ulempe på systemet bak ofte er vanskligere å drifte. Vanlige graf databaser blir ofte brukt for ReBAC systemer, og slike type databaser lagrer en kanskje en av de mest komplekse datastrukturene som finnes. Hvis vi bryter det opp så kan vi tenke fra “mest simpelt” til “mest komplekst” i forhold til datastrukturer som:
- Key-value (felt + verdi; Redis, NATS)
- Dokumentdatabaser (Mongodb)
- Relasjonsdatabaser (Postgres/SQL)
- Graf Databaser (Janusgraph, Memgraph og Neo4j)
Key-value databaser er ofte enkeleste å skalere og kan kjapt synkronisere data på tvers av mange maskiner med enkle algoritmer hvor flere av maskinene kan ta imot data samtidig, imens relasjonsdatabaser som Postgres ofte er vanskligere å skalere, krever tyngre algoritmer, krever mer for å kunne skrive til flere maskiner samtidig og vil feile oftere og krever det som heter “write-ahead logs” for å få synkronisere data på tvers av flere maskiner. Graf databaser er mest kompleks, men det er derfor mange bygger egne spesialiserte graf databaser/systemer ved bruk av graf teori på toppen av key-value databaser. Det siste punktet er hvordan ReBAC ofte kan skaleres, dataene lagres i en høyt skalerbar database og graf nettverket kjøres igjennom en algoritme som kjører på toppen. Noen av disse systemene kan være treige å skrive til, men kjappe å leses fra. Så for skrivehandlinger, så kan det ofte bli brukt ett ekstern køsystem for å holde dataene synkronisert og responsivt.
ReBAC løser ikke bare role explosion, men den gjør det også lett å se hvem som har tilgang til hvilken ressurs og hvilke ressurser noen har tilgang til. Det kan også brukes for å filtere store lister med data basert på tilgang eller å se hvilke tjenester en bruker har tilgang til når en meny skal presenteres. Nedsiden er at “pagination” kan bli vanskelig, ettersom relasjoner ikke har en rekkefølge på hvordan dataene hentes inn. Dette kan derimot løses på andre måter som å legge inn samme data i ett system som passer bedre til slikt.
Alt i sammenheng
Hvis vi ser på alt enkeltvis så virker det som ReBAC kan være løsningen, så er faller ofte svaret litt nærmere “kanskje litt av alt”, det er lett å gi en bruker rollen “admin” for en hel plattform og bruke attributer for å definere mer spesialiserte med bredere tilfeller en det ReBAC krever, så kan ReBAC håndtere tilgang til enkeltressurser.
Hvis du velger å gå for noe slikt derimot, så anbefaler vi å se på noe som heter OPA (Open Policy Agent) som er ett eget system og språk for å holde evaluerings logikk sentralisert på ett sted og uavhengig av koden som skal beskyttes. Hvis det er noe som er ukjent, så spør oss gjerne.
Kjapp kommentar rundt OWASP top 10
Hvis du ikke helt forstår hvorfor tilgangskontroll, RBAC, ABAC og ReBAC er viktig å forstå, så er feil i regler rundt tilgangskontroll den største årsaken til at ett system blir utnyttet i følge OWASP top 10 (en global måling for kategorier av utnyttede sårbarheter). Det er derfor du burde sørge for at tilgangskontrollen er gjort skikkelig.