README.md in ejson-rails-0.2.1 vs README.md in ejson-rails-1.0.0
- old
+ new
@@ -1,10 +1,10 @@
# EJSON::Rails
[](https://github.com/Shopify/ejson-rails/actions?query=branch%3Amain)
-Automatically injects [`ejson`](https://github.com/Shopify/ejson) decrypted secrets into your `Rails.application.secrets`.
+Automatically injects [`ejson`](https://github.com/Shopify/ejson) decrypted secrets into your `Rails.application.credentials`.
## Installation
Add this line to your application's Gemfile:
@@ -18,127 +18,60 @@
Or install it yourself as:
$ gem install ejson-rails
-## Usage
+## Configuration
-Decrypted secrets and credentials from `project/config/secrets.json` (or `project/config/secrets.{current_rails_environment}.json` if that doesn't exist) will be accessible via `Rails.application.secrets`. For example:
+By default, the gem will look for decrypted secrets in `project/config/secrets.json` or `project/config/secrets.{current_rails_environment}.json` if that doesn't exist.
-`# project/config/secrets.json`
-```json
-{ "some_secret": "key" }
-```
+If your application or environment has a unique way of retrieving decrypted secrets, you can do so by setting `EJSON::Rails::Railtie.ejson_secret_source` to a callable object in `config/application.rb`. For example:
-will be accessible via `Rails.application.secrets.some_secret` or `Rails.application.secrets[:some_secret]` upon booting. JSON files are loaded once and contents are `deep_merge`'d into your app's existing rails secrets.
-
-Secrets will also be accessible via `Rails.application.credentials`, e.g. `Rails.application.credentials.some_secret` or `Rails.application.credentials[:some_secret]`. To avoid subtle compatibility issues, if a credential already exists, an error will occur.
-
-If you set the `EJSON_RAILS_DELETE_SECRETS` environment variable to `true` the gem will automatically delete the secrets from the filesystem after loading them into Rails. It will delete both paths (`project/config/secrets.json` and `project/config/secrets.{current_rails_environment}.json`) if the files exist and are writable.
-
-NOTE: This gem does not decrypt ejson for you. You will need to configure this as part of your deployment pipeline.
-
-## Migrating to credentials
-
-Rails 7.1 has deprecated application secrets in favor of credentials. ejson-rails can migrate secrets to application credentials.
-
-Even before running Rails 7.1, you can migrate your secrets in several steps:
-1. Convert secrets from YAML to JSON
-2. Move any ERB embedded within the YAML to the corresponding environment file
-3. Use `Rails.application.credentials` in place of Rails secrets
-
-### 1. Convert secrets from config/secrets.yml to config/secrets.json
-
-Typically, secrets share the same structure across different environments. While test secrets are often placeholders, development secrets may sometimes use environment variables to communicate with external services.
-In that case, the easiest way to migrate is to use the test secrets in all local environments, and override for development as needed:
-
-```sh-session
-# Recommended
-bin/rails runner -e test 'Rails.root.join("config/secrets.json").write(JSON.pretty_generate(Rails.application.secrets.to_h.without(:secret_key_base)))'
-```
-
-> [!NOTE]
-> Alternatively, if its necessary to configure distinct values between the development/test environment, you can use separate JSON files for the development/test environments:
->
-> ```sh-session
-> bin/rails runner 'Rails.root.join("config/secrets.#{Rails.env}.json").write(JSON.pretty_generate(Rails.application.secrets.to_h.without(:secret_key_base)))'
-> bin/rails runner -e test 'Rails.root.join("config/secrets.#{Rails.env}.json").write(JSON.pretty_generate(Rails.application.secrets.to_h.without(:secret_key_base)))'
-> ```
-
-### 2. Move any ERB into the corresponding environment files
-
-YAML supports ERB while JSON secrets do not. If your secrets contain ERB, you will need to move that logic to the corresponding environment file:
-
-**Before**:
-
-`config/secrets.yml`
-```yaml
-development:
- some_external_service:
- api_token: <%= ENV.fetch(SOME_EXTERNAL_SERVICE_API_TOKEN, "12345") %>
-```
-
-**After**:
-
-`config/secrets.json` as generated by the *recommended* command above.
-```json
-{
- "some_external_service": {
- "api_token": "12345"
- },
- "something_else_entirely": "abc"
-}
-```
-
-`config/environments/development.rb`
```ruby
-Rails.application.configure do
- # elided
+# config/application.rb
- credentials.some_external_service.api_token = ENV.fetch("SOME_EXTERNAL_SERVICE_API_TOKEN", "12345")
- credentials.something_else_entirely = ENV.fetch("SOMETHING_ELSE_ENTIRELY", "abc")
+# This must be placed BEFORE your application constant which inherits from Rails::Application
+EJSON::Rails::Railtie.ejson_secret_source = FooBar::SecretCredentialReader
+
+# Custom credential reader that lives somewhere else
+module FooBar
+ class SecretCredentialReader
+ class << self
+ def call
+ '{"secret": "secret_from_ejson_secret_source"}'
+ end
+ end
+ end
end
```
-#### Rails 7.0 Note
-> [!NOTE]
-> In Rails 7.0, credentials are accessed as a Hash with [] and []=.. This is important because the dynamic accessor methods will set values in a different object, and credentials will behave inconsistently after that:
+For simple cases, you can use a `proc`:
```ruby
-Rails.application.credentials.some_external_service.api_token = "foo"
-Rails.application.credentials[:some_external_service][:api_token] # => "12345"
+EJSON::Rails::Railtie.ejson_secret_source = proc { '{"secret": "secret_from_ejson_secret_source"}' }
```
-Also note the code sets top-level values through `credentials.config`, because `credentials#[]=(key, value)` sets values in a different object.
+## Usage
-```ruby
-Rails.application.credentials[:something_else_entirely] = "foo"
-Rails.application.credentials[:something_else_entirely] # => "abc"
-```
+Decrypted secrets will be accessible via `Rails.application.credentials`. For example:
-Make sure there's no code using the dynamic accessors before setting the configuration in the Hash, or the values won't be accessible from the dynamic accessor:
+`# project/config/secrets.json`
-```ruby
-Rails.application.credentials.something_else_entirely # just accessing is enough to cause the issue
-Rails.application.credentials[:some_external_service][:api_token] = "foo"
-Rails.application.credentials.some_external_service.api_token # => "12345"
+```json
+{ "some_secret": "key" }
```
-### 3. Use `Rails.application.credentials`
+will be accessible via `Rails.application.credentials.some_secret` or `Rails.application.credentials[:some_secret]` upon booting. JSON files are loaded once and contents are `deep_merge`'d into your app's existing Rails credentials.
-You are now ready to replace Rails secrets with Rails credentials:
+To avoid subtle compatibility issues, if a credential already exists, an error will occur.
-```sh-session
-git ls-files | xargs ruby -pi -e 'gsub("Rails.application.secrets", "Rails.application.credentials")' --
-```
+If you set the `EJSON_RAILS_DELETE_SECRETS` environment variable to `true` the gem will automatically delete the secrets from the filesystem after loading them into Rails. It will delete both paths (`project/config/secrets.json` and `project/config/secrets.{current_rails_environment}.json`) if the files exist and are writable.
-To avoid the deprecation warning from the use of secrets in `ejson-rails` once you're running Rails 7.1, require another file from your Gemfile:
+NOTE: This gem does not decrypt ejson for you. You will need to configure this as part of your deployment pipeline.
-```ruby
-gem 'ejson-rails', require: 'ejson/rails/skip_secrets'
-```
+## Migrating to credentials
-With this require, ejson-rails will no longer merge secrets from JSON into `Rails.application.secrets`. This will be the default in the next major version.
+Rails 7.1 has deprecated application secrets in favor of credentials. `ejson-rails` no longer writes to Rails secrets to avoid crashing given Rails 7.2 removal of the feature. See the README for the last version that supports secrets to read more about migrating: [`ejson-rails` v0.2.2 – Migrating to credentials](https://github.com/Shopify/ejson-rails/tree/v0.2.2#migrating-to-credentials).
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.