Heroku sets SECRET_KEY_BASE when it's not defined - ruby-on-rails

I want Heroku to not set SECRET_KEY_BASE so I can use the one from credentials, but despite me deleting it from the UI, verifying it doesn't exist by running heroku config, I still get it set as an environment variable on my dynos. And it's the same in all the dynos:
SECRET_KEY_BASE=d2753b472abb...
I also tried setting it to a blank string by running heroku config:set SECRET_KEY_BASE="" and Heroku insist on setting it up as I can see by running bash and then env within bash.
How can I prevent that from happening?

Unfortunately, the Heroku Ruby buildpack generates and sets SECRET_KEY_BASE via the shell if it doesn't exist in your Heroku config vars.
It currently doesn't seem possible to directly use the secret key set in credentials.yml. You could make credentials.yml and SECRET_KEY_BASE align though.
Source: https://github.com/heroku/heroku-buildpack-ruby/issues/1143
And here is a short extract from that issue:
If you set your own SECRET_KEY_BASE, we do nothing.
If you do not set a SECRET_KEY_BASE we generate and set one for you.
We recommend using our heroku config interface for storing secrets rather than using the encrypted file storage that ships with rails.
If you want to use encrypted file storage locally with rails you could copy our secret key base heroku run echo $SECRET_KEY_BASE or you can set your own
value manually locally and then again via heroku config.

Related

Setting Rails Credentials For Production Mode

I am trying to store my stripe live key via Credentials as shown in the Securing Rails Application Guide: https://guides.rubyonrails.org/security.html#custom-credentials
I'm not sure what I'm doing wrong, the keys are written to the credentials file and in the test and development environments they work but when pushing to production I get errors that say my API Keys are not set. Here are what my credentials file and production config look like:
Credentials file ->
stripe_live: xxx.xxx.xxx
config/environments/production:
Stripe.api_key = Rails.application.credentials.stripe_live
I've also tried setting the keys with this command
rails credentials:edit --environment production and still no luck in the production environment.
How do I set rails credentials for the production environment? Do I need to set the RAILS_MASTER_KEY as an env variable in my production environemtn?
Set RAILS_MASTER_KEY to the string located within config/master.key . Rails automatically will use this value to decrypt your credentials file. A separate credentials file is optional, but if you do chose to use the separate credentials file you need to be sure that you use that key for the RAILS_MASTER_KEY env variable.

Why is secret_key_base blank on Heroku (Rails 5.2)

I deleted secrets.yml and created credentials.yml.enc.
Locally I am using master.key, and in production I don't have any master key, only a RAILS_MASTER_KEY set as an environment variable.
On Heroku, if I run Rails.application.secrets I get:
{:secret_key_base=>nil, :secret_token=>nil}
and if I run Rails.application.credentials I do in fact see my secret_key_base.
However, locally... if I run the same commands, I DO see secret_key_base when calling Rails.application.secrets.
My main concern is that rails is going to have an empty secret_key_base in production which would be used to encrypt sessions and all kinds of critically important security things. I'm trying to verify that it actually does have the key set.
I'd love a way to 100% confirm that it's working in production, and that it's not blank. Is there some method I can call to check which doesn't rely on calling it via the methods above?
The SECRET_KEY_BASE is stored as an environment variable on Heroku. You can either view these in the interface by going to the settings for that dyno or you can do it in the terminal:
heroku run bash
then
env | grep SECRET_KEY_BASE
If you do not see it there may be an issue but you can generate a new one for Heroku and set it in the environment variables (see Rails.application.key_generator)

How to set up and use Rails environment variables in production server?

