Missing secret token, secret key base when running my application in production - ruby-on-rails

I work with Rails 4 and Ruby 2.1 and sorry but I am working on Windows
I have read a lot about this topic "Missing secret token, secret key base" but actually I do not understang anything.
I do not use Heroku, Git, Puma, Passenger or everything else I've read. I just thought I could instead of running rails s as usual run rails s -e production and see what is the version of my web application in production.
But I have the error "Missing secret_token and secret_key_base for production environment, set these values in config/secrets.yml"
I read about solutions using openSSL, export SECRET_KEY_BASE=<the long string> but I do understand the solutions.
I thought it was a problem related to the system of connection by password I settled thanks to Rails tutorial of Micheal Hartl. So disabled SSL connection. But nothing change.
This is my config/secrets.yml :
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Can someone explain how to concretely solve this issue ?

GDMN I am sorry that everyone gave you such poor explanations and instructions. Ok onto it then, shall we......
First everyone is right you no longer need "secret_token", you do however need "secret_key_base". What this does is it secures your visitors connection and keeps your system and app more secure. That is a simple explanation but all you need to worry about at the beginners level.
Second the ENV stands for "Environment Variable" they are used in all operating systems and they refer to variables on the OS level that hold information that you do not want to be accessible t someone trying to gain access to your site. For instance in Ruby On Rails if you HARD CODE the secrety_token_base string/hash then I hacker can gain access by using your security_token against you. I have seen this happen and it is not pretty, if the individual is skilled enough then they can gain access to even your root/admin account.
Now on to setting it all up. I only know the linux way and I know you are looking for the windows method but this should at least give you an understanding to seek out the information relevant to your operating system.
First thing you would need to do is generate your secret_token_base by running
bundle exec rake secret
To my knowlege this is the way you do it in all Operating Systems. After you run the above command the console will return a string and you would need to copy it. Once copied you would run the following command:
export SECRET_KEY_BASE=WhatYouJustCopied
Then we would check to make sure the Environment Variable SECRET_KEY_BASE is set by running:
env | grep -E "SECRET_TOKEN|SECRET_KEY_BASE"
If you do not have SECRET_TOKEN set you will only get the KEY_BASE.
If you want to learn more in depth information please visit this link it may be a little dated but most of it is still relevant and conceptually it is the same.
I wish you luck on your new found ROR Adventure! It is fun once you get the hang of it!

From your command prompt, run:
bundle exec rake secret
It will generate a long string of characters. Copy this string and paste it into config/secrets.yml as follows:
production:
secret_key_base: <paste the string here>
Note: only do this if you are not using a public repository. This key should not be accessible to anyone else. An alternate, and more secure way of doing this is using an environment variable. See this: http://daniel.fone.net.nz/blog/2013/05/20/a-better-way-to-manage-the-rails-secret-token/

So, if you look inside the secrets.yml file, you will see where your secret_key_base is set for each of your environments. When you look at the production setting, it wants an env variable to initialize your secret_key_base. Normally, in production, you would want your app server to fetch the value from a general place in case you need to spin multiple servers up, you wouldn't have to hard-code your secret_key_base everywhere since that is not a secure way of setting that variable.
Basically, you will have to have that env variable set up on the machine that will run your rails app in production. There are so many different ways to set this.
What I have set up to initialize my ENV variables for production is have a separate yml file that is constructed like this
# config/env_provider.yml
production:
SECRET_KEY_BASE: "KEY GOES HERE"
other_production_variables: #...etc
Then my separate servers will be told where to find this file before initializing the variables (This is not checked into version control). After the file is in place it will know to initialize the variables from the following code in environment.rb before your app initializes
#config/environment.rb
YAML.load_file("#{::Rails.root}/config/env_provider.yml")[::Rails.env].each {|k,v| ENV[k] = v }
# This is before Rails.application.initialize!
The thing with this set up is to make sure that you do not have this file accessible to everyone to see, only allow your application servers to use it. Anyway, this is how I deal with ENV variables and deploy them to production. I hope this helps you.

