Does Rails 4.2 use secret_token? - ruby-on-rails

Are both secret_key_base and secret_token needed for production in Rails 4.2? Setting neither causes the following exception message:
Missing secret_token and secret_key_base for 'production'
environment, set these values in config/secrets.yml
The 4.2 upgrade guide (http://railsapps.github.io/updating-rails.html) says this:
When you create a new Rails application using the rails new command, a
unique secret key is generated and written to the
config/initializers/secret_token.rb file.
But no such file was created when I generated my app, and there is no reference to secret_token in config/secrets.yml
I'm assuming that the error message is wrong, and that only secret_key_base is needed. When I run my app in production on my dev machine, it starts with just secret_key_base, but in Engineyard, setting secret_key_base (via an environment variable) isn't working. I still get the error.

The problem you're seeing on Engine Yard is because the secret_key_base environment variable doesn't (yet) exist by default. That's something we're working on. You can put that in place on your own using custom chef; I suggest talking to our support team for more info on that.
As for the actual error you're getting, I just tested a brand new Rails 4.2 app ("rails new foo") to see if it's generating secret_token.rb, which it's not. I think what you need here is to create config/secrets.yml, and that file should look like this:
development:
secret_key_base: somekey
test:
secret_key_base: someotherkey
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Now, when you see ENV["SECRET_KEY_BASE"], that's where Engine Yard has a bit of a twist - we don't provide that out of the box yet. As long as your repo is private, you can hard-code something in there on your own. Otherwise, using custom chef could get you squared away by creating a secret key base and putting it in the wrapper script responsible for launching your app worker processes (so config/env.custom on our platform, for example).
Hope this helps.

4.2 does use the secret key and the link you posted has the solution you are looking for.
In an environment that doesn't end up with the secret key active, you need to generate it using rake secret then place the output from the console into your config/initializers/secret_token.rb file (you can make one if there isn't one).
You have the option to avoid using secrets.yml. Many people prefer to use another gem/procedure (e.g. figaro) for handling secret info. To simplify your life you could just put this information into the secret_token.rb file and move on - or you can learn the various other idiomatic ways of handling the situation.

At least Rails 4.2.2 gave me the same error, but setting the environment variable SECRET_KEY_BASE in the rails user's .bash_profile file solved the problem for me, so the bit about secret_token seems to be bogus -- a holdover from earlier versions, probably.
Generate the secret by commanding rake secret, then use the generated string in file .bash_profile like this:
export SECRET_KEY_BASE='the_output_of_the_rake_secret_command'

I'd suggest re-generating a new app with the latest version of Rails installed.
This file was auto-generated in my last project:
# 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: fooooo
test:
secret_key_base: fooooo
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
I'd also recommend that you compare the generated files via the railsdiff site (example: http://railsdiff.org/4.1.10.rc2/4.2.1.rc2) as it sounds like you're upgrading from an older version.

Related

secret_key_base in Rails 6.0 best practices

