
Rails: Credentials
(UPD 09.06.2020)
Начиная с версии 5.2 в Rails перешли с секретов (secrets.yml) на полномочия (credentials.yml).
Это менеджер ключей и паролей (да и вообще любых строк), хранящий всё в зашифрованном виде. Разберём как перевести имеющиеся секреты под новые требования на примере secret_key_base.
В данных примерах использовались: Rails 6.0.3.1, Capistrano 2.15.9, Bundler 2.1.4.
1. Нужно создать
Можно и на локальном сервере, затем скопировать на релизный. Консольная команда, вызывающая редактирование credentials:
EDITOR=vim rails credentials:edit
Если через бандлы, то:
EDITOR=vim bundle exec rails credentials:edit
Редактор можно выбрать любой, даже с GUI. В него ввести практически то же самое, что было в secrets.yml, формат соответственно YAML.
development:
secret_key_base: 461989807a53d2de8dacd1c73585713c37fddfe...
staging:
secret_key_base: fd9065a781d4e3e96f17790c7d25ca45dcb1d8d...
production:
secret_key_base: 914edbe043002157751b338ef7d571b949654cc...
Если в secrets.yml использовался <%= ENV["SECRET_KEY_BASE"] %>, то нужно его заменить на сам ключ.
После первого сохранения будут созданы master.key (в нём хранится ключ шифрования, при повторных сохранениях будет использоваться уже он) и credentials.yml.enc (это зашифрованные credentials).
Adding config/master.key to store the encryption key: 5ca595fdd3a6a774f0ae6b52c3fa29fc
Save this in a password manager your team can access.
If you lose the key, no one, including you, can access anything encrypted with it.
create config/master.key
File encrypted and saved.
2. Нужно задействовать.
1. В config/environments, как минимум в production.rb:
config.secret_key_base = Rails.application.credentials[Rails.env.to_sym][:secret_key_base]
Также включить требование ключа:
config.require_master_key = true
2. В иных местах, где использовался этот ключ, заменить на такую же конструкцию:
YourApp::Application.config.db_token = Rails.application.credentials[Rails.env.to_sym][:secret_key_base]
Но в этом примере правильнее всё-таки задействовать config:
YourApp::Application.config.db_token = Rails.application.config.secret_key_base
3. Использовать на релизе.
Ключ можно хранить в двух местах: config/master.key и переменная окружения RAILS_MASTER_KEY. Отсюда вариативность использования:
3.1 RAILS_MASTER_KEY
export RAILS_MASTER_KEY=5ca595fdd3a6a774f0ae6b52c3fa29fc
Вариант простой, но не безопасный - любой процесс на сервере имеет к ним доступ. Также, если на одном сервере больше одного проекта, им придётся использовать одну переменную. Так что рекомендую второй способ.
3.2 master.key
На примере, когда на проекте используются репозиторий и деплои.
Файл master.key не рекомендуется хранить в открытых репозиториях. Если Ваш репозиторий закрыт от ненужных глаз, то данной частью можно пренебречь, иначе не забыть добавить его в .gitignore. Файл credentials.yml.enc зашифрован и его лучше хранить в репозитории.
Одним из вариантов использования master.key на сервере является хранение его во внешней папке с ограниченным доступом и при деплое делать ссылку на него в папке config. Допустим, есть папка shared, находящаяся вне проекта, доступная только необходимым пользователям, и на которую есть ссылка shared в папке проекта. Туда и можно скинуть данный файл.
Создание ссылки на файл на примере Capistrano. Сам таск:
namespace :custom do
task :create_symlinks do
run "ln #{release_path}/shared/master.key #{release_path}/config/master.key"
end
end
Выполнение его нужно добавить после обновления кода, но перед выполнением любых подключений к БД, например миграций:
after "deploy:finalize_update", "custom:create_symlinks", "deploy:migrate"
С credentials.yml.enc всё проще - он добавится вместе с остальным кодом. После такого деплоя релизный проект сможет читать зашифрованные в файле ключи. Если что-то пошло не так, получите ошибку:
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit`
Если это первое использование на релизе, то рельсы нужно пнуть с помощью rails credentials:edit:
EDITOR=vim rails credentials:edit
или через bundle:
EDITOR=vim bundle exec rails credentials:edit
Готово:
"/tmp/47452.credentials.yml" 14L, 652C written
File encrypted and saved.
Немного о хранении других ключей
Хранить можно любые значения, например:
development:
stripe:
secret_key: sk_test_asdfgh123
token: rk_test_Hkkjbh43
production:
stripe:
secret_key: sk_live_qwerty456
token: rk_live_dsIIjhh5
service1_key: sdgnhcs3sc435dc
github:
app_id: 1111
app_secret: dfgdrghj6f
Обращение к ним:
Rails.application.credentials[Rails.env.to_sym][:stripe][:secret_key]
Rails.application.credentials[:service1_key]
Rails.application.credentials[:github}[:app_id]
Также можно запросить целый объект:
Rails.application.credentials.github
Начиная с Rails 6 можно использовать отдельные файлы для разных сред:
rails credentials:edit --environment staging