Rails

Rails5.2から追加された credentials.yml.enc のキホン

secrets.yml はどこへ消えた?

Rails5.2では新規アプリを作成した時にconfig/secrets.ymlが生成されず、代わりにconfig/credentials.yml.encが生成されるようになりました。

credentials.yml.encの使い方について調べた内容を備忘録として投稿させていただきます。

credentials.yml.enc の編集方法

ファイルを直接編集することはできない

credentials.yml.encの内容は暗号化されてるため、エディタなどで直接ファイルを開いて編集することはできません。

config/credentials.yml.enc
Q+GBLmbxagoirjyHWkJDdaMdg0cJR...

credentials.yml.encを編集するためにはrails credentials:editコマンドを実行します。

EDITOR未指定の場合

credentials.yml.encの編集には環境変数:EDITORに指定されてるエディタが利用されます。環境変数:EDITORが未設定の状態でrails credentials:editを実行した場合は以下のようなメッセージが表示されます。

$ rails credentials:edit

No $EDITOR to open file in. Assign one like this:

EDITOR="mate --wait" bin/rails credentials:edit

For editors that fork and exit immediately, it's important to pass a wait flag,
otherwise the credentials will be saved immediately with no chance to edit.

EDITORの指定方法

viを利用してcredentials.yml.encを編集する場合は、環境変数:EDITORviを指定してrails credentials:editコマンドを実行します。

$ EDITOR="vi" bin/rails credentials:edit

.bash_profileなどに環境変数:EDITORを指定しておけば、EDITOR="xxx"の指定は不要になります。

# .bash_profileに環境変数 EDITOR を設定する
$ echo 'export EDITOR="vi"' >> ~/.bash_profile
$ source ~/.bash_profile
$ echo $EDITOR
  #=> vi

$ bin/rails credentials:edit
credentials.yml.enc
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: 8be8e637d755f79c799048bed8be0c...

credentials.yml.enc の読み取り方法

credentials.yml.encに設定した資格情報を取り出すにはRails.application.credentials.xxxを指定します。

credentials.yml.enc
aws:
  access_key_id: 123
  #=> Rails.application.credentials.aws[:access_key_id]
  secret_access_key: 345
  #=> Rails.application.credentials.aws[:secret_access_key]

secret_key_base: 8be8e637d755f79c799048bed8be0c...
#=> Rails.application.credentials.secret_key_base

例:rails consoleを利用したcredentials.yml.encの読み取り

$ rails c

irb(main):001:0> Rails.application.credentials.aws[:access_key_id]
=> 123

irb(main):002:0> Rails.application.credentials.aws[:secret_access_key]
=> 345

irb(main):003:0> Rails.application.credentials.secret_key_base
=> "8be8e637d755f79c799048bed8be0c..."

irb(main):004:0> exit

credentials.yml.enc の暗号化・復号について

config/master.key

credentials.yml.encmaster keyを利用して暗号化・復号されます。
デフォルトのmaster keyの値はconfig/master.keyに記載されてます。

config/master.key
cee513823adb2cda09b6c08b2b5508..

Rails5.2が生成する.gitignoreでは/config/master.keyが標準で指定されており、master keyがGitリポジトリに含まれないように配慮されてます。

.gitignore
# Ignore master key for decrypting credentials and more.
/config/master.key

/config/master.keyが存在しない状態でrails credentials:editコマンドを実行した場合、/config/master.keyが生成されます。

$ bin/rails credentials:edit

Adding config/master.key to store the master encryption key: 0c31e7f7da70866fe43d4f2cb93a56c2

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

環境変数:RAILS_MASTER_KEY

/config/master.keyが共有できない環境ではmaster key環境変数:RAILS_MASTER_KEYで指定します。

/config/master.keyが存在せず、環境変数:RAILS_MASTER_KEYmaster keyが設定されてない場合はcredentials.yml.enc内のデータは読み取れません。

$ rails c

irb(main):001:0> Rails.application.credentials.secret_key_base
=> nil

/config/master.key`が存在しなくても、環境変数:RAILS_MASTER_KEYmaster keyを設定した場合はcredentials.yml.enc内のデータが読み取れるようになります。

$ export RAILS_MASTER_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$ rails c

irb(main):001:0> Rails.application.credentials.secret_key_base
=> cee513823adb2cda09b6c08b2b5508..

config.require_master_key設定

本番環境ではmaster keyの指定漏れを防ぐためにconfig/environments/production.rbconfig.require_master_key = trueを有効化することが推奨されてるようです。

config/environments/production.rb
config.require_master_key = true

上記オプションが有効の場合、master keyが指定されてない状態でサーバ起動を実行しようとするとエラーが発生します。

$ rails s

=> Booting Puma
=> Rails 5.2.0 application starting in development
=> Run `rails server -h` for more startup options
Missing encryption key to decrypt file with. Ask your team for your master key and write it to /xxx/my-app/config/master.key or put it in the ENV['RAILS_MASTER_KEY'].
Exiting

参考

Rails Encrypted Credentials on Rails 5.2