Rails Secret_key_base Generate

An intro to Encrypted Secrets in Ruby on Rails

Rails 5.1 introduced Encrypted Secrets to help simplify the management of your application secrets (things such as service credentials and the secret_key_base). This article details the feature and its usage.

Why Encrypted Secrets?

In development mode, a Rails application would use its name as the secretkeybase, and can be easily extracted by visiting an invalid resource for a path. As a result, this allows a remote user to create and deliver a signed serialized payload, load it by the application, and gain remote code execution.

Since Rails 4.1, the framework has given you the ability to centrally store secrets in the config/secrets.yml file. The glaring shortcoming of secrets.yml is that the file actually is in no way secure, and you cannot actually safely check it into version control with any production credentials. The convention for production credentials was always to load them within secrets.yml but from the host environment. Usually your secrets file would end up looking something like this:

  1. Dec 22, 2017  Rails 5.1 introduced Encrypted Secrets to help simplify the management of your application secrets (things such as service credentials and the secretkeybase). This article details the feature and its usage. Why Encrypted Secrets? Since Rails 4.1, the framework has given you the ability to centrally store secrets in the config/secrets.yml file.
  2. As the name implies, secretkeybase should be a secret. That's why we don't generate a secret for production in config/secrets.yml.You see that it's reading from an environment variable so you can easily set your secret on your production server, without changing the file.
config/secrets.yml
2
4
6
8
10
secret_key_base:972888f3521e5c5ec8491cd3295e51af38fc93e059c1a00e8e03804288f64d77753b66a5108baaddfe6
secret_key_base:1d1be5ad7ea1e9d833e752a2de941217222fe9c6ea5467b9d63f69d38c8aa4c4219db9edc37d3b80fc4
secret_key_base:<%=ENV['SECRET_KEY_BASE']%>

Rails 5.1+’s Encrypted Secrets feature means you can now keep production secrets in a second fully encrypted file (AES-256 by default), which is managed by the framework. Secrets from the encrypted secrets.yml.enc file are merged with secrets from the unencrypted secrets.yml file.

Getting started with Encrypted Secrets

Encrypted secrets is not set up by default, and in order to bootstrap it you need to run:

In shell

This will drop a few files into your project tree:

  • config/secrets.yml.key – contains the actual secret key used by the framework to AES-encrypt your secrets.
  • config/secrets.yml.enc – the encrypted digest form of your (encrypted) secrets.

It should go without saying that the config/secrets.yml.key file should be handled carefully and never checked into version control as it is all that is required to decrypt your secrets (it is accordingly gitignored by default).

To edit your secrets, invoke the command:

In shell

If you have no EDITOR variable defined in your shell environment you will need to set one. For Sublime Text, you can add the following to your .bash_profile (or similar shell configuration file).

.bash_profile
2
4
# Assumes you have set up 'subl':
# https://www.sublimetext.com/docs/2/osx_command_line.html

The secrets:edit task will decrypt your secrets and pop them open in your editor where you can make changes. When you quit the editor, the framework will re-encrypt the secrets and overwrite the existing secrets.yml.enc file.

Usage in production

In production, Rails will look for the decryption key either in the environment variable RAILS_MASTER_KEY or in a local copy of the key file (config/secrets.yml.key). How you get the environment variable exposed to your application or how you inject the key file is a matter that is specific to your particular hosting and infrastructure management setup.

Caveats

It is important to understand that using Encrypted Secrets over other solutions does have drawbacks. It is likely to fit best within projects that have small and very trusted teams. Because every developer who is expected to manage secrets in an application must have a local copy of the encryption key, situations like terminating an employee become somewhat complicated. More specifically you would need an efficient solution to quickly rotate your encryption key in production, and also to quickly distribute a new key to all developers.

For this reason you may want to consider another solution if your organization is of a certain scale. What the best such solution is will likely come down to details of your infrastructure management and hosting, but no matter what it will likely be a matter of having credentials exposed via the ENV. PaaS solutions like Heroku, CloudFoundry and Cloud66 all provide ENV variable management faculties, and such solutions are better equipped to handle the practical security needs of larger organizations.

Related posts:

Leave a Comment

An Engine with the responsibility of coordinating the whole boot process.

Initialization

Rails::Application is responsible for executing all railties and engines initializers. It also executes some bootstrap initializers (check Rails::Application::Bootstrap) and finishing initializers, after all the others are executed (check Rails::Application::Finisher).

Configuration

Rails Generate Secret_key_base For Staging

Besides providing the same configuration as Rails::Engine and Rails::Railtie, the application object has several specific configurations, for example “cache_classes”, “consider_all_requests_local”, “filter_parameters”, “logger” and so forth.

Check Rails::Application::Configuration to see them all.

Routes

The application object is also responsible for holding the routes and reloading routes whenever the files change in development.

