Rails触った事ないけどある日突然production.keyを作成する事になり四苦八苦したので記録。
Railsのproduction.keyとは
production環境の暗号化されたファイルproduction.ymlを復号するためのキー。
暗号化されたファイルにはプロジェクトの機密情報が含まれ、暗号化されたファイルをバージョン管理し、キーはバージョン管理から外す。
production.ymlというのは作成時に環境を指定したからこの名前になっており、基本的にはcredentials.ymlというのが暗号化されたファイルの名称。
Credentialsの作り方(基本)
既存のキーの確認方法
下記のような感じで確認する
$ EDITOR="vi" bin/rails credentials:show
# 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: xxx
aa_bank:
secret: yyy
aeskey: zzz
例えばaa_bankのシークレット情報を暗号化したい場合は下記で編集。
暗号化するファイル名はcredential.ymlになる。
キーはmaster.keyという名前になる。
EDITOR="vi" bin/rails credentials:edit
暗号化するファイルにproduction.ymlと名付けたい場合は下記のようにする。
production
の部分を環境名に変える事で、環境毎にファイルとキーを作成できる。
EDITOR="vi" bin/rails credentials:edit -e production
できあがるファイルは下記のような構成。
$ ls -ltr config/credentials
total 16
-rw------- 1 user user 32 Sep 16 18:38 production.key
-rw-rw-r-- 1 user user 672 Sep 16 19:26 production.yml.enc
アプリからのシークレット情報呼び出し
こんな感じで呼び出すらしい。
pry(main)> Rails.application.credentials.config
=> {:aa_bank=>{:secret=>yyy, :aeskey=>zzz}}
Rails6からの仕様ではまった
EDITOR="vi" bin/rails credentials:edit
して作成したmaster.keyをRails6から環境変数RAILS_MASTER_KEY
に入れておけばmaster.keyのファイル自体は不要、という仕様がある。
それ自体は便利な仕様だけど、例えばアプリ担当とインフラ担当が明確に分かれていて、アプリ担当の開発環境にはmaster.keyが存在、appname/.env
に環境変数でキーを追記してその形で受け取ったインフラ担当がRailsの仕様を知らない場合などはまる事案が発生する(自分)
具体的には、.env
に環境変数でキーが存在する場合、credentials:edit
しても新たにmaster.key
や-e
で指定して作成するproduction.keyなどキーが全て新たに作られない、という動きになり、作られるはずのものが作られず、でもアプリ側ではシークレットの読み込みに問題がない、という不思議状態に陥る。
対処について
確認方法:RAILS_MASTER_KEY
を削除、master.keyを配置する
これを試す時、.env
から環境変数の記載を削除した後、サーバ上から環境変数が削除されていない事に気づかずはまった。
詳細は不明だが、railsの実行ユーザーには.env
に記載した環境変数が追加される、という仕様っぽい。
下記はrailsでの環境変数の参照の仕方。rails c
すら知らんかった。
$ ./bin/rails c
[fog][DEPRECATION] Fog::Storage::AWS is deprecated, please use Fog::AWS::Storage.
[fog][WARNING] Unrecognized arguments: aws_access_key_id, aws_secret_access_key, aws_session_token, aws_credentials_expire_at, region, use_iam_profile
Loading staging environment (Rails 6.1.3.2)
irb(main):001:0> ENV["RAILS_MASTER_KEY"]
=> "bbb"
irb(main):002:0>
環境変数を削除
export -n RAILS_MASTER_KEY
この状態でcredentials:edit
すると、、
$ EDITOR="vi" bin/rails credentials:edit -e test
Adding config/credentials/test.key to store the encryption key: ccc
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/credentials/test.key
Ignoring config/credentials/test.key so it won't end up in Git history:
append .gitignore
キーができた!
上記を踏まえた実運用手順
production.keyを新たに作りたいけど、もし.env
にRAILS_MASTER_KEY
が存在している環境でアプリケーションを動かしているなら、下記の手順で作業をする。
#.envに記載のRAILS_MASTER_KEYの値xxxをコピペしmaster.keyを作成
cd appname
vim config/master.key
more config/master.key
xxx
# RAILS_MASTER_KEYの削除
sed -i '/^"RAILS_MASTER_KEY/d' .env
export -n RAILS_MASTER_KEY
# 削除確認
bin/rails c
ENV["RAILS_MASTER_KEY"]
# secretとキーを作成
EDITOR="vi" bin/rails credentials:edit -e production
出来上がったキーを.env
のRAILS_MASTER_KEY
に追記するのが基本的な取り扱い方らしい。
master.keyは名前のイメージとは違いdevelop用のようなものなのですね。
キーの名前だけRails5のmaster.keyの名残なのでは、との事でした。
(Rails5知りませんが)