My recommendation: think about how many
- implementation exist currently in this world for access management? I would bet some millions.
- man-hours are built into this field already? I can't even guess, and most of them are totally parallel...
- open source solutions are there, ready to use in your system?
So, it is very good that you started thinking about it, created a simple implementation, identified the core components and their functions.
But now you should focus on the task you have to do, and don't waste time on access management. It will surely be worse (less features, weaker structure, less tested, has several vulnerabilities caused by the problems of your platform you haven't even known) than anything that is available for you right now to integrate and use (well, I have assumed that you are not Superman and not pioneering on an esoteric field, both are very likely).
Imagine your application in its full size, collect the features and assumed counts (user, feature, role, requests per second, ...). Use Google to narrow your search to like five solutions, compare them by their reflection on forums, blogs, etc., select one and use it. On the other hand: separate you actual choice from your code with a custom interface that you create by your feature list. This will be a bless if you have to switch to another solution because of something that you don't know today.
I think this approach has more benefits even if you write this system in order to learn. You should adapt to formalize your requirements, evaluate available solutions and learn from other coders' good solutions instead of making the same beginner mistakes from which those solutions have evolved. To become a reliable programmer, you have to find the right balance between writing and using components, and learn to objectively value your time, and the quality of your code compared to what is available (background knowledge, coding perfection, available amount of man-hours to bug fix and maintain, for development and real-life test).
You don't write your word processor to edit a text file. Why? Then why should you write an access control component (and copy-paste it to other systems that you make)?
In some cases, there is an objective reason for both. In most cases, there is none. Sadly enough, programmers tend to think that a word processor is more serious task (so they use one) than a writing a truly reliable access management (so they write one). Last note: contrary to all above, it is very likely that I will write an access manager - but I have a good reason to do it. :-)