I'm am working as a part of a team for a school project. We are using Ruby 2.6.5 and Rails 6.0.2.1. I have pulled the master branch from GitHub, but when I try to run the application I get this error:
ArgumentError: Missing secret_key_base for 'production' environment
I have looked online and found that the old solution was to change the config/secrets.yml file, but rails 6 no longer has that file, and instead has an encoded credentials.yml.enc file that has the same functionality. How do I fix this issue?
Rails > 5.2 introduced a new feature for securing credentials. For this rails uses a master.key in config folder which is usually added to .gitignore so that it stays secure and doesn't get pushed to git.
This master.key is used to encrypt or decrypt content from the credentials.yml.enc file which you found.
If you are working on a team then the project creator will have to share this master.key file to you personally or you have to create a new credentials.yml.enc. You can do it using the below command -
EDITOR=vim rails credentials:edit
This will create a new master.key and credentials.yml.enc in your machine but the changes made by your teammates in the credentials.yml.enc will be lost. To avoid that hassle just get the master.key from your teammate and put it in the config. folder.
You can try changing the config.require_master_key = true #in config/environments/production.rb
You can go to this link to check this in detail:- https://blog.engineyard.com/rails-encrypted-credentials-on-rails-5.2
I hope this will work for you.
I updated my Rails app from 5.1.6 to 5.2.1 and we were using secrets before. We'd like to switch to credentials since it was supposed to replace secrets. There are a couple of things I'm wondering:
1) Is there a "Railsy" way to do this? I'm aware I can just edit the secrets and copy the contents over to the credentials but I'm not sure if that's the right way to do it since I couldn't find anything that talks about this. Also, I tried copy the encrypted content from secrets.yml.enc and paste it to credentials.yml.enc but that didn't work, ran into some issues with the encryption.
2) Related to the first point, am I supposed to still be able to use secrets in 5.2.1? I thought credentials was supposed to replace secrets so I was surprised I could still use secrets and all my tests are passing.
Thanks for any info or help on this!
Backup your config/secrets.yml. Scaffold a temporary vanilla Rails 5.2.1 project via rails new. Copy config/master.key and config/credentials.yml.enc from it to your existing Rails project. Edit these credentials e.g in Ubuntu via:
EDITOR="gedit --wait" bin/rails credentials:edit
Replace the secret_key_base (new flat format prefered, optional for all environments) from the old secrets.yml and / or paste whatever else you need as a secret into it and save it. Delete config/secrets.yml and the temporary Rails project. Access the secrets in your code e.g. via:
Rails.application.credentials.secret_key_base
Ensure that your upgraded Rails 5.1.6 project use the master key in config/environments/*.rb:
Rails.application.configure do
...
config.require_master_key = true
...
end
Restart the Rails server. Do'nt forget to .gitignore and .dockerignore the config/master.key!
I am trying to go to my localhost and I keep getting the following error in my browser:
You must set config.secret_key_base in your app's config
I have looked around and people say that you have to rake the secret key and then put it into config/initializers/secret_token.rb but I don't have a secret_token.rb file in my folder. I am running ruby version ruby 2.1.2p9 and rails version Rails 4.0.8 I am following the tutorial at railstutorial.org if that helps on 2.2
Run rake secret to generate a new token.
Now create a new file config/initializers/secret_token.rb and add the following:
MyApp::Application.config.secret_key_base = '<token>'
Replace <token> with the one you just generated and replace MyApp with the actual module name of your app. You can find the module name of your app at the top of config/environments/development.rb
Rails-5
In rails-5, create config/initializers/secret_token.rb
Add Rails.application.config.secret_key_base= 'secret_token'
where 'secret_token' = rake:secret
Restart the server
I created a Rails application, using Rails 4.1, from scratch and I am facing a strange problem that I am not able to solve.
Every time I try to deploy my application on Heroku I get an error 500:
Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`
The secret.yml file contains the following configuration:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
On Heroku I configured the "SECRET_KEY_BASE" environment variable with the result of the rake secret command. If I launch heroku config, I can see the variable with the correct name and value.
Why am I still getting this error?
I had the same problem and solved it by creating an environment variable to be loaded every time I logged in to the production server, and made a mini-guide of the steps to configure it:
I was using Rails 4.1 with Unicorn v4.8.2 and when I tried to deploy my application it didn't start properly and in the unicorn.log file I found this error message:
app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)
After some research I found out that Rails 4.1 changed the way to manage the secret_key, so if you read the secrets.yml file located at exampleRailsProject/config/secrets.yml you'll find something like this:
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
This means that Rails recommends you to use an environment variable for the secret_key_base in your production server. In order to solve this error you should follow these steps to create an environment variable for Linux (in my case Ubuntu) in your production server:
In the terminal of your production server execute:
$ RAILS_ENV=production rake secret
This returns a large string with letters and numbers. Copy that, which we will refer to that code as GENERATED_CODE.
Login to your server
If you login as the root user, find this file and edit it:
$ vi /etc/profile
Go to the bottom of the file using Shift+G (capital "G") in vi.
Write your environment variable with the GENERATED_CODE, pressing i to insert in vi. Be sure to be in a new line at the end of the file:
$ export SECRET_KEY_BASE=GENERATED_CODE
Save the changes and close the file using Esc and then ":x" and Enter for save and exit in vi.
But if you login as normal user, let's call it "example_user" for this gist, you will need to find one of these other files:
$ vi ~/.bash_profile
$ vi ~/.bash_login
$ vi ~/.profile
These files are in order of importance, which means that if you have the first file, then you wouldn't need to edit the others. If you found these two files in your directory ~/.bash_profile and ~/.profile you only will have to write in the first one ~/.bash_profile, because Linux will read only this one and the other will be ignored.
Then we go to the bottom of the file using Shift+G again and write the environment variable with our GENERATED_CODE using i again, and be sure add a new line at the end of the file:
$ export SECRET_KEY_BASE=GENERATED_CODE
Having written the code, save the changes and close the file using Esc again and ":x" and Enter to save and exit.
You can verify that our environment variable is properly set in Linux with this command:
$ printenv | grep SECRET_KEY_BASE
or with:
$ echo $SECRET_KEY_BASE
When you execute this command, if everything went ok, it will show you the GENERATED_CODE from before. Finally with all the configuration done you should be able to deploy without problems your Rails application with Unicorn or some other tool.
When you close your shell and login again to the production server you will have this environment variable set and ready to use it.
And that's it! I hope this mini-guide helps you solve this error.
Disclaimer: I'm not a Linux or Rails guru, so if you find something wrong or any error I will be glad to fix it.
I'm going to assume that you do not have your secrets.yml checked into source control (ie. it's in the .gitignore file). Even if this isn't your situation, it's what many other people viewing this question have done because they have their code exposed on Github and don't want their secret key floating around.
If it's not in source control, Heroku doesn't know about it. So Rails is looking for Rails.application.secrets.secret_key_base and it hasn't been set because Rails sets it by checking the secrets.yml file which doesn't exist. The simple workaround is to go into your config/environments/production.rb file and add the following line:
Rails.application.configure do
...
config.secret_key_base = ENV["SECRET_KEY_BASE"]
...
end
This tells your application to set the secret key using the environment variable instead of looking for it in secrets.yml. It would have saved me a lot of time to know this up front.
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.
I had this exact same issue and it just turned out that the boilerplate .gitignore Github created for my Rails application included config/secrets.yml.
This worked for me.
SSH into your production server and cd into your current directory, run bundle exec rake secret or rake secret, you will get a long string as an output, copy that string.
Now run sudo nano /etc/environment.
Paste at the bottom of the file
export SECRET_KEY_BASE=rake secret
ruby -e 'p ENV["SECRET_KEY_BASE"]'
Where rake secret is the string you just copied, paste that copied string in place of rake secret.
Restart the server and test by running echo $SECRET_KEY_BASE.
While you can use initializers like the other answers, the conventional Rails 4.1+ way is to use the config/secrets.yml. The reason for the Rails team to introduce this is beyond the scope of this answer but the TL;DR is that secret_token.rb conflates configuration and code as well as being a security risk since the token is checked into source control history and the only system that needs to know the production secret token is the production infrastructure.
You should add this file to .gitignore much like you wouldn't add config/database.yml to source control either.
Referencing Heroku's own code for setting up config/database.yml from DATABASE_URL in their Buildpack for Ruby, I ended up forking their repo and modified it to create config/secrets.yml from SECRETS_KEY_BASE environment variable.
Since this feature was introduced in Rails 4.1, I felt it was appropriate to edit ./lib/language_pack/rails41.rb and add this functionality.
The following is the snippet from the modified buildpack I created at my company:
class LanguagePack::Rails41 < LanguagePack::Rails4
# ...
def compile
instrument "rails41.compile" do
super
allow_git do
create_secrets_yml
end
end
end
# ...
# writes ERB based secrets.yml for Rails 4.1+
def create_secrets_yml
instrument 'ruby.create_secrets_yml' do
log("create_secrets_yml") do
return unless File.directory?("config")
topic("Writing config/secrets.yml to read from SECRET_KEY_BASE")
File.open("config/secrets.yml", "w") do |file|
file.puts <<-SECRETS_YML
<%
raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
%>
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
SECRETS_YML
end
end
end
end
# ...
end
You can of course extend this code to add other secrets (e.g. third party API keys, etc.) to be read off of your environment variable:
...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>
This way, you can access this secret in a very standard way:
Rails.application.secrets.third_party_api_key
Before redeploying your app, be sure to set your environment variable first:
Then add your modified buildpack (or you're more than welcome to link to mine) to your Heroku app (see Heroku's documentation) and redeploy your app.
The buildpack will automatically create your config/secrets.yml from your environment variable as part of the dyno build process every time you git push to Heroku.
EDIT: Heroku's own documentation suggests creating config/secrets.yml to read from the environment variable but this implies you should check this file into source control. In my case, this doesn't work well since I have hardcoded secrets for development and testing environments that I'd rather not check in.
You can export the secret keys to as environment variables on the ~/.bashrc or ~/.bash_profile of your server:
export SECRET_KEY_BASE = "YOUR_SECRET_KEY"
And then, you can source your .bashrc or .bash_profile:
source ~/.bashrc
source ~/.bash_profile
Never commit your secrets.yml
For rails6, I was facing the same problem as I was missing the following files. Once I added them the issue was resolved:
1. config/master.key
2. config/credentials.yml.enc
Make sure you have these files!
What I did :
On my production server, I create a config file (confthin.yml) for Thin (I'm using it) and add the following information :
environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction
I then launch the app with
thin start -C /whereeveristhefieonprod/configthin.yml
Work like a charm and then no need to have the secret key on version control
Hope it could help, but I'm sure the same thing could be done with Unicorn and others.
I have a patch that I've used in a Rails 4.1 app to let me continue using the legacy key generator (and hence backwards session compatibility with Rails 3), by allowing the secret_key_base to be blank.
Rails::Application.class_eval do
# the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
fail "I'm sorry, Dave, there's no :validate_secret_key_config!" unless instance_method(:validate_secret_key_config!)
def validate_secret_key_config! #:nodoc:
config.secret_token = secrets.secret_token
if config.secret_token.blank?
raise "Missing `secret_token` for '#{Rails.env}' environment, set this value in `config/secrets.yml`"
end
end
end
I've since reformatted the patch are submitted it to Rails as a Pull Request
I've created config/initializers/secret_key.rb file and I wrote only following line of code:
Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]
But I think that solution posted by #Erik Trautman is more elegant ;)
Edit:
Oh, and finally I found this advice on Heroku: https://devcenter.heroku.com/changelog-items/426 :)
Enjoy!
this is works good https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
for root user should edit
$ /etc/profile
but if you non root should put the generate code in the following
$ ~/.bash_profile
$ ~/.bash_login
$ ~/.profile
On Nginx/Passenger/Ruby (2.4)/Rails (5.1.1) nothing else worked except:
passenger_env_var in /etc/nginx/sites-available/default in the server block.
Source: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var
Demi Magus answer worked for me until Rails 5.
On Apache2/Passenger/Ruby (2.4)/Rails (5.1.6), I had to put
export SECRET_KEY_BASE=GENERATED_CODE
from Demi Magus answer in /etc/apache2/envvars, cause /etc/profile seems to be ignored.
Source: https://www.phusionpassenger.com/library/indepth/environment_variables.html#apache
In my case, the problem was that config/master.key was not in version control, and I had created the project on a different computer.
The default .gitignore that Rails creates excludes this file. Since it's impossible to deploy without having this file, it needs to be in version control, in order to be able to deploy from any team member's computer.
Solution: remove the config/master.key line from .gitignore, commit the file from the computer where the project was created, and now you can git pull on the other computer and deploy from it.
People are saying not to commit some of these files to version control, without offering an alternative solution. As long as you're not working on an open source project, I see no reason not to commit everything that's required to run the project, including credentials.
I had the same problem after I used the .gitignore file from https://github.com/github/gitignore/blob/master/Rails.gitignore
Everything worked out fine after I commented the following lines in the .gitignore file.
config/initializers/secret_token.rb
config/secrets.yml
I receive this warning when running my specs. Is there a best practice for generating a secret_key_base, or will any string suffice (with regard to security concerns)?
You propably upgraded to Rails 4 from a 3.x or a previous version.
First generate a random secret key value:
$ bundle exec rake secret
Then take that value and put it in config/initializers/secret_token.rb:
YourApp::Application.config.secret_key_base = 'your-secret'
replacing YourApp with the name of your application.
The reason for this is explained here.
Also see http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#config-secrets-yml
As of 4.1, you need to use the config/secrets.yml file. This is discussed in http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#config-secrets-yml .
You simply need to create a secret_token.rb file in the config/initializers directory.
Contents of the file below:
YourAppNameHere::Application.config.secret_key_base = #type the key you generated with rake secret here
then save the file
close your server:
ctrl c
restart it: rails s
You'll now see the basic rails app page you saw in the last chapter (If you're working through Hartl's tutorial)
If you are a total noob like me, remember to put the secret_key_base = 'whatever' inside single quotes. Just a copy and paste without quotes will throw an error :
C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activesupport-4.0.8/lib/act
ive_support/dependencies.rb:223:in `load': C:/Users/Jeff C/documents/rails_proje
cts/first_app/config/initializers/secret_token.rb:1: syntax error, unexpected tI
DENTIFIER, expecting $end (SyntaxError)
Had this same issue when working on a Rails 4 application that was upgraded to Rails 5.
All I had to do was run the command below to generate a secret key:
bundle exec rake secret
And then I added the secret key to the config/secret.yml file:
development:
secret_key_base: 21bc6137d0496a2a11f4459a7c7deb4f782d223d41ee328934b2fe7a405a42ec63eb3829db67f0ec6a759e134ba0bb15dc2d01168b64d83efcf8d42b403ac8bd
That's all.
I hope this helps