60

I've have a Rails app that loads a number of RSA certificates before a transaction is made with Paypal. On my development machine, these certificates are read from files in the file system but because Heroku (which I'm using for delpoyment) is largely read-only, I can't upload these files so I'm guessing I'll have to read the certificates from config variables (see Heroku Config Vars).

Because the certificates consist of multiple lines of data, I'm not sure how to set them as variables or even if this is possible. Does anyone know how I could do this or be able to suggest an alternative approach?

Many thanks, Eddie

Eddie Johnston
  • 623
  • 1
  • 5
  • 7

7 Answers7

58

I found that a easy way to add multi-line configs is to double quote them and then echo them from my local environment

heroku config:add EC2_PRIVATE_KEY="$EC2_PRIVATE_KEY"
danmayer
  • 4,326
  • 1
  • 22
  • 15
  • 5
    This worked great for me. This answer was helpful to me as well: http://stackoverflow.com/questions/2789319/file-content-into-unix-variable-with-newlines You can just set the var by using cat on the file that stores the multi-line var. – Josiah I. Oct 10 '13 at 16:29
  • 9
    `testvar=$(cat myfile.txt)`. Then `heroku config:add EC2_PRIVATE_KEY="$testvar"` – Eric H. May 27 '14 at 21:35
  • 40
    `heroku config:add EC2_PRIVATE_KEY="$(cat privatekey.pem)"` – wik Oct 20 '14 at 20:56
  • 1
    What happens when you echo the environment variable in the Heroku shell? Do you get spaces in the output, or actual newlines? – jollyroger Mar 19 '16 at 16:53
19

If you want to set Heroku config values from your file contents, you can use the following shell trick:

$ heroku config:set SECRET_KEY="$(cat path/to/secret.key)"

Multi-line values can be set directly by putting quotes around the value:

$ heroku config:set SECRET_KEY='first line
> second line'

If you're using Foreman to run locally (now heroku local), it doesn't support multi-line variables. You must use something to inject them into the environment first, such as envdir:

$ envdir my-env-dir heroku local
Judy2K
  • 795
  • 4
  • 8
  • 1
    This doesn't work in my Ruby 2.3.0 and Rails 5.0.0 app. I isolated it to being multi-line env var because changing it to a single line works. I get a psych parse error. Any thoughts on how to solve it? – HM1 Jan 25 '17 at 00:09
  • Here's error. It's easy to create test case locally. `/Users/hm/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/psych.rb:377:in 'parse': (): mapping values are not allowed in this context at line 29 column 17 (Psych::SyntaxError) from /Users/hm/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/psych.rb:377:in 'parse_stream' from /Users/hm/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/psych.rb:325:in 'parse' from /Users/hm/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/psych.rb:252:in 'load' from /Users/hm/.rvm/gems/ruby-2.3.0@global/gems/railties-5.0.0/lib/rails/application.rb:391:in 'secrets'` – HM1 Jan 26 '17 at 22:51
  • Sorry for the delay in responding to this... I'm not a Ruby developer, but your stack trace indicates that Rails is trying to parse a YAML file. Nothing in this answer involves writing code or even having a YAML file anywhere, so I guess this is unrelated? I'd recommend having a look at rails/application.‌​rb to see what YAML file it's attempting to load. – Judy2K May 27 '17 at 13:28
  • Thanks for responding... I was setting some key in rails `secret.yml` file to the `env` var that contained a multi-line text from a `cert.pem` file. It turns out, the parser worked with other dummy test samples, but not the real `cert.pem` file (it broke the parser giving above error). The solution per Heroku was to create a `.profile` file that wrote the `env` to a file on disk which was read where needed in the app. – HM1 May 31 '17 at 00:03
13

Or you can just go to the Settings tab of the Heroku dashboard, open Config Vars and paste it in.

Heroku Settings

Easy peasy.

James Gentes
  • 7,528
  • 7
  • 44
  • 64
  • 2
    Thanks. I pasted the private key without escaping any special chars and without doing "\n". Worked like a charm. – Arik Mar 12 '18 at 14:57
  • @Arik am facing the same problem - can you elaborate on what you mean by 'doing "\n"'? much appreicated – BenKoshy Aug 29 '18 at 08:20
  • @BKSpurgeon I didn't add \n to the end of the lines – Arik Aug 29 '18 at 11:23
10

We needed to do the same thing.

You can wrap the variable value in double quotes:

bobvila@bobuntu:~/svnroot/app/myapp$ heroku config:add woodchuck="How much wood
> could a woodchuck chuck
> if a woodchuck could chuck wood"
Adding config vars and restarting myapp... done, v25
woodchuck: How much wood
could a woodchuck chuck
if a woodchuck could chuck wood
bobvila@bobuntu:~/svnroot/app/myapp$ heroku config
=== Config Vars for myapp
woodchuck:                       How much wood
could a woodchuck chuck
if a woodchuck could chuck wood
bobvila@bobuntu:~/svnroot/app/myapp$ 

If you're using Foreman for localhost development, the .env file doesn't support multi-line variables so you'll need to export it to the shell before launching Foreman

daveespo
  • 589
  • 5
  • 9
8

My answer comes a bit late but I had the same issue recently with multi-line env. variables on Heroku. My solution was to use strict_encode64:

encoded_secret = Base64.strict_encode64("my_multi_line_secret")

add the key:

$ heroku config:set SECRET_KEY='the encoded_secret string here'

In the code, you then decode it using Base64.strict_decode64(ENV['SECRET_KEY'])

paulld
  • 151
  • 2
  • 5
7

An example of how to deal with this problem using NodeJS. Sanitize the value by replacing \\n characters with \n:

process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n')

Taken from: Escaping issue with firebase privateKey as a Heroku config variable

Eugene Kulabuhov
  • 2,349
  • 1
  • 26
  • 25
3

I know this is a very manual way of doing it, but what worked for me is to paste the private key into a text editor, find and replace \n with an actual line break and paste that as the value for the env var in Heroku.

dmc85
  • 250
  • 1
  • 9