Access Control: Role-based Access control
After a quick look at Context-based Access control (CBAC) we can come back to Access Control List (ACL) types of schemes.
One big issue with ACL is the tediousness to declare permissions, you have to do it subject by subject while it would be convenient to do it for multiples subjects at the time.
Here comes Role-based Access control (RBAC).
As its name suggests it, it's based on roles, which are assigned to subjects.
Let's introduce few types:
data Role = SimpleUser | Admin | FileOwner deriving stock (Eq, Ord, Show)
type RbacRules role' resource action = Map.Map role' (Map.Map resource (Set.Set action))
Actually, if we take the time to refactor our ACL implementation, they are very close:
type AclRules resource actor action = Map.Map resource (Map.Map actor (Set.Set action))
So close, we can simply rely on it for RBAC.
canRbac rules role resource =
canAcl rules role resource
Let's add some tests:
describe "RBAC" $ do
let rules =
Map.fromList
[ ( Admin,
Map.fromList
[ (Motd, Set.fromList [Read, Write]),
(Shadow, Set.fromList [Read, Write]),
(FileOwned, Set.fromList [Read, Write])
]
),
(SimpleUser, Map.fromList [(Motd, Set.fromList [Read])]),
(FileOwner, Map.fromList [(FileOwned, Set.fromList [Read, Write])])
]
forM_
[ (SimpleUser, Motd, Read, True),
(SimpleUser, Motd, Write, False),
(SimpleUser, Shadow, Read, False),
(SimpleUser, Shadow, Write, False),
(SimpleUser, FileOwned, Read, False),
(SimpleUser, FileOwned, Write, False),
(Admin, Motd, Read, True),
(Admin, Motd, Write, True),
(Admin, Shadow, Read, True),
(Admin, Shadow, Write, True),
(Admin, FileOwned, Read, True),
(Admin, FileOwned, Write, True),
(FileOwner, FileOwned, Read, True),
(FileOwner, FileOwned, Write, True)
]
$ \tc@(role, resource, action, expected) ->
it (show tc) $
canRbac rules role resource action `shouldBe` expected
Note: FileOwner
is a trick to represent the ownership of a file at access-time,
it's not great since it forces us to dynamically changes roles, it's not-convenient
but used in other schemes.