0.0
The project is in a healthy, maintained state
A safe, browser-based Rails console you mount on your app.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

Rails Console

Tests RuboCop Gem Version Maintainability Coverage Sponsor

A safe, browser-based Rails console you mount on your app.

Installation

gem 'rails-console'
bundle install
bin/rails generate rails_console:install
bin/rails db:migrate

Mounting

Mount the engine behind your own authentication and authorization:

# config/routes.rb
authenticate :user, ->(user) { user.devops? } do
  mount RailsConsole::Engine, at: :console
end

The route constraint protects the HTML page. The gem's authorize config (below) also protects the ActionCable channel — required because /cable is outside the mount.

Configuration

Created by bin/rails generate rails_console:install. Example:

# config/initializers/rails_console.rb
RailsConsole.configure do |config|
  config.audit = true

  config.authorize = ->(user) { user&.devops? }

  config.command = 'bundle exec rails console'

  config.current_user = ->(user) { { id: user&.id, label: user.try(:email) || 'unknown' } }

  config.idle_timeout = 10.minutes
  config.sandbox_command = 'bundle exec rails console --sandbox'
end

authorize and current_user receive the resolved user from HTTP (request) and WebSocket (connection) contexts.

Option Purpose
audit Persist sessions and I/O log lines (default: true)
authorize Proc (user) -> bool — may the user use the console (HTTP and WebSocket)
command Command after unsafe!
current_user Proc (user) -> { id:, label: } for audit records
idle_timeout Kill idle PTY sessions after this duration
sandbox_command Default command (safe-by-default sandbox)
socket_path Unix socket between Puma workers and the broker (default: tmp/sockets/rails_console.sock)
user_class ActiveRecord model class name for session user lookup (default: User)

Security layers

  1. Route constraintauthenticate / custom constraint on the mount (HTTP only).
  2. Controllerauthorize runs again before rendering the page.
  3. Channelauthorize on subscribed is the only protection for /cable; the mount does not cover WebSockets.

Additional safeguards:

  • Sandbox by default — sessions start with rails console --sandbox.
  • unsafe! / safe! — explicit toggle between write and sandbox mode; each swap starts a fresh PTY and is audited.
  • Broker isolation — one PTY per container, shared via Unix socket across Puma workers.
  • Audit trailRailsConsole::Session and RailsConsole::LogLine when audit is enabled.

Do not rely on command filtering inside Ruby; use authorization + sandbox + auditing.

Usage

Open /console (the path you mounted the engine at) to get a real rails console in the browser.

Sessions start in safe mode — changes are rolled back and never persisted:

User.last.destroy # runs, but nothing is saved

Type unsafe! to switch to write mode, where changes persist:

unsafe!
User.last.destroy # now really deletes the record

Type safe! to go back to sandbox mode. Each toggle starts a fresh session and is recorded in the audit trail.

Broker process

The broker boots on demand when someone opens /console, or run it manually:

bundle exec rails_console

Development (gem)

npm install
bundle exec rake assets:build # rebuild xterm bundle into app/assets/rails_console/
bundle exec rake spec