Rails 5.2 Encrypted credentials for production environment - ruby-on-rails

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.

Related

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

Running a rails server in production locally (InvalidMessage error)

I'm running Ruby 2.5.1 and Rails 5.2.0. I ran rails s -e production, and it gives this error:
/home/roy/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:206:in `rescue in_decrypt': ActiveSupport::MessageEncryptor::InvalidMessage
(ActiveSupport::MessageEncryptor::InvalidMessage)
How do I do this properly?
EDIT:
The same error appears whenever I try to edit the credentials file using
EDITOR="nano --wait" bin/rails credentials:edit
Also I realized that I didn't create a production database yet so I tried that using
RAILS_ENV=production bundle exec rails db:reset
(I know db:reset is a bit redundant but it should work trying to create, migrate and seed a server)
Sadly I get the same kind of error (InvalidMessage error)
Unsupported rails environment for compass
rake aborted!
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
/home/roy/apps/myappname/config/environment.rb:5:in `<main>'
/home/roy/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/home/roy/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
Caused by:
OpenSSL::Cipher::CipherError:
/home/roy/apps/myappname/config/environment.rb:5:in `<main>'
/home/roy/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/home/roy/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
Tasks: TOP => db:create => db:load_config => environment
Okay I got it working finally.
I simply deleted my master.key and credentials.yml.enc files and then ran
bin/rails credentials:edit
Which created new files. After that everything worked fine.
I don't really understand why it works though. Can anyone give a good explanation for this?
It appears your solution of removing the master.key and credentials.yml.enc indicates you are running Rails 5.2. This setup changed from a similar encrypted secrets.yml.enc file used in Rails 5.1.
The goal is to allow committing secret keys (AWS, Rails' secrect_key_base) to a project's code repository. These would typically be set with ENV variables. Now collaborators need only share the master.key that was generated to decrypt and modify or read the contents of credentials.yml.enc.
When you removed both the master.key and credentials.yml.enc files, rails generated a new pair, now you were able to decrypt credentials.yml.enc and this file was initialized with a new Rails secret_key_base value needed to avoid the ActiveSupport::MessageEncryptor::InvalidMessage. If you track down the source of that message, it's likely referencing the Rails credentials secret key base: Rails.application.credentials.secret_key_base.
These are nice write ups on the topic:
https://medium.com/cedarcode/rails-5-2-credentials-9b3324851336
https://www.engineyard.com/blog/rails-encrypted-credentials-on-rails-5.2
For Rails 6, I had a multi-environment credentials setup.
One for development, staging, and production.
The master.key works for the main credentials.yml file
The other environments have there own key, so for staging we used the production.key in place of the RAILS_MASTER_KEY config envs on heroku and that fixed it for me.
I had this similar issue when working with a Rails 5 application in production, royketelaar's answer and gib's answer
Just to add a few things:
After deleting the credentials.yml.enc and master.key files,
And running the command below to generate a new secret_key_base, credentials.yml.enc and master.key files (my editor is VS Code and not Nano):
EDITOR="code --wait" bin/rails credentials:edit
Ensure that uncomment the following configuration in your config/environments/production.rb file:
config.require_master_key = true
For your production environment, since the master.key file containing the master key which is used for decrypting the credentials.yml.enc is not recommended to be committed to version system control, save the master key in a RAILS_MASTER_KEY environment variable using the figaro gem.
That's all.
I hope this helps
You need to ask for the master key to you project leader / team leader / coworkers.
With that long key like 63y4gh47373h3733jj474 you copy it and paste it the master.key file under config folder.
That solve the issue.

Generating a new secrets.yml file

I'm trying to clone a rails repository from github, but it doesn't have a secrets.yml file. When I try to run the app from rails server, I get the error
Missing secret_key_base for 'development' environment, set this value in config/secrets.yml
I know what the structure of the file is supposed to look like, but is there a way for me to generate keys to use the development environment?
This rake task generate secret for you:
bundle exec rake secret
Generate a cryptographically secure secret key (this is typically
used to generate a secret for cookie sessions)
All rake tasks:
bundle exec rake -T
The secrets.yml file(note the indentation):
development:
secret_key_base: d140269c106b6d064cdd670a5aace0bbbb1400de545377a47836dbdab8104f2fdf0ab87e6b7982819d1bcc2ccf6a5f093985a0895970f01f30b0b15378a090e9
some_key: 338a3312d82
some_secret: f5d9c3214e7b
other_environment: development
other_password: password
production:
secret_key_base: d140269c106b6d064cdd670a5aace0bbbb1400de545377a47836dbdab8104f2fdf0ab87e6b7982819d1bcc2ccf6a5f093985a0895970f01f30b0b15378a090e9
some_key: 338a3312d82
some_secret: f5d9c3214e7b
other_environment: development
other_password: password
In Rails 5 you can simply type.
rails secret
This will generate a new key for you. Just copy the key and put it in your secrets.yml file
development:
secret_key_base: <Generated key>

Unable to set secret_key_base for the production environment in Ruby on Rails 4.1.4 application running on Heroku

I am unable to set secret_key_base for the production environment in Ruby on Rails 4.1.4 application running on Heroku.
Here are the steps that I've tried to do:
Run rake secret and copy the secret key to the clipboard
Run heroku config:set SECRET_KEY_BASE=%SECRET_KEY%
It returns success and Heroku lists this environment variable in the dashboard on the site, but the application still thinks that the secret key was not provided:
Missing secret_key_base for 'production' environment, set this value
in config/secrets.yml
Why? What am I doing wrong? How can I fix it?
Thanks in advance.
Add config/secrets.yml to version control and deploy again. You might need to remove a line from .gitignore so that you can commit the file.
.gitignore Github created for my Rails application included config/secrets.yml
OR
Follow this steps:
$ heroku config (run this command in your terminal)
Copy value from SECRET_KEY_BASE
paste value to secrets.yml file in place of <%= ENV["SECRET_KEY_BASE"] %> (without any quote)
e.g
production:
secret_key_base: b1de60dd9e00816d0569c5ce3f8dbaa3c8ea4a7606120dc66cXXXXXXXXXXXXXXXXXXXXXX
re-deploy
Note: Actually this is not safe but in-case you just wanted to run your app temporary in production mode for testing or in emergency condition
I hope it works for you...
What is in your config/secrets.yml? For production it should contain the lines:
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

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