0

Background

  • 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.

Problem

  • 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.

My Thoughts

  • 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 Alice do action GetUsersInDomain in IAM domain org/6c1b5c24/75247aeb?

and it will respond yes or no. But it cannot answer questions like,

Hey, who are all the users who can do GetUsersInDomain in IAM domain org/6c1b5c24/75247aeb?

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:

  • admin
  • viewer
  • contributor

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 |

Here, user, iam_domain, and 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.

  • Just to clarify, this system is using the DB as a source of truth for permissions? So it would look up a user and the corresponding IAM permissions, which it would then "merge" with the tags to get the final list of permissions? – Jesse Aug 20 at 14:44
  • Our system uses a DB, but it's not the source of truth. It mirrors the actual source of truth DB on the external system. Any time our system (or other systems in the ecosystem) need to check permissions, we hit the external source of truth. But for functionality like "getting all users with role X," we rely on our own DB. – Andrew Cheong Aug 20 at 15:34
  • Our system is the only one that actually writes / modifies those permissions. So we have the unique privilege of being able to store our "mirror" of permissions using whatever abstractions we like (e.g. roles, tags, etc.) as long as we boil it down to a "template" on the external system (again, just a list of actions). All actual verifications of permissions hit that external system directly; the template has all the info needed. – Andrew Cheong Aug 20 at 15:36

Your Answer

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

Browse other questions tagged or ask your own question.