I need to design and implement a RBAC (role based access control) library to protect RPC calls. A role is a list of verbs (RPC methods). One should be able bind a user (or group of users) to a role over a resource (or group of resources). The architecture needs to scale to 10^8 users and 10^8 resources.

I thought of having int64 unique identifiers for users and resources. I'd store group hierarchy, role binding and users and resources in a SQL or NoSQL database. Then I'd use Apache Spark to flatten (user, role, resource) tuples which I'd store somewhere I'd query quickly, like ElasticSearch.

I'm pretty sure this design scales. However, it is not clear how I'd handle group membership changes and role unbinding.

Any suggestions on how to make sure changes above won't leave lingering (user, role, resource) tuples?


One approach you might see is that a clear distinction is drawn between the (consistent) source of truth for all role assignments, and the (eventually consistent) database that is typically queried. This latter database behaves more like a cache, and entries are regularly expired. Expiry might be forced if a user, role, or resource changes, or entries might have a TTL, or you might have a background process that scans the cache to see whether it is still up to date. Such a design implies that RBAC changes need some time to take effect, typically on the scale of minutes to an hour.

If your source of truth is a denormalized database (or a NoSQL database) you'll have to carefully design your system to purge old entries when the RBAC assignments change. Compared to a TTL-based cache this has a higher chance of programming errors and the queries needed for purging old data might be expensive. However, changes will be able to propagate more quickly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.