26

Just pushed my first app to Heroku using Git and straight away got an Interanl Server Error.

You must set config.secret_key_base in your app's config.

This is because on my .gitignore file the following file is included:

config/initializers/secret_token.rb

I am using a standard template for my .gitignore file found here: https://github.com/github/gitignore/blob/master/Rails.gitignore

My Question: Should I set this key via Heroku directly for added security and if so how?

OR

should I just remove this line from my .gitignore file?

tommyd456
  • 10,443
  • 26
  • 89
  • 163
  • Do you have a value for `config.secret_key_base` in `config/initializers/secret_token.rb` (don't paste it here). – ScottJShea Sep 01 '13 at 09:33
  • thanks yes i do and I pushed this file (with the others) to Heroku – tommyd456 Sep 01 '13 at 09:37
  • You know it would have helped if I read your post better. Sorry – ScottJShea Sep 01 '13 at 09:39
  • Hang on a minute - I've just checked my .gitignore and the file is listed at the bottom so this will be the cause. But this leads me to asking - Should I be setting this key on Heroku directly rather than transferring the file? – tommyd456 Sep 01 '13 at 09:40
  • I got the template .gitignore from here by the way: https://github.com/github/gitignore/blob/master/Rails.gitignore – tommyd456 Sep 01 '13 at 09:41
  • I will edit the question – tommyd456 Sep 01 '13 at 09:42
  • You could try removing it from `.gitignore` but changing the line to read something like this: `SampleApp::Application.config.secret_key_base = ENV[secure_token]` and then set the secure token as an Heroku ENV variable – ScottJShea Sep 01 '13 at 09:46
  • would that then work on my local setup? – tommyd456 Sep 01 '13 at 09:47
  • You would need the ENV variable set locally too. Michael Hartl has some tips here that may also work for you: http://ruby.railstutorial.org/chapters/static-pages – ScottJShea Sep 01 '13 at 09:48

3 Answers3

32

In addition to setting the secret token as an ENV variable on Heroku, as outlined by Nick Ginanto, you also need the following to make this work.

Remove the config/initializers/secret_token.rb from .gitignore

Change the line in this file to:

MyApp::Application.config.secret_token = ENV['SECRET_TOKEN']

This will then pick up the secret token you have set with Heroku's config vars.

In order for the token to be picked up in your local environment you will need to add it. There are a number of options here but the one closest to Heroku is to use the foreman gem along with a .env file in your project root. The .env will need to have the secret_token

SECRET_TOKEN=NKUd7gisd7fueAISDfg....

You can use the rake secret command to generate tokens. Make sure your .env file is added to .gitignore.

With all this in place you will have different tokens for Heroku and local and your token will not be in your source control.

nmott
  • 9,454
  • 3
  • 45
  • 34
  • 1
    Thanks - I ended up using Figaro gem in the end. – tommyd456 Sep 02 '13 at 18:59
  • 1
    Nice one. Figaro is a great option for setting all this up. Just be aware that there may be some config vars which may be required before Figaro loads them (eg if you use unicorn.rb) in that case you can still use .env for those items alongside Figaro. – nmott Sep 02 '13 at 22:47
  • 2
    For reference here's the link for heroku config vars: https://devcenter.heroku.com/articles/config-vars – Jason Axelson Sep 13 '13 at 18:12
  • Also you want to run `foreman run rails server` after creating the .env file – Jason Axelson Sep 13 '13 at 18:14
10

Set it as a Heroku environment variable, & provide a fallback for development

Remove the hardcoded secret, check the secret initialiser into version control, set an environment variable on Heroku, and provide a fallback for development and stage.

1. Remove the hardcoded secret, and optionally provide a fallback:

Edit your config/initializers/secure_random.rb to remove the hardcoded secret for production. Optionally include a fallback for non-production environments if you'd rather not change the way you start your server.

secret = Rails.env.production? ? ENV['SECRET_TOKEN'] : "top_secret_token"
YourApp::Application.config.secret_key_base = secret

2. Check config/initializers/secure_random.rb into git

Edit .gitignore and remove the line:

config/initializers/secret_token.rb

Now commit the file.

3. Set the secret key for Heroku

Run:

rake secret

to generate a random alphanumeric string. I like to make doubly sure by mixing the key up a little by hand as well, just in case a future weakness is discovered in the key generation algorithm, as happened for Debian not so long ago. Probably this is unnecessary.

Next run:

heroku config:set SECRET_TOKEN=paste_random_string_here

to set the secret as a Heroku environment variable. Deploy to Heroku and you're done.

superluminary
  • 47,086
  • 25
  • 151
  • 148
6

Its best to use an ENV variable for this..

This way you can invalidate all the cookies quickly if needed, have a separate secret per environment and no need to deal with the file in a special way

heroku config:set SECRET_TOKEN=ertbs45tnsb3aw5bsxdrt54...

if you duplicated the app or have another app setup in heroku, each app will have its own secret_token. on your localmachine just setup the same variable

Nick Ginanto
  • 31,090
  • 47
  • 134
  • 244
  • thanks - could you give me a little more info on how to go about setting this up in relation to the different environments? – tommyd456 Sep 01 '13 at 10:01
  • 6
    You should use rake secret to generate SECRET_TOKEN : `heroku config:set SECRET_TOKEN=$(rake secret)` – dsimard Jan 14 '14 at 20:01