Skip to content

Authorization is still quite broken

Posted on:
2 min

I’ve been thinking about authorization systems. RBAC, ABAC, Re-BAC, all that jazz. I’ve been fascinated with the Zanzibar paper ever since I read it. I’m not as interested so much in the scale as I am in the granularity and flexibilty in modelling relationships. Solutions like OpenFGA and SpiceDB aim to implement something that resembles Zanzibar but they feel broken in their own ways and this has been on my mind for quite some time.

To begin with, here’s me trying to model Fleet, an MDM in OpenFGA.

type device
  relations
    define seller: [business]
    define can_delete: [business#member] or owner from seller
    define can_revoke: [business#member] or owner from seller
    define can_read: [business#member] or owner from seller

The statement owner from seller would mean that the business owner has full access. In this case, I could also not check for authorization when I already know that the user authenticated is the owner but that doesn’t leave an audit trail, which is part of why we’re using an authorization service. Alternatively, I could also model the business owner as a member of the business, making the check() call simpler.

type device
  relations
    define can_delete: [business#member]
    define can_revoke: [business#member]
    define can_read: [business#member]

When using the latest SDK (0.9.0 at the time), the only relevant information the check() method returns is a boolean value allowed. This prevents me from generating a useful error message for the end user if they do not have access to a resource. I found an example of a complex schema at Grafana but I couldn’t help but think that this is still limiting with auditing.

const { allowed } = await openFga.check({
  object: 'usage',
  relation: 'can_create',
  user: 'undefined?'
})

Could this be done better using error codes? Did we peak at XACML? Am I doing this wrong?

I don’t know but I dislike how we do authorization and I’d like to find better ways to do it that is fast, transparent, and prevents redundancies between application and authorization databases.