- Our users can have a single role per account (internally an IAM domain), but may have roles across multiple accounts.
- Each role is defined as a list of permissible actions.
- In certain cases such as failed payments or suspicious activity, we'd like to limit some of their actions.
- We can also imagine cases in which we might give trusted or vetted users additional permissions, such as higher budget limits.
- Although these circumstances revolve around permissions, I don't think that they make sense as "roles" per se, and I also feel "roles" may get messy if a user can have multiple roles in an account (but maybe that's okay too, I'm not sure).
- And because of the mutual exclusivity of such circumstances, I thought maybe tagging was the best way to represent these subtractions and additions of permissions.
I wonder though, am I just adding unnecessary complexity? Are they really just additional "roles," and I should allow users to have multiple roles per account? Or, on the other end, has my system outgrown "roles" altogether and should migrate fully to tags? If both are practically used options, then what would you say are the deciding factors?
The rest of this is optional. Just describing the current architecture preemptively.
OPTIONAL: Current Architecture
We rely on an external system to store and serve user permissions. (We can influence it, but it's not easy to change it, as the system serves a much larger ecosystem than just our product.) We can ask this system,
Hey, can user
GetUsersInDomainin IAM domain
and it will respond yes or no. But it cannot answer questions like,
Hey, who are all the users who can do
GetUsersInDomainin IAM domain
This is fine for most applications, but not for building an administrative UI that must display, for example, all "admins" on a certain account.
Now in the external system, there's a concept of templates (sorry if this is obvious and basic). Just a list of actions that essentially translates to what our product calls a role (e.g. "admin"). Suppose these are some roles:
In order to be able to query for users by role, we created a service that mirrors and extends the external permissioning system, with a schema like:
| user | iam_domain | role | template | +------+-----------------------+--------+----------+ | 1 | org/6c1b5c24/75247aeb | admin | b7a3fe18 | | 2 | org/6c1b5c24/75247aeb | viewer | 29416fe6 | | 3 | org/5e02bab7/dd389a37 | admin | b7a3fe18 |
template are already concepts stored in the external system. And technically we don't really need
role since we always know, for example, that the "admin" template is "b7a3fe18". But having mirrored permissions these way, we can now query by
role as we like.
The new challenge however is: How do we implement multiple, independent roles per user and IAM domain?
There, my proposal is:
| user | iam_domain | role | template | tags +------+-----------------------+--------+----------+---------- | 1 | org/6c1b5c24/75247aeb | admin | b7a3fe18 | | 2 | org/6c1b5c24/75247aeb | viewer | ???* | failed_payment | 3 | org/5e02bab7/dd389a37 | admin | ???* | suspicious_activity
as it would allow independent subtractions and additions of permissions (as long as we have a proper hierarchy of affection and code the logic and resulting templates properly).
* We'd have to generate combinatory templates in the external system to do this, as there's no concept of exclusions or inclusions yet. But since the set of actions to exclude or include won't change frequently, this is okay for now.