Part 4 · 2 chapters · ~12 min
RBAC, ABAC and ReBAC
Role-based, attribute-based and relationship-based access control, policy engines (OPA, Cedar, Casbin), where and how to enforce checks, broken object level authorisation, the four-eyes principle, and auditing authorisation decisions.
9
Three models and policy engines
code
# OPA / Rego: tellers approve transfers under ₦1M in their own branch
package transfers.approve
default allow := false
allow if {
input.user.role == "teller"
input.transfer.amount_kobo < 100000000
input.transfer.branch_id == input.user.branch_id
not input.transfer.created_by == input.user.id # four eyes: not your own transfer
}RBAC, ABAC, ReBAC
three ways to decide "may this subject do this action on this resource?"
swipe the figure sideways, or tap expand for full screen
1/6
RBAC
Role-based access control maps roles (teller, branch manager, auditor) to permissions. It is easy to audit and explain; it struggles when access depends on which resource ("only accounts in my branch").
roles → permissionsstruggles with per-resource rules
10
Broken object level authorisation
code
// the bug: authenticated, but not authorised for THIS account
app.get('/accounts/:id', requireAuth, async (req, res) => res.json(await Accounts.find(req.params.id)));
// the fix: scope every query by the caller's rights
app.get('/accounts/:id', requireAuth, async (req, res) => {
const acct = await Accounts.findOne({ id: req.params.id, ownerId: req.user.id }); // or an authz check
if (!acct) return res.sendStatus(404); // 404, not 403: do not confirm existence
res.json(acct);
});