A Pragmatic Comparison of User Impersonation and RBAC

Apr 11, 2025

The ability for a service to operate beyond its authorized controls, effectively performing actions as the user, forms the core of programmatic user impersonation. User impersonation, or just impersonation, is a powerful tool that can be a convenient solution and a complex troublemaker. Let’s try and visualize this:

Maisie and Max are working on a project that requires them to send a PDF back-and-forth to each other. Maisie completes her part and sends it to Max. Max completes his and sends it back. Uh oh! Max made a mistake and needs to get the document back. How can this be done without giving too much control to Maisie or Max? Impersonation. The file service can impersonate Maisie, send the file back to Max, and log it as returned. Impersonation can also be Max requesting a batch of files to be sent and the service performing the individual actions on Max’s behalf.

Maisie and Max continue working, as well as your potential thousands of users. After millions of real and impersonated file sends, how do we distinguish between these actions?

In your own service, providing a basic log such as “job X returned file on behalf of Max” might suffice. However, any resulting actions that aren’t owned by you will interpret these impersonations as real user actions. For example, if my service is using the Dropbox API and I impersonate Maisie, Dropbox will interpret this request as actually coming from Maisie. This is a problem because all of Dropbox’s audit logs will be invalid from the perspective of your user. A convenient solution suddenly results in downstream mistakes. When considering impersonation in your designs, think about the impact it could have on your service and its dependencies’ audit logs.

So how does this impersonation work under the hood, especially concerning credentials? This form of impersonation is always a service that replicates a user’s action by utilizing that user’s data access token (DAT). This impersonation token can have a time to live (TTL) that varies depending on the service’s needs. Typically, you would limit the TTL of the DAT to a small value, like 5 minutes. Queued jobs might run into expiration issues, where you would need to explore longer TTLs. A long lived DAT might be a security concern within your team, so your impersonation job or action should operate within the time constraint of your user’s DAT. Whether your project is limited by a dependencies QPS ceiling and requires a queue, or security concerns don’t allow you to maintain user credentials, there are alternatives, such as a role-based access control (RBAC) system.

RBAC is a security approach used to restrict system access for authorized users based on their roles within an organization. The role your service would take on would be similar to a super user with access to move all files freely. A dependency might require the user to allow increased permissions for this service, but it would avoid confusion on who is performing the move operations. Job X would still be performing actions on behalf of Max, but now the dependency knows that too. It simplifies the potential issues that could arise from your product’s audit logs. However, this shouldn’t take away from the security concerns that an RBAC system introduces. Assigning a service super user access to all of your users’ files is a major risk, and should be limited or avoided all together. From my experience, limiting the data that the service can access is a possible solution to this problem. This might be in the form of creating labels to categorize data, and then specifying permissions based on these labels. In a sense, creating new, non-super user roles.

Navigating the choice between user impersonation and RBAC often comes down to which set of problems you’d rather solve. Impersonation’s downstream audit ambiguity and token lifecycle management can be complex, while RBAC’s potential for overly broad permissions presents serious security hurdles, often necessitating the kind of granular role definition discussed from my own experience. Both paths require careful implementation. Before committing, thoroughly analyze the impact on your audit logs, your dependencies, and your overall security architecture to determine which approach — or perhaps a carefully architected hybrid — best aligns with your project’s specific constraints and priorities.