In Previous rails versions, the secrets file wasn't encrypted. So the best practice was to read, e.g. secret_key_base, from the environment.
This makes sense and it was pretty simple:
# config/secrets.yml
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
The Secrets served then as a simple logical directory for the keys.
in Rails 6.0 the file is encrypted and is not parsed, which means it must contain hard coded strings, i.e. the real secrets.
Is the best practice to have the value hardcoded and use the same key for all environments? This doesn't seem right.
When secure credentials where introduced in 5.2 you only had a single credentials file.
By popular demand Rails 6 will load a seperate config/credentials/*.yml.enc file - where * is the name of the environment if the file is present. This file takes complete precedence over config/credentials.yml.enc - the two are not merged.
You can edit the credentials for a specific environment by passing the environment option:
rails credentials:edit --environment development
See:
Rails PR #335219

Separate secret_key_base in Rails 5.2?

I just upgraded from 5.1 to 5.2 and I'm quite confused about this 'better' methodology to storing secrets...
Maybe I'm not understanding, but it seems like now development and production have been 'merged' into a SINGLE SECRET_KEY_BASE as well as master.key... is this correct?
If not, how do I use a separate master key and SECRET_KEY_BASE in development?
What if I have developers helping me and I don't want them to know my master key (or secrets) I use in production?
Rails 5.2 changed this quite a bit. For development and test enivoronments, the secret_key_base is generated automatically, so you can just remove it from secrets.yml or wherever you have it set.
As for production, there is the credentials file which you can generate and edit it by running rails credentials:edit. This will also create the master key in config/master.key which is only used for encrypting and decrypting this file. Add this to gitignore so it's not shared with anyone else, which should take care of sharing it with fellow devs.
If all of this sounds a bit tedious, and it is, you can just ignore it and provide the secret_key_base in ENV. Rails will check if it's present in ENV["SECRET_KEY_BASE"] before it complains.
There are two ways to access secret_key_base:
Rails.application.credentials.secret_key_base
Rails.application.secrets.secret_key_base
Rails 5 took the first way by default.
you can change Rails.application.credentials.secret_key_base by rails credentials:edit. for all other environments, remember to set environment variable RAILS_MASTER_KEY to be the same content of config/master.key. the master.key is git ignored by default. this way uses the same secret key for all environments. if you want to use different keys, you need to control namespaces by yourself.
If you prefer the second way Rails.application.secrets.secret_key_base. you need to create config/secrets.yml:
development:
secret_key_base: ...
test:
secret_key_base: ...
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
remember to set environment variable SECRET_KEY_BASE on production.
if config/secrets.yml file is secret enough, changing <%= ENV["SECRET_KEY_BASE"] %> to plain text is fine.
rake secret can generate a random secret key for you.
I prefer the second way(old way), because of simple.
I used this gem when I didn't want to share the production master.key with my friend developers which I think is the exact same purpose as the OP.
https://github.com/sinsoku/rails-env-credentials
You can have a master key for each evironment as below, so you can have a discretion as to which key you want to share with which developers/deployers.
config/credentials-development.yml.enc
config/credentials-test.yml.enc
config/credentials.yml.enc
master-development.key
master-test.key
master.key
Each key will be generated when you first run something like:
rails env_credentials:edit -e development
If you switch from one master.key setup to this, one error you might encounter will be related to config/database.yml in which Rails tries to evaluate all environment information no matter which environment you are on.
(Even if you comment them out, Rails still tries to evaluate the erb parts.)

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

Rails 4.0.5 secret.yml configuration

So I'm trying to get my first ruby on rails app running and after running "rails s" for the first time, I get the following message when I navigate to localhost:3000:
Internal Server Error
You must set config.secret_key_base in your app's config.
I did some research and it looks like I need to configure my secrets.yml file but am unsure what it should look like. This is what my secrets.yml file looks like:
# 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: fe3ffe8d0308f92a4765f3ea02264cd24f1ddc9dd5a64aa601c61402c85e2de4d5fb74df8d66ef6d2a43dee34584dce87a51f83050d4d1d57320b5e846a6a8aa
test:
secret_key_base: fe3ffe8d0308f92a4765f3ea02264cd24f1ddc9dd5a64aa601c61402c85e2de4d5fb74df8d66ef6d2a43dee34584dce87a51f83050d4d1d57320b5e846a6a8aa
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
the development and test secret_key_base come from the key that's generated when I run "rake secret".
What am I supposed to put in the production secret_key_base (that's what I speculate is wrong)?
Edit: What is my config/initializers/secret_token.rb file supposed to look like? This is what I have for that:
Demoapp::Application.config.secret_key_base = fe3ffe8d0308f92a4765f3ea02264cd24f1ddc9dd5a64aa601c61402c85e2de4d5fb74df8d66ef6d2a43dee34584dce87a51f83050d4d1d57320b5e846a6a8aa
SOLUTION: I had forgotten to put the generated key in quotes inside my config/initializers/secret_token.rb file. config/initializers/secret_token.rb now looks like this and works fine:
Demoapp::Application.config.secret_key_base = 'fe3ffe8d0308f92a4765f3ea02264cd24f1ddc9dd5a64aa601c61402c85e2de4d5fb74df8d66ef6d2a43dee34584dce87a51f83050d4d1d57320b5e846a6a8aa'
You're supposed to add an environment variable SECRET_KEY_BASE with value from a new rake secret command on the server that hosts this production environment. In secrets.yml, the production secret_key_base is assigned the value of this environment variable SECRET_KEY_BASE.
Please see Environment variable for information on the subject across different platforms.
Setting the environment variable satisfies the requirement, and you need not modify the secrets.yml file.

AWS::S3::Errors::InvalidAccessKeyId

So, I'm running rake db:drop db:create db:migrate db:seed and for some reason I'm getting the following error:
AWS::S3::Errors::InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.
Bare in mind, most of the migrations run however, I seem to be getting the error directly after this migration:
20140606122523 CreateActiveAdminComments: migrated (0.8930s) ===============
I have all of the updated keys in the appropriate files as follows:
config/aws.yml:
defaults: &defaults
access_key_id: '*key here*'
secret_access_key: '*key here*'
bucket_name: '*bucket name*'
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults
initializers/aws.rb
AWS.config(YAML.load_file(Rails.root.join("config/aws.yml"))[Rails.env])
What am I doing wrong? I've double and triple checked the keys, and have even tried generating new ones.. Still getting the same error.
Please help!
Migration
After a discussion in the comments, the issue was that the migration referenced Paperclip, which used S3 settings. To fix the migration, the OP had to remove the Paperclip S3 settings from the config/application.rb, allowing the migration to proceed.
--
ENV Vars
The ENV vars are slightly different
It's strange how you'd try and set them in the application.rb - by their nature, environment (ENV) variables are meant to reside in the OS - making them accessible by your app & other parts of the system. It's just another security feature to help keep data both secure & modular
The problem you have is setting ENV vars in development is about putting the variables on the machine, and it's also the case that Rake won't load them unless they are available at OS-level
The solution you need is two-fold:
--
secrets.yml
Rails 4.1.0 introduced secrets.yml to help fix this:
Rails 4.1 generates a new secrets.yml file in the config folder. By
default, this file contains the application's secret_key_base, but it
could also be used to store other secrets such as access keys for
external APIs.
#config/secrets.yml
If you upgrade to Rails 4.1, you'll get a `secrets.yml` file which will look like this:
# 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: [a salt]
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
You'll be able to put your API keys in there, and then reference using Rails.application.secrets.some_api_key
--
figaro
An alternative, which is just as effective, is to use the figaro gem. This is kind of redundant with secrets.yml but anyway, it creates an application.yml which you can then reference using the direct ENV["setting"] var
Either way should solve your issue!

Resources