Getting rid of the credentials "feature" in Rails - ruby-on-rails

I am under a lot of stress due to this feature that is simply not needed in my scenario. It causes a lot of hassle and errors. For example:
[mememe#app site]# rails db:migrate RAILS_ENV=production
rails aborted!
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit`
Then when trying to edit:
[mememe#app site]# EDITOR="mate --wait" bin/rails credentials:edit
Adding config/master.key to store the master encryption key: 7b3516f223e08c7eb04813154582be2b
Save this in a password manager your team can access.
If you lose the key, no one, including you, can access anything encrypted with it.
create config/master.key
Traceback (most recent call last):
38: from bin/rails:3:in `<main>'
37: from bin/rails:3:in `load'
36: from /app/site/bin/spring:15:in `<top (required)>'
...
1: from /usr/local/rvm/gems/ruby-2.5.5/gems/activesupport-5.2.3/lib/active_support/message_encryptor.rb:183:in `_decrypt'
/usr/local/rvm/gems/ruby-2.5.5/gems/activesupport-5.2.3/lib/active_support/message_encryptor.rb:206:in `rescue in _decrypt': ActiveSupport::MessageEncryptor::InvalidMessage (ActiveSupport::MessageEncryptor::InvalidMessage)
Then I tried to set it up in .env, and now I get:
[mememe#app site]# rails db:migrate RAILS_ENV=production
rails aborted!
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
/usr/local/rvm/gems/ruby-2.5.5/gems/activesupport-5.2.3/lib/active_support/message_encryptor.rb:206:in `rescue in _decrypt'
I also tried setting in production.rb:
config.require_master_key=false
I just want to migrate the db to production, I do not want all this :( can someone more experienced please tell me how to get rid of this "feature"?

secret_key_base is used for things like cookies signing and session encryption, if you're going to use these then you need it and need to keep it secret.
In rails 5 it can also be set via old-fashined config/secrets.yml (use rails secret to generate):
development: &defaults
secret_key_base: some_other_very_long_key_here
test:
<<: *defaults
production:
<<: *defaults
secret_key_base: <%= ENV["SECRET_KEY_BASE"] || 'some_very_long_key_here' %>
And previously you had to keep this file with production keys secret. With credentials - you only keep master key secret.
If you're sure that you do not need "secrets"/"credentials" - you can commit above file in your code and rails will not complain

Related

How do I give ENV['DATABASE_URL'] to Whenever gem in Fly.io Rails app?

I'm trying to use the Whenever gem in my Rails app to schedule some rake tasks.
I'm hosting the app on Fly.io, and the rakes are aborting because they can't connect to the Postgres database in the production environment.
I wondered if the credentials stored in the secrets were somehow wrong; to troubleshoot this, I deleted the database and set up a new one, and set the secrets (username, URL, password) which are meant to be accessible in the ENV['DATABASE_URL'] environment variable.
I understand that the ENV['DATABASE_URL'] takes precedence over the database.yml file when it's present. I've tried all sorts of configurations, currently I have this in my schedule.rb file:
`env :DATABASE_URL, ENV['DATABASE_URL']
set :environment, :production`
And this in my database.yml file:
production: <<: *default
But I still get the following errors in my cron.log file:
rake aborted! ActiveRecord::ConnectionNotEstablished: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: database "thomaskitson" does not exist /Users/thomaskitson/code/tkitson/newsguessr/rails-authentication/lib/tasks/newspaper.rake:17:in block (2 levels) in '
/Users/thomaskitson/.rbenv/versions/3.1.2/bin/bundle:25:in load' /Users/thomaskitson/.rbenv/versions/3.1.2/bin/bundle:25:in '
Caused by:
PG::ConnectionBad: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: database "thomaskitson" does not exist
/Users/thomaskitson/code/tkitson/newsguessr/rails-authentication/lib/tasks/newspaper.rake:17:in block (2 levels) in <main>' /Users/thomaskitson/.rbenv/versions/3.1.2/bin/bundle:25:in load'
/Users/thomaskitson/.rbenv/versions/3.1.2/bin/bundle:25:in <main>' Tasks: TOP => newspaper:new_images (See full trace by running task with --trace)
"thomaskitson" is not the name of the database, so I don't know why it's searching for one called that. There is an env variable called DATABASE_URL present in the fly secrets, so I believe that this is set up properly. Any help appreciated!
Thanks

Rails: During asset precompile throws error key must be 16 bytes

I am storing my secret key in environment and /config/environments/production.rb has config.require_master_key = true uncommented
config.require_master_key = true
When running
RAILS_ENV=production bundle exec rake assets:precompile
I get the error
/Users/something/Development/wwwroot/trivial/config/environment.rb:5:in `<main>'
/Users/something/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/Users/something/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
Caused by:
ArgumentError: key must be 16 bytes
/Users/something/Development/wwwroot/trivial/config/environment.rb:5:in `<main>'
/Users/something/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/Users/something/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
Tasks: TOP => environment
any ideas on how to fix this error? What else can I do?
Your problem is that the key you generated is longer of what rails expects https://github.com/rails/rails/issues/33528#issuecomment-412677795
Solution
You can recreate a new one by deleting your master.key and credentials.yml.enc and run
rails credentials:edit
I faced the same issue while setting up a Rails 6.0 application on Ubuntu in production.
I was using the figaro gem for my environment variables.
The issue was that I was copying the content of the secret_key_base instead of the master_key
Here's how I solved it
Delete the previous master.key and the credentials.yml.enc file
Recreate a new master.key and credentials.yml.enc:
rails credentials:edit
OR
EDITOR="code --wait" bin/rails credentials:edit # If you want to use VS Code as your editor
Copy the contents of the master.key, which is of this format:
34d3cc7c5305dde06865acfa473716cd
Replace my RAILS_MASTER_KEY value with the master_key in production:
RAILS_MASTER_KEY: "34d3cc7c5305dde06865acfa473716cd"
And then save it.
Note: You could also experience this issue if you set/specify a wrong RAILS_MASTER_KEY environment variable in your .env files (.env, .env.development, .env.test, .env.production). Say you just want to use it as a placeholder temporarily. This may also throw an error key=': key must be 16 bytes (ArgumentError) if you try to generate new master.key and the credentials.yml.enc files using rails credentials:edit or EDITOR="code --wait" bin/rails credentials:edit
What you have to do is to either provide the right RAILS_MASTER_KEY environment variable in the .env file(s) or comment out the RAILS_MASTER_KEY environment variable if you are not using it.
That's it.
I hope this helps
For me I had to ensure I remove the quotes around the key in my .env file.
It seems my server(AWS ECS Fargate) was counting the "" as part of the key. Locally it was all fine.
Before
RAILS_MASTER_KEY="12345"
After
RAILS_MASTER_KEY=12345
You can run this in your terminal
heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
You can follow the tutorial here

Rails 5.2 Encrypted credentials for production environment

I have created the new Rails app with the version of 5.2. Rails 5.2 introduced the encryption feature for the secrets.
I have configured the secret key in devise.rb file
config.secret_key = Rails.application.credentials[Rails.env.to_sym][:secret_key_base]
and also added the secret_key's for all environments using
EDITOR=vim rails credentials:edit
development:
secret_key_base: absdss
test:
secret_key_base: 123232
production:
secret_key_base: 123456
after the saving the credentials i can able to get the secret_key's in the rails console in local
Output in rails console:
Running via Spring preloader in process 44308
Loading development environment (Rails 5.2.0)
2.5.1 :001 > Rails.application.credentials.development[:secret_key_base]
=> "absdss"
The credentials are not working on production server, we are using CI/CD in gitlab for deployment stages, when i run the
rails db:create db:migrate
i am getting the following error
> rails db:create db:migrate
---> Running in 1563453ddf2a
rails aborted!
NoMethodError: undefined method `[]' for nil:NilClass
/usr/src/app/config/initializers/devise.rb:12:in `block in <main>'
/usr/local/bundle/gems/devise-4.4.3/lib/devise.rb:307:in `setup'
/usr/src/app/config/initializers/devise.rb:5:in `<main>'
/usr/local/bundle/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
Now the question is how to set the RAILS_MASTER_KEY to production server?
Im sharing few points which may help you
Encrypted credentials offer a few advantages over plaintext credentials or environment variables
Rails 5.1 introduced encrypted secrets
config/secrets.yml.key
config/secrets.yml.enc
Rails 5.2 replaces both secrets with encrypted credentials
config/credentials.yml.enc
config/master.key
config/master.key file is created while creating a rails project
Encryption key(master.key) is git ignored
In production
config/environments/production.rb
config.require_master_key = true
Can’t decrypt your credentials without the key
Managing the Key
a. scp or sftp the file
b. If you need to give a developer a copy of the key then You can use a password manager because they use encryption.
c. I used last pass for managing the master key file
The key used to encrypt credentials is different from the secret key base.
The key on master.key is used to encrypt and decrypt all credentials. It does not replace the secret key base.
The secret key base is required by Rails. If you want to generate a new secret key base run,
bin/rails secret
and add that to your credentials by running bin/rails credentials:edit.
You can put your master key as MASTER_KEY secret variable in Gitlab CI/CD Settings and then put
echo "$MASTER_KEY" > config/master.key
in before_script section of your .gitlab-ci.yml file.
Rails.application.credentials.development&.dig(:secret_key_base)
try this instead.

Rails 5.2 with master.key Digital Ocean deployment: ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage

I have migrated my Ruby on Rails application from Rails 5.1.2 to Rails 5.2.0 to use the encrypted secrets. Application is successfully deployed to Digital Ocean Ubuntu Server. But when I go in browser to access, it shows the following log.
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:206:in `rescue in _decrypt'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:184:in `_decrypt'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:157:in `decrypt_and_verify'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/messages/rotator.rb:21:in `decrypt_and_verify'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_file.rb:79:in `decrypt'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_file.rb:42:in `read'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:21:in `read'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:33:in `config'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:38:in `options'
/home/deploy/apps/GeekyCricket/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/core_ext/module/delegation.rb:271:in `method_missing'
(erb):12:in `<main>'
I have added encrypted secrets using rails credentials:edit, which creates config/credentials.yml.enc and master.key.
I also have added the master.key file on /app_name/shared/config/ on my ubuntu server, also placed an env variable RAILS_MASTER_KEY. But still getting this error, I don't know what I am missing here.
Solution A and B are different solutions. Just choose which is good for you.
a. Deploy from Continous Integration
1. Edit deploy.rb
set :default_env, {
"RAILS_ENV" => "production",
"RAILS_MASTER_KEY" => ENV["RAILS_MASTER_KEY"]
}
2. Add RAILS_MASTER_KEY as a variable
Travis CI
GitLab CI
b. Usage of master.key
1. Edit deploy.rb
append :linked_files, "config/master.key"
2. Upload master.key with :linked_files
Let's assume our application's root path is /home/deploy/awesome-project. All we need to do is upload the key file to /home/deploy/awesome-project/shared/config/master.key.
I faced the same problem, when deploying for the first time on my DigitalOcean Droplet, every time I ran RAILS_ENV=production cap production deploy:initial it failed complaining this error - ActiveSupport::MessageEncryptor::InvalidMessage
I tried below options which all failed -
removing master.key and credential.yml.enc file and then deploying again.
adding both files again and deploying.
Finally one solution worked, i just added master.key, removing credentials.yml.enc file, committed it and redeployed, and it worked without changing my deploy.rb file

How do I set secrets

Long story short, I decided to use VM for development in addition to my local machine.
So when I pulled my source code inside that VM and ran rspec I received following output:
action#rails:~/workspace(master)$ rspec
/home/action/.rvm/gems/ruby-2.0.0-p451/gems/devise-3.2.3/lib/devise/rails/routes.rb:481:in `raise_no_secret_key': Devise.secret_key was not set. Please add the following to your Devise initializer: (RuntimeError)
config.secret_key = '...'
I've added the key, but now I have following errors in specs:
2) Password pages user views his passwords
Failure/Error: sign_in user
RuntimeError:
Missing `secret_key_base` for 'test' environment, set this value in `config/secrets.yml`
# ./spec/support/login_macros.rb:3:in `sign_in'
# ./spec/features/account_pages_spec.rb:7:in `block (2 levels) in <top (required)>'
What should be inside that file?
I just installed rails 4.1 and created a new project. The following is the default generated content of config/secrets.yml:
# Be sure to restart your server when you modify this file.
# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.
# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.
development:
secret_key_base: 83aa0c7d6e2ed4574099514eb64bc3896fb8a71a344935fbd54705e0dd65adb897bc062fe477d03395a4d65675c833ba73ed340166be3874bfc01f43d6076385
test:
secret_key_base: 513fb7657945b56098db290394bf23f5e11463c473fb228719428a30fd34b8b899dff3f6173c32d7e6bc028dc3276f15dcba11b684d27983d8203fb5634ce8ae
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
You can generate a new key using rake secret then updating the value of config.secret_key.
$ rake secret
Use the output of the above command as the value for config.secret_key usually placed in config/initializers/devise.rb for devise. Restart rails server if you are using that as well.

Resources