秘密情報の管理について
Railsアプリケーションをリポジトリにプッシュする際に、秘密情報の管理があります。
例えば、githubでアプリケーションをグローバルに公開する場合、データベースのユーザとパスワードなどをconfig/detabase.ymlに記述すると閲覧した全ユーザに秘密情報を公開することになりどのように管理するかが問題となります。次に挙げる要件全てを満たすやり方がベストです。
- アプリケーションが秘密情報を利用できるようにしたい
- 開発者が必要に応じて秘密情報を確認したり、変更できるようにしたい。開発者同士では共有したい。
- 秘密情報が漏洩すると第三者に悪用される危険があるため、レポジトリに秘密情報を格納することは避けたい(特に、レポジトリが全世界に後悔されているような場合は絶対に避けたい)
Rails5.1までは、この問題を解決するために、秘密情報を環境変数でアプリケーションに伝える方法が広く使われていました。しかし、このやり方では、管理すべき秘密情報が多くなると、リポジトリ外で管理すべきことが増え、煩雑になってしまいます。そこで、Rails5.2から、Credentialsという新しい機能が追加されました。
Credentialsは、特定の方法で管理されるproduction環境用の秘密情報です。管理される秘密情報そのものを指すと同時に、そのような管理の仕組みを指す言葉でもあります。Credentialsでは、秘密情報w構造化して記述してリポジトリで管理できるようにしますが、このときリポジトリに入る内容はある1つのキーで暗号化されます。そして、そのキーはリポジトリの外で管理しておき、アプリケーションに伝えて、アプリケーションが復号して利用できるようにします。これによって、多くの秘密情報を一括で簡単に管理できるにも関わらず、秘密情報の漏洩を防ぐことができるようになるのです。
秘密情報の復号化・復号
production環境用の秘密情報はconfig/credentials.ymlに記述します。このファイルは常に暗号化された状態で保存されます。開発者がこのファイルの内容を編集するには、Railsの用意している専用のコマンドを通じて行います。
Credentialsの内容
credentialsを暗号化して保存するためのconfig/credentials.yml.encはrails newで新規Railsアプリケーションを作成した時点で作成されています。初期状態では暗号化されています。
復号化するには、rails credentials:showコマンドを使います。
$ 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: edac5f08c1e8077c5d79d9ca20c7cbb7b190fa78bb08eebcfc92bcf50d446b0dab53093cef331e2cab636f0f5954b079c967fc74768679c74b5325c5f4d6f011
Credentialsの編集
credentialsの編集コマンドを打つ前に、デフォルトのエディタを設定する必要があるので環境変数にエディタを設定します。
~/.bashrc ファイルに以下のコードを追記します。ここでは例としてvimを設定します。
export EDITOR=vim
credentialsを編集するには以下コマンドを使用します。
$ bin/rails credentials:edit
コマンドを実行すると、環境変数「EDITOR」で指定したテキストエディタが起動し、一時ファイルとして復号されたcredentialsの内容を編集することができます。編集して、保存すると暗号化してconfig/credentials.yml.encに保存されます。
アプリケーションからcredentialsを参照する
Railsアプリケーションからは、以下のようにして秘密情報にアクセスできます。
> Rails.application.credentials.aws
=> [:access_key_id=>123, :secret_access_key=>123]
存在しないキーをを参照していた場合はnilが返ります。
> Rails.application.credentials.something_missing
=> nil
もし存在しないキーを参照する意図がなく、そのような場合に確実に例外を発生されたいのであれば「!」をキーの最後につけることでそのように動作してくれます。
> Rails.application.credentials.something_missing!
=> KeyError: :something_missing is blank
マスターキーの扱いに気をつける
暗号化<=>復号化の時に意識しませんでしたが、鍵情報となるのがconfig/master.keyです。
このマスターキーを万が一紛失してしまうと、2度とcredentialsを復号できなくなってしまいます。マスターキーはチームが参照できるパスワード管理アプリケーションなどで保存するなどしましょう。
ちなみに、本当にマスターキーを紛失してしまった場合は、古いcredentials.yml.encファイルを削除して、再度「credentials:edit」で新しく作成する必要があります。
また、マスターキーの情報を暗号化したcredentialsと一緒のリポジトリに保存しないようにしましょう。これを行ってしまうと、平文のcredentialsを保存しているのと変わらない状態になってしまいます。なお、Railsアプリケーション作成時の「.gitignore」ファイルにはこのようなミスを防止するために「/config/master.key」が記述済みとなっています。