最初は社内ブログに書いてたけど、動機は「探してもあんまり日本語のよさそうな情報がなかったから」なのでここに書きます。適当な理解という感じですが、いまのところうまくいっています。
前提
❯❯❯ be rails --version Rails 6.0.0 ❯❯❯ ruby --version ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
tl;dr
- 環境ごとに
credentials
ファイルとその鍵を分けられるようになりました。bundle exec rails credentials:edit --environment staging
のような感じで編集します。
RAILS_MASTER_KEY
に、RAILS_ENV
と一致した適切な鍵を入れれば自動で decrypt されて実行されます。Rails.application.credentials.muse[:minami_kotori]
たとえばこんな感じでアクセスできます。
rails/rails の実装 PR
Add support for multi environment credentials. by morgoth · Pull Request #33521 · rails/rails
やりかた
- いままでの
bundle exec rails credentials:edit
に option を付け加えるだけです。実際どういう風に中身を書いてアクセスするかは後述します。- ex:
bundle exec rails credentials:edit --environment production
- ex:
bundle exec rails credentials:edit --environment staging
- ex:
bundle exec rails credentials:edit --environment development
- ex:
bundle exec rails credentials:edit --environment test
- ex:
- decrypt するには、後述するようなディレクトリ構造で鍵を持ってきて置くか、実行する
RAILS_ENV
に応じたRAILS_MASTER_KEY
を設定します。 - 実行している
RAILS_ENV
のcredential
が存在するときはそこを勝手に読みにいってくれるので(実装参照)、特に追加する設定はないです。.gitignore
にも追加してくれます。- ただ、
secret_key_base
については、 production のは最初からあったconfig/credentials.yml.enc
から持ってくると楽です。 - staging のものは
bundle exec rake secret
とかで出したものを設定するとよいでしょう。
- ただ、
https://github.com/rails/rails/pull/33521/files#diff-19128a84fe2ae7019ccdb86efc86f684R281-R299
def credentials_available_for_current_env? File.exist?("#{root}/config/credentials/#{Rails.env}.yml.enc") end def default_credentials_content_path if credentials_available_for_current_env? File.join(root, "config", "credentials", "#{Rails.env}.yml.enc") else File.join(root, "config", "credentials.yml.enc") end end def default_credentials_key_path if credentials_available_for_current_env? File.join(root, "config", "credentials", "#{Rails.env}.key") else File.join(root, "config", "master.key") end end
ディレクトリ構造とか
こういう風になります。
❯❯❯ tree config/credentials config/credentials ├── development.key ├── development.yml.enc ├── production.key ├── production.yml.enc ├── staging.key ├── staging.yml.enc ├── test.key └── test.yml.enc
ファイルの中身はこんな感じ。
muse: minami_kotori: kawaii private_key: | -----BEGIN RSA PRIVATE KEY----- naisyo no kagi dayo -----END RSA PRIVATE KEY----- secret_key_base: himitsu <3
コードからは、こういう感じでアクセスできます。
kotori = Rails.application.credentials.muse[:minami_kotori] key = OpenSSL::PKey::RSA.new(Rails.application.credentials.muse[:private_key])
うれしいこと
- 権限に応じて適切に見られる情報を管理できる
- たとえば、
production.key
は正社員とかつよい権限のひとしか知らない、とかができる - 業務委託でお願いするひとには
test.key
とdevelopment.key
だけわたす、とか
- たとえば、
- 環境によって変化する値を気にしなくてよくなる
- unstable と production で値が異なるときとか
- kubesec とかでやるにはむずかしい機微情報を管理できる?
- 環境変数に入っちゃうのは良し悪しだと思うので…。