Pretender for Rails: Controlled User Impersonation
Log in as another user in Rails
At a glance
- What is it?
- Pretender gives Rails applications a small API for administrators to view the application as another user while retaining access to the administrator's identity. It supports configurable authentication roles, Action Cable, and audit integrations with limited application code.
- Who is it for?
- Adopt Pretender when an authenticated Rails administrator needs a documented, reversible way to inspect the application as a selected user, especially when current_user must change without losing the administrator identity. Do not choose it as a replacement for your authorization layer, permanent account switching, or identity-provider administration.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Star history
- ankane/pretender1,425 ★ · +0
| Repository | 2026-10-16 | 2026-10-23 |
|---|---|---|
| ankane/pretender | 1.4k | 1.4k |
0 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Pretender's Rails Impersonation Boundary
Pretender solves a specific administrative support problem: viewing a Rails application through the permissions and state of another user. The README frames this as letting an administrator see exactly what another user sees. That distinction matters because application behavior can depend on the authenticated record, authorized routes, rendered data, and connection-specific identity rather than on a query parameter or a special preview mode.
The gem is aimed at Rails applications with an administrative person who must inspect a user session without replacing the entire authentication flow. Its documented integrations mention Devise, Authlogic, and Sorcery, while also stating that Pretender works with any authentication system. That makes it more suitable as an identity switch layered over an existing authentication mechanism than as a full authentication library.
Pretender does not decide whether an administrator may impersonate a particular account. The sample controller explicitly applies `before_action :require_admin!`, described in the README as the application's authorization method. Pretender then accepts the selected user and changes the method used by the application. Access control remains the responsibility of the host application. This separation can produce a small implementation, but it also makes route protection an adoption requirement rather than an optional detail.
Inside Pretender's User State Swap
After an application declares `impersonates :user`, Pretender creates a default impersonation interface centered on three methods. Calling `impersonate_user(user)` changes what `current_user` returns. Calling `true_user` retrieves the real authenticated user, which remains available even while the selected user is active. Calling `stop_impersonating_user` ends the impersonation state.
The default configuration exposes that relationship through a lookup callable:
impersonates :user,
method: :current_user,
with: ->(id) { User.find_by(id: id) }This is more configurable than a hard-coded user switch. The example shows an alternative called `account`, with `authenticated_account` as the application method and `EnterpriseAccount.find_by(id: id)` as the lookup. According to the configuration documentation, declaring it creates `true_account`, `impersonate_account`, and `stop_impersonating_account`. The README also states that multiple roles can be impersonated at the same time.
The documentation does not specify the internal session key, serialization format, expiration policy, or persistence mechanism. Those details should not be inferred from the public API alone. What can be confirmed is the observable contract: an application-facing method changes identity, a corresponding true-identity method remains available, and a stop method reverses the state. Existing authentication can still perform the initial sign-in, after which Pretender controls the selected application identity.
Installing Pretender in a Rails Controller
The documented installation path is through the application's `Gemfile`. Pretender is a Ruby gem, and the README does not provide a manual installation command or version constraint.
gem "pretender"After adding that line, declare the role in `ApplicationController`. This gives the controller hierarchy access to the generated methods:
class ApplicationController < ActionController::Base
impersonates :user
endA first real use requires an administrator-only interface. The sample creates a controller with `require_admin!`, loads all users, starts impersonation from a member route, and exposes a collection route for stopping it:
class UsersController < ApplicationController
before_action :require_admin! # your authorization method
def index
@users = User.order(:id)
end
def impersonate
user = User.find(params[:id])
impersonate_user(user)
redirect_to root_path
end
def stop_impersonating
stop_impersonating_user
redirect_to root_path
end
endReplace the sample's authorization method and routes with application-specific equivalents. `require_admin!` is illustrative, not a method supplied by Pretender. The host application must define it and ensure both actions are protected.
Wiring Pretender Routes and an Impersonation Screen
The README defines the two controller operations through nested Rails routes. The member action receives a user identifier, while the collection action has no user parameter because it only stops the current impersonation:
resources :users, only: [:index] do
post :impersonate, on: :member
post :stop_impersonating, on: :collection
endA minimal index view can submit the corresponding forms. The `data: {turbo: false}` option is present in the documented view, so readers following that example retain the submitted non-Turbo behavior:
<ul>
<% @users.each do |user| %>
<li>Sign in as <%= button_to user.name, impersonate_user_path(user), data: {turbo: false} %></li>
<% end %>
</ul>The layout should make the impersonation visible. This is more than cosmetic: an administrator operating under another identity can otherwise lose track of whose permissions are active. The documented comparison is `current_user != true_user`.
<% if current_user != true_user %>
You (<%= true_user.name %>) are signed in as <%= current_user.name %>
<%= button_to "Back to admin", stop_impersonating_users_path, data: {turbo: false} %>
<% end %>The README does not document safeguards such as expiration, confirmation prompts, logging impersonation events, or preventing simultaneous impersonation in multiple browser sessions. Those behaviors must be verified in the host application if they are required.
Connecting Pretender to Action Cable
Pretender also covers WebSocket identity through Action Cable. The README instructs developers to declare both `:current_user` and `:true_user` as identifiers and to call `impersonates :user` inside `ApplicationCable::Connection`. Its example then sets `current_user` from the existing verified Devise session and rejects an unauthorized connection.
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user, :true_user
impersonates :user
def connect
self.current_user = find_verified_user
reject_unauthorized_connection unless current_user
end
private
def find_verified_user
env["warden"].user # for Devise
end
end
endThe README states that `current_user` then returns the impersonated user in channels. It does not explain whether an existing Action Cable connection picks up an impersonation state created later in an HTTP controller session. That timing question requires verification for any application whose administrator view depends on live channel behavior.
The sample also demonstrates that Pretender must be declared separately for the HTTP controller and the cable connection. An application that omits `impersonates :user` from `ApplicationCable::Connection` will not receive the documented channel integration.
Preserving the Real Identity for Audited
An impersonation system can become misleading when records attribute actions to the selected user even though an administrator initiated them. Pretender addresses this case for the `Audited` library. The README instructs applications to configure Audited's current user method as `true_user`:
Audited.current_user_method = :true_userThis creates an explicit division between authorization context and attribution context. Application behavior can use `current_user`, which points to the impersonated user, while the audit library reads `true_user`, which remains the actual authenticated person. The README's compatibility claim for auditing tools is specific rather than general, and the concrete example only names `Audited`.
The documentation does not state how Pretender behaves in background jobs, asynchronous callbacks, mailers, or external services that have no controller or Action Cable connection. It also does not show automatic audit records for starting or stopping impersonation. Applications that attribute events outside HTTP requests must inspect those code paths directly. The practical boundary is that `true_user` works only where the Pretender state and the configured method are actually available.
Pretender's Trade-offs and Maintenance Cost
Pretender's main advantage is its narrow surface. The README describes it as less than 100 lines and presents three central operations for each declared role. Configuration can rename the methods, choose a different model lookup, or impersonate several roles. For a Rails application whose existing authentication library supplies a stable user object, this is a direct way to add a reversible identity view.
The corresponding limitation is equally specific. Pretender does not document an administrative interface, expiration rules, session isolation, impersonation logs, or an authorization model. The sample manually protects the controller with `require_admin!`, which demonstrates that the gem expects the host application to decide who may enter the identity-switching flow. A direct custom controller that saves a selected ID in the session and swaps the current-user accessor follows a similar approach but requires maintaining session keys, lookup rules, cleanup, and stop behavior by hand. Pretender packages that common contract into a gem and adds true-user access and configuration for multiple roles.
The repository is not archived, and its last push was on 2026-04-02. However, it has no GitHub releases, so the release history and upgrade path are not documented through that channel. The README links to `CHANGELOG.md` for history. Its development commands are explicit:
git clone https://github.com/ankane/pretender.git
cd pretender
bundle install
bundle exec rake testThese commands cover cloning, dependency installation, and the repository's test task. The repository is licensed under MIT, as recorded in `LICENSE.txt`; that identifies the project's stated license, not an interpretation of obligations for a particular deployment.
Editorial conclusion
Adopt Pretender when an authenticated Rails administrator needs a documented, reversible way to inspect the application as a selected user, especially when current_user must change without losing the administrator identity. Do not choose it as a replacement for your authorization layer, permanent account switching, or identity-provider administration. Before adoption, verify that every protected controller action, background job, audit hook, and WebSocket connection consistently uses the intended Pretender methods, because the README documents controller and Action Cable integration but does not address background jobs or a complete security policy for impersonation routes.
Frequently asked questions
Which Rails authentication systems can work with Pretender?
The README says Pretender works with any authentication system and specifically names Devise, Authlogic, and Sorcery. Its Action Cable example retrieves the user through Devise's `warden` environment object.
How does Pretender retain access to the administrator's identity?
While `current_user` returns the selected impersonated user, `true_user` returns the actual authenticated user. The README recommends using `true_user` as the current user method for Audited audit attribution.
Does Pretender control whether an administrator may impersonate a user?
No such authorization policy is documented in Pretender. The sample controller uses the application's own `require_admin!` method before exposing the impersonation and stop actions.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ankane-pretender)Star history chart for your README
[](https://hysenlabs.com/projects/ankane-pretender)Was this useful?