Middlewares

The Application is also responsible for building the middleware stack.

Booting process

The application is also responsible for setting up and executing the booting process. From the moment you require “config/application.rb” in your app, the booting process goes like this:

Multiple Applications

If you decide to define multiple applications, then the first application that is initialized will be set to Rails.application, unless you override it with a different application.

To create a new application, you can instantiate a new instance of a class that has already been created:

In the above example, the configuration from the first application was used to initialize the second application. You can also use the initialize_copy on one of the applications to create a copy of the application which shares the configuration.

If you decide to define Rake tasks, runners, or initializers in an application other than Rails.application, then you must run them manually.

  • MODULERails::Application::Bootstrap
  • MODULERails::Application::Finisher
  • CLASSRails::Application::Configuration
  • CLASSRails::Application::DefaultMiddlewareStack
  • CLASSRails::Application::RoutesReloader
Methods
C
  • config_for,
  • console,
  • create,
E
  • encrypted,
F
G
I
  • inherited,
  • initialized?,
  • initializer,
  • instance,
K
M
N
R
  • rake_tasks,
  • reload_routes!,
S
  • secret_key_base,
V
[RW] assets
[W] config
[R] executor
[R] reloader
[R] reloaders
[RW] sandbox
[RW] sandbox?
[W] secrets
Class Public methods

Source: show on GitHub

Source: show on GitHub

Rails Secret_key_base Generate Account

Source: show on GitHub

Source: show on GitHub

Source: show on GitHub

Instance Public methods

Rails Generate Secret Key Base

Convenience for loading config/foo.yml for the current Rails env.

Example:

Source: show on GitHub

Sends any console called in the instance of a new application up to the console method defined in Rails::Railtie.

Source: show on GitHub

Decrypts the credentials hash as kept in config/credentials.yml.enc. This file is encrypted with the Rails master key, which is either taken from ENV['RAILS_MASTER_KEY'] or from loading config/master.key. If specific credentials file exists for current environment, it takes precedence, thus for production environment look first for config/credentials/production.yml.enc with master key taken from ENV['RAILS_MASTER_KEY'] or from loading config/credentials/production.key. Default behavior can be overwritten by setting config.credentials.content_path and config.credentials.key_path.

Source: show on GitHub

encrypted(path, key_path: 'config/master.key', env_key: 'RAILS_MASTER_KEY') Link

Online universal key generator 2019. Shorthand to decrypt any encrypted configurations or files.

For any file added with rails encrypted:edit call read to decrypt the file with the master key. The master key is either stored in config/master.key or ENV['RAILS_MASTER_KEY'].

It's also possible to interpret encrypted YAML files with config.

Any top-level configs are also accessible directly on the return value:

The files or configs can also be encrypted with a custom key. To decrypt with a key in the ENV, use:

Or to decrypt with a file, that should be version control ignored, relative to Rails.root:

Source: show on GitHub

Stores some of the Rails initial environment parameters which will be used by middlewares and engines to configure themselves.

Source: show on GitHub

Sends any generators called in the instance of a new application up to the generators method defined in Rails::Railtie.

Source: show on GitHub

Returns true if the application is initialized.

Source: show on GitHub

Sends the initializers to the initializer method defined in the Rails::Initializable module. Each Rails::Application class has its own set of initializers, as defined by the Initializable module.

Source: show on GitHub

Sends the isolate_namespace method up to the class method.

Source: show on GitHub

Returns the application's KeyGenerator

Source: show on GitHub

Returns a message verifier object.

This verifier can be used to generate and verify signed messages in the application.

It is recommended not to use the same verifier for different things, so you can get different verifiers passing the verifier_name argument.

Parameters

  • verifier_name - the name of the message verifier.

Examples

See the ActiveSupport::MessageVerifier documentation for more information.

Source: show on GitHub

If you try to define a set of Rake tasks on the instance, these will get passed up to the Rake tasks defined on the application's class.

Source: show on GitHub

Reload application routes regardless if they changed or not.

Source: show on GitHub

Sends any runner called in the instance of a new application up to the runner method defined in Rails::Railtie.

Source: show on GitHub

The secret_key_base is used as the input secret to the application's key generator, which in turn is used to create all MessageVerifiers/MessageEncryptors, including the ones that sign and encrypt cookies.

In development and test, this is randomly generated and stored in a temporary file in tmp/development_secret.txt.

In all other environments, we look for it first in ENV, then credentials.secret_key_base, and finally secrets.secret_key_base. For most applications, the correct place to store it is in the encrypted credentials file.

Source: show on GitHub

Returns secrets added to config/secrets.yml.

Example:

Rails.application.secrets.namespace returns my_app_production in the production environment.

Source: show on GitHub

Instance Protected methods

Source: show on GitHub