-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Rails: Default to "sandbox" mode when accessing production-like environments #747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…onments In an effort to avoid mutating production data, we recommend using "sandbox" mode when using `rails console`. If you need to [maniuplate data][data migrate], consider running a custom Rake task, or use [maintenance_tasks][]. [data migrate]: https://guides.rubyonrails.org/active_record_migrations.html#data-migrations [maintenance_tasks]: https://github.com/Shopify/maintenance_tasks
Mixed on this. In my perfect world the console is always sandboxed and no one attempts to change or alter data. In a world in which I regularly live, stuff changes from the console. Being in sandbox mode and attempting to change records will lock the DB rows until the session is ended and the transaction is rolled back, which can cause problems and potentially crash. It also doesn't prevent side effect calls (changing job states in redis/ external api calls/ etc) made during the session. In a lot of applications, there just aren't the tools available to debug, change config, or run code at a specific enough level. Building those tools only usually happens on large teams which have non-technical admin who are taking responsibility for fixing those problems for their users. When those tools exist as one off scripts or rake tasks they tend to be forgotten about and then you either support code that isn't understood or "correct" over time or you run the risk of the rake task doing something slightly different than the core flow and causing a waterfall of problems. Both of those seem higher risk to me over a longer time than trusting a developer to do something with immediacy in a console session. So yeah, torn on the outcome here and not sure there's "generalizable" advice. I think maybe if you had to have console access because you didn't have the other tools for debug-ability (or things like deploying those tools takes way too long) I would push for an audit log tagged with the user, if that's possible. You could add an initializer with a custom logger and an ActiveSupport::Notification subscription for events that change the DB (and maybe custom ones for external side-effects or job enqueueing)? # config/initializers/console_audit.rb
if defined?(Rails::Console)
console_audit_logger = ActiveSupport::TaggedLogging.new(
Logger.new(Rails.root.join("log/console_audit.log"))
)
ActiveSupport::Notifications.subscribe(/^sql\.active_record$/) do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
if /\A(INSERT|UPDATE|DELETE)/i.match?(event.payload[:sql])
username = `whoami`.strip # am lazy, could make them say the user or give a token or something
console_audit_logger.tagged("CONSOLE_AUDIT", username) do
console_audit_logger.info(event.payload[:sql].gsub(/\s+/, " "))
end
end
end
# Write the notice out to the console
puts "Console audit logging enabled. All changes will be recorded in log/console_audit.log"
end But maybe the idea is that if you have sensitive enough data or don't have trust in your dev team, or it's just too many people, maybe don't allow console or ssh access at all? |
I know basecamp has some tools for this I've never used |
rails/README.md
Outdated
@@ -81,6 +81,12 @@ Guidance on ActiveRecord, ActiveModel, and other model objects. | |||
- Use `db/seeds.rb` for data that is required in all environments. | |||
- Use `dev:prime` rake task for development environment seed data. | |||
|
|||
## Console | |||
|
|||
- Access production-like [console][] sessions in "sandbox" mode: `bin/rails console --sandbox` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brian-penguin would it help if we changed the framing from "don't change data in production" to "exercise caution when using the rails console in production... you wouldn't wanna delete something on accident"?
- Access production-like [console][] sessions in "sandbox" mode: `bin/rails console --sandbox` | |
- Access production-like [console][] sessions in "sandbox" mode when possible: `bin/rails console --sandbox` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spirit of this guidance is to highlight that this is even an option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the spirit of this, but I share the same thoughts as @brian-penguin. But I do think just pointing towards better approaches is a nice way to do this here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about the changes proposed in 4e4e6bd?
This way, you need to explicitly pass --no-sandbox
when entering the Rails console.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, interesting. I'm a fan of that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's a better default!
850c399
to
4e4e6bd
Compare
In an effort to avoid accidental writing to the production database, we
recommend setting config.sandbox_by_default to
true
inproduction-like environments.