I need to set up an environment variable for my rails app. Both in my local machine and in the production server. I read some tutorials on the internet but NONE has given the complete instruction on how to set and use these variable in the actual production server. I use digital ocean and linux server to host my rails app.
I have spent days trying to figure this out, but still haven't found a clear and complete instruction from setting the variables on my local machine -> push it to git repo -> set and use the variables in production server. So, hope somebody can help me here, thanks!
UPDATE:
This is how I currently setup the environment variables in my rails app by using figoro gem:
You can set system-wide environment variables in the /etc/rc.local file (which is executed when the system boots). If your Rails app is the sole user of the Linux system, that is a good place to store credentials such as API keys because there is no risk of including this file in a public Git repository, as it is outside the application directory. The secrets will only be vulnerable if the attacker gains shell access to your Linux server.
Set the environment variables within /etc/rc.local (do not include the <> characters):
export SOME_LOGIN=<username>
export SOME_PASS=<password>
To see the value of an environment variable, use one of the following commands in the Linux shell:
printenv MY_VAR
echo $MY_VAR
To access those environment variables within Rails, use the following syntax:
Inside .rb files or at the rails console
ENV['MY_VAR']
Inside .yml files:
<%= ENV['MY_VAR'] %>
For anyone still having this issue, figaro now has an easy method in setting the production variables in heroku. Just run:
$ figaro heroku:set -e production
ryzalyusoff.
For Unix
You can use LINUX ENV in rails application.
# .env
GITHUB_SECRET_KEY=SECRET
TWITTER_ACCESS_KEY=XXXXXXXXXXXX
# in rails code
puts ENV["TWITTER_ACCESS_KEY"] # => SECRET
Create .env files for local machine and your production server. Export environment variables like this(on server with ssh):
export GITHUB_SECRET_KEY="XXXXXXXXXXXXXXXXXX"
Anyway, storing keys in config - bad idea. Just add .env.example, others keys configs add to .gitignore. Goodluck.
Example with Rails
For Windows
Syntax
SET variable
SET variable=string
SET /A "variable=expression"
SET "variable="
SET /P variable=[promptString]
SET "
Key
variable : A new or existing environment variable name e.g. _num
string : A text string to assign to the variable.
expression : Arithmetic expression
Windows CMD
I believe we should not push a secret file on git.
To ignore such file use gitignore file and push other code on the git.
On the server side just copy the secret file and create a symlink for that file.
You can find demo here http://www.elabs.se/blog/57-handle-secret-credentials-in-ruby-on-rails
You can set your environment variables in production in the same way, you do it for local system. However, there are couple of gems, which make it easier to track and push to production. Have a look at figaro. This will help you in setting up and deployment of env vars.
You can do this with figaro gem
or in rails 4 there is a file named secret.yml in config folder where you can define your environment variables this file is by default in .gitignore file.For production you need to manually copy that file to server for security reason so that your sensitive information is not available to any one
First create your variable like:
MY_ENV_VAR="this is my var"
And then make it global:
export MY_ENV_VAR
You can check if the process succeeded with:
printenv
Or:
echo MY_ENV_VAR

Fog directory can't be blank, Aws access key can't be blank, Aws secret access key can't be blank

Im using asset_sync gem to upload assets to Amazon S3 bucket. I used dotenv to store my keys and secret keys and deployed using capistrano to Amazon EC2. Everything was fine.
But when I moved the keys to .bash_profile on my server and added an initializer, asset upload failed with this error.
rake aborted!
Fog directory can't be blank, Aws access key can't be blank, Aws secret access key can't be blank
Please help me to figure out why the keys/secrets are not found.
Basically means you've not set the ENV vars for your shell session. I guarantee if you run rake assets:precompile FOG_DIRECTORY=[your_dir] AWS_ACCESS_KEY_ID=[your_access_key] AWS_SECRET_ACCESS_KEY=[secret_access] you'll be able to perform the operation
The best recommendation I can give right now is to look in the
/etc/environment file on your VM. If you have this file, you'll be
able to set the system-wide variables which will get used each time
you load your app
The problem is an issue between the assigning of ENVIRONMENT & SHELL variables - SHELL vars are only available in a specific shell session, whilst ENVIRONMENT vars are available throughout the system
I have not found how to declare shell-specific variables on the fly yet, by putting all the env vars inside /etc/environment it works for us

Heroku: upload single unversioned file

I have a Rails 4 application hosted by Heroku.
Seeing as I'm working on an open-source project, there are several unversioned files containing sensitive information listed in .gitignore. For example, I have a .secret file at the root of the app that contains the key with which cookies are encrypted. I created this file by running the rake secret command.
My problem is that I cannot send this file to my heroku app since it is not versioned, it is not included in the deployment. Furthermore, I am using Github and cannot risk having my key disclosed publicly in the commit history.
I have attempted to use the heroku run command to create the file (heroku run 'rake secret > .secret' to no avail). I have attempted to connect with the terminal using heroku run bash but as the filesystem is ephemeral, my changes are not preserved when I exit the terminal.
Do you have any idea how I could achieve having unversioned files on a Heroku application?
Secret data (keys, passwords, etc) should be stored as config vars on Heroku. They are then accessed via the ENV hash in your code.
If you use something like figaro, you can place these vars in an application.yml (don't commit the file)
application.yml:
SECRET_KEY: my_secret_key
Figaro then has a rake task to push these to heroku:
rake figaro:heroku
Or, you can manually set them:
heroku config:set SECRET_KEY=my_secret_key
Finally, access them in your app as:
ENV['SECRET_KEY']

Resources