Related

Why are rails development credentials gitignored by default?

I'm generating credentials using the following command:
rails credentials:edit --environment development
I notice that rails puts this in the gitignore:
+/config/credentials/development.key
I dont understand why, based on the following reasons:
The development credential file is encrypted by default, hence harmless to check in as long as the master key isnt checked in.
It's essential for a fresh environment setup (eg. on a new dev environment)
If the original file is lost, all the data in the dev environment will have to be reseeded.
I'm inclined to check it in but figured, given Chesterton's fence and all, I'm likely missing something.
I figured it out. I was confused between the development.key and the config/credentials/development.yml.enc. The latter is the encrypted credential file.

Rails Production - How to set Secret Key Base?

So I am trying to get my rails app to deploy in production mode, but I get the error: Missing secret_token and secret_key_base for 'production' environment, set these values in config/secrets.yml
My secrets.yml file is as expected:
development:
secret_key_base: xxxxxxx
test:
secret_key_base: xxxxxxx
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
But even after google and research, I have no idea what to do with the production secret key base. Most of the info out there assumes I have certain background knowledge, but the reality is that I'm a noob.
Can anyone explain to me how to set my secret key and get this to work in production mode?
You can generate the key by using following commands
$ irb
>> require 'securerandom'
=> true
>> SecureRandom.hex(64)
=> "3fe397575565365108556c3e5549f139e8078a8ec8fd2675a83de96289b30550a266ac04488d7086322efbe573738e7b3ae005b2e3d9afd718aa337fa5e329cf"
>> exit
The errors you are getting just indicate that the environment variable for secret_key_base are not properly set on the server.
You can use various scripts like capistrano that automate the process of setting these before the application is run.
As for a quick fix try this:
export SECRET_KEY_BASE=YOUR SECRET BASE
Validate the environment variables and check if these have been set.
Command:
env | grep -E "SECRET_TOKEN|SECRET_KEY_BASE"
If your values pop up then these are set on the production server.
Also it is best practice to use ENV.fetch(SECRET_KEY) as this will raise an exception before the app even tries to start.
This answer helped me a lot. He indicates you how to config the secrets.yml file in production and how to read it from the environment:
original link:
https://stackoverflow.com/a/26172408/4962760
I had the same problem and I solved it by creating an environment
variable to be loaded every time that I logged in to the production
server and made a mini guide of the steps to configure it:
https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
I was using Rails 4.1 with Unicorn v4.8.2, when I tried to deploy my
app 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 this steps to create an environment variable for Linux (in my
case Ubuntu) in your production server:
1.- In the terminal of your production server execute the next command:
$ RAILS_ENV=production rake secret This returns a large string with
letters and numbers, copy that (we will refer to that code as
GENERATED_CODE).
2.1- Login as root user to your server, find this file and edit it: $ vi /etc/profile
Go to the bottom of the file ("SHIFT + G" for capital G in VI)
Write your environment variable with the GENERATED_CODE (Press "i" key
to write 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 (we push "ESC" key and then write ":x" and "ENTER" key for save
and exit in VI)
2.2 But if you login as normal user, lets call it example_user for this gist, you will need to find one of this other files:
$ vi ~/.bash_profile $ vi ~/.bash_login $ vi ~/.profile These files
are in order of importance, that means that if you have the first
file, then you wouldn't need to write in the others. So if you found
this 2 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 ("SHIFT + G" for capital G in VI)
And we will write our environment variable with our GENERATED_CODE
(Press "i" key to write in VI), be sure to be in 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 (we push "ESC" key and then write ":x"
and "ENTER" key for save and exit in VI)
3.- 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 app with Unicorn or other.
When you close your shell terminal and login again to the production
server you will have this environment variable set and ready to use
it.
And thats it!! I hope this mini guide help you to 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!
nowadays (rails 6) rails generate a secret key base in tmp/development_secret.txt for you.
and in production environment the best is having SECRET_KEY_BASE as en env variable, it will get picked up by rails.
you can check with Rails.application.secret_key_base.
should give you a long string of numbers and characters from 'a' to 'f' (a 128 chars long hexadecimal encoded string)
As you can see, there is a hardcoded value for the development and test environments, but the one for production comes from a variable. First of all, why this way? It is a security feature. This way, if you check this file into version control such as git or svn, the development and test values get shared, which is fine, but the production one (the one that would be used on a real website) isn't, so no one can look at the source to get that secret.
As for the variable used, ENV["SECRET_KEY_BASE"], this is an environment variable from the environment Rails is run in (not to be confused with the Rails "environment", such as development, test, and production). These environment variables come from the shell. As mentioned in JensD's post, you can set this environment variable temporarily with:
export SECRET_TOKEN=YOUR SECRET TOKEN
export SECRET_KEY_TOKEN=YOUR SECRET BASE
To generate a new secret token, use the rake secret command in the command line.
That is temporary, however, and not a good final solution. For a final solution, check out this article which has a quick bit near the end on implementing dotenv to load configuration secrets. Remember, if you use version control, be sure to exclude your .env file from being checked in!
Setting dotenv up takes a little bit of work, but I highly recommend it over trying to manually configure these environment variables.

controller can not read env variables on the server

I used Capistrano 3 to deploy my Rails 4 app to amazon ec2.
Unfortunately, my app on ec2 can not read environment variables.
I've added my variables to ~/.bashrc, /etc/environment and tried
# config/deploy/staging.rb
set :default_env, {
...
}
I can get my variables via $echo $my_var on command line interface and ENV['my_var'] on rails console on my ec2 instance. However, whenever I head to pages that need to read environment variable, I got a http 500 error. According to the log, it seems that my controller can not read the env variable.
I've also rebooted my server and re-deployed many times, but there is no luck.
How can I make my server read the env variable properly?
by the way, I am using unicorn (4.8.3) and the capistrano-unicorn-nginx (~> 3.1.0).
Hopefully you've found a solution for this by now. I'll post a brief answer so maybe it benefits to others that google for this.
Because server environment varies so much from OS to OS, Capistrano wants to ignore it and isolate from it as much as possible. Here's a link with more info. Also, it is probably that capistrano does not load ~/.bashrc, more info here. These are likely the reasons why your app could not read the environment.
I'm not sure why updating the :default_env option was failing. But that's also not the best way to solve this because you'd have to place credentials in a file that is version controlled.
A good way to solve the secret credentials problem is by using either dotenv or rails_config gems. You'll likely prefer the dotenv gem because it works with env vars.
Rails 4.1+, has the built in secrets.yml "feature" which is also fine and will probably be the standard moving forward. I wrote the capistrano-secrets-yml plugin that works with this.

secrets.yml environment variable not working in Rails 4.1.4

I am in the process of deploying a Rails app.
I get errors missing secret_key_base in the nginx log file when I have secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> in the secrets.yml file.
I have generated the secret using rake secret in the console and placed in ~/.bashrc as
export SECRET_KEY_BASE="secret"
From the console I run echo $SECRET_KEY_BASE and copy secret to secrets.yml replacing <%= ENV["SECRET_KEY_BASE"] %> with secret.
Then everything works fine and the application runs fine in production environment.
I would rather not keep secret in secret.yml and I do not know how to correct this or what I am doing wrong.
Does anyone have any suggestions?
If you use passenger, add
passenger_set_cgi_param SECRET_KEY_BASE "yoursecret";
to your nginx configuration in the relevant section.
See this section in the passenger user guide.
In production ~/.bashrc might not be read - e.g., you run as a different user, nginx might not read ~/.bashrc before starting, etc. Lots of people run into this issue.
A common approach to this is to handle environment configuration like Rails handles database configuration. Create a config/something.yml file with settings for each environment, then read that yaml in a config/initializers/something.rb initializer and use the values for the specific environment. The rails_config and figaro gems automate this approach. I've often just done it without a gem, as it's not terribly difficult. The key, as with database.yml, is that you never want to check this into source control - use .gitignore with git.
If you want to stick with setting your secret key base using an environment variable, then how you do that depends on your production machine, and how you provision it and deploy your code. With Heroku, it's simple enough to just pop into the Heroku console and set it. For other situations, you could use something like Chef/Puppet/Ansible to set the environment variable for your server. Another approach would be to push that information using Capistrano.
You can put the secret base in /config/initializes/secret_token.rb:
SampleApp::Application.config.secret_key_base = 'Your_Base_here'
EDIT:
This is kind of discouraged in many cases, so edit your .env file and set your key base:
SECRET_KEY_BASE=Your_base_here
and put your secrets.yml back to:
<%= ENV["SECRET_KEY_BASE"] %>
You could alternatively use /config/initializes/secret_token.rb:
SampleApp::Application.config.secret_token = ENV['SECRET_TOKEN']
Which will give you the same result, being more secure.
If you are then planning on pushing this to Heroku:
heroku config:set SECRET_KEY_BASE=$SECRET_KEY_BASE

How do you manage secret keys and heroku with Ruby on Rails 4.1.0beta1?

With the release of the secrets.yml file, I removed my reliance on Figaro and moved all of my keys to secrets.yml and added that file to .gitignore.
But when I tried to push to Heroku, Heroku said they needed that file in my repo in order to deploy the website. which makes sense, but I don't want my keys in git if I can avoid it.
With Figaro, I would run a rake task to deploy the keys to heroku as env variables and keep application.yml in the .gitignore. Obviously, I can't do that any more. So how do I handle this?
Secrets isn't a full solution to the environment variables problem and it's not a direct replacement for something like Figaro. Think of Secrets as an extra interface you're now supposed to use between your app and the broader world of environment variables. That's why you're now supposed to call variables by using Rails.application.secrets.your_variable instead of ENV["your_variable"].
The secrets.yml file itself is that interface and it's not meant to contain actual secrets (it's not well named). You can see this because, even in the examples from the documentation, Secrets imports environment variables for any sensitive values (e.g. the SECRET_KEY_BASE value) and it's automatically checked into source control.
So rather than trying to hack Secrets into some sort of full-flow environment variable management solution, go with the flow:
Pull anything sensitive out of secrets.yml.
Check secrets.yml into source control like they default you to.
For all sensitive values, import them from normal environment variables into secrets ERB (e.g. some_var: <%= ENV["some_var"] %>)
Manage those ENV vars as you normally would, for instance using the Figaro gem.
Send the ENV vars up to Heroku as you normally would, for instance using the Figaro gem's rake task.
The point is, it doesn't matter how you manage your ENV vars -- whether it's manually, using Figaro, a .env file, whatever... secrets.yml is just an interface that translates these ENV vars into your Rails app.
Though it adds an extra step of abstraction and some additional work, there are advantages to using this interface approach.
Whether you believe it's conceptually a good idea or not to use Secrets, it'll save you a LOT of headache to just go with the flow on this one.
PS. If you do choose to hack it, be careful with the heroku_secrets gem. As of this writing, it runs as a before_initialize in the startup sequence so your ENV vars will NOT be available to any config files in your config/environments/ directory (which is where you commonly would put them for things like Amazon S3 keys).
An equivalent for secrets.yml of that Figaro task is provided by the heroku_secrets gem, from https://github.com/alexpeattie/heroku_secrets:
gem 'heroku_secrets', github: 'alexpeattie/heroku_secrets'
This lets you run
rake heroku:secrets RAILS_ENV=production
to make the contents of secrets.yml available to heroku as environment variables.
see this link for heroku settings
if u want to run on local use like this
KEY=xyz OTHER_KEY=123 rails s

Resources