LiBz Tech Blog

LiBの開発者ブログ

Railsのcredentials.yml.encは、どういった運用ができるか?

f:id:kazuhisa_o:20181127101538j:plain

はじめに

株式会社LiBで今年11月からサーバーサイドエンジニアとして働いているブロッコリーです。
Rails未経験の中でRailsを使っている中で疑問に思ったことを記事にしていきたいと考えています。

セキュリティの意識について

日本では"改正個人情報保護法"や欧州では"GDPR"が話題になり、 インターネットサービスを運用していくにはセキュリティに関する重要性が高まってきました。

LiBでもPマークを取得するなど、個人情報保護の意識がとても高い会社だと感じています。
私個人では、今までの経験上セキュリティの要件を高く設計して開発したことがなかったため、特にセキュリティにフォーカスを当てていきます。

なぜcredentials.yml.enc?

Rails未経験だったため、試しに個人でセキュリティを意識しながら小さなサービスを作ってみようと検討してみました。
脳内の想定では、DevOpsのように開発と運用を密に連携する小さなチームをイメージして作成を開始しました。

そこではじめに悩んだのが、credentials.yml.encの運用についてでした。

複数環境での管理方法はどのようにするのか?
サービスを運用するにあたり、安全にアップデートを行うために、
開発環境,検証環境,本番環境などの複数環境を構築することが多いかと思います。

開発と運用が密になっている場合は、本番環境のデータベースなど個人情報のあるデータには直接アクセスできないようにすることで、悪意ある1人の開発者の影響で流出することを防いだり牽制することができます。
特に近年では、ソースコードの自動デプロイやサーバーの監視ツールなど本番環境のサーバーに入らずとも運用することが手段が増えているため、細かな権限の分離をしても運用することが可能になっていると考えています。

データベースのアカウント名やパスワードなどの機密情報を暗号化し運用するためにRailsではcredentials.yml.encが提供されています。
しかし、credentials.yml.encでは、各環境の機密情報を1つのファイルにまとめることはできるが、ファイルを分離し保存することができません。
そのためデータベースのアカウント名やパスワードを記載してしまうと、開発者全員に本番環境の機密情報を晒すことになります

解決策

いくつか調べたり、周りの人に聞いてみると下記のような方法で解決しているようです。

credentials.yml.encをメインに使う場合

本番環境以外は、機密情報扱いにせずオープンな状態にしておく

そのままcredentials.yml.encを使う。
検証環境に機密情報がある場合は、閲覧編集権限を本番と揃えておけば、"開発","検証と本番"の2つの権限で分けて使うことができる。

qiita.com

$ rails credentials:show
HOGEHOGE: credentials
$ rails c
Running via Spring preloader in process 29960
Loading development environment (Rails 5.2.1)
irb(main):001:0> Rails.application.credentials.HOGEHOGE
=> "credentials"

rails-env-credentialsで環境ごとにcredentials.yml.encを用意

credentials.yml.enc機能をproduction,development,testなどで分割して使うことができる。
github.com

環境のconfigさえ用意すれば好きな環境のconfigが作れる。
各環境のmaster.keyは.gitignoreに追加されるので権限に合わせて配布すれば良い。

$ ls config/environments/hogehoge.rb
config/environments/hogehoge.rb
$ rails env_credentials:edit -e hogehoge
Adding config/master-hogehoge.key to store the master encryption key: *****************************

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-hogehoge.key

Ignoring config/master-hogehoge.key so it won't end up in Git history:

      append  .gitignore

New credentials encrypted and saved.
$ ls config/*hogehoge*
config/credentials-hogehoge.yml.enc   config/master-hogehoge.key

ただし、本番環境にログインできる全てのユーザーに見せたくない場合は、 サーバーにmaster.keyを置く際に権限を絞って配置しておく必要がある。

本番環境に環境変数を用意

credentials.yml.encには直接書き込みをせず、環境変数を読み込ませるようにする。
環境変数自体はユーザーごとに設定するなどしないと見ることができるので権限管理が必要になる。

環境変数は下記のような形で設定が可能である。

# config/database.yml
default: &default
  password: <%= ENV['DATABASE_PASSWORD'] %>

credentials.yml.encはdevelopmentだけなど使い分けをすることができる。

linuxの環境変数

環境ごとに設定し管理する。
全てのユーザーに見せたくない場合は、サーバーログイン自体の権限管理が必要になる。
また、編集履歴を取りたい場合は別途管理が必要になる。 環境変数 - ArchWiki

$ cat /etc/environment
HOGEHOGE="test"
$ echo ${HOGEHOGE}
test

dotenvやfigaroを使って各環境で環境変数の用意

環境ごとにrailsの環境変数をGemで設定管理できる。
ソースコードの管理に混ぜることもできるので、
コード管理と一緒に編集履歴を残すことができる

dotenv

github.com

$ cat .env
HOGEHOGE="dotenv"
$ rails c
Running via Spring preloader in process 28678
Loading development environment (Rails 5.2.1)
irb(main):001:0> require 'dotenv/load'
=> true
irb(main):002:0> ENV["HOGEHOGE"]
=> "dotenv"

figaro

github.com

$ cat config/application.yml
HOGEHOGE: "figaro"
$ rails c
Running via Spring preloader in process 28890
Loading development environment (Rails 5.2.1)
irb(main):001:0> ENV["HOGEHOGE"]
=> "figaro"
irb(main):002:0> Figaro.env.HOGEHOGE
=> "figaro"

AWSの環境変数管理

AWS Systems Managerを使うとAWS上で権限をコントロールし、暗号化したパラメータを受け渡しすることができる。
AWS上で権限管理や変更履歴を残すことができる

techblog.lclco.com

また、Amazon Elastic Container ServiceのDockerコンテナのアプリケーションを動かすサービスでは、
AWS Systems Managerを使うと復号化の処理をDockerの起動時タスクで行わせることもできる。

dev.classmethod.jp

また、ECSでは暗号化されていないが環境変数を使うことも可能になる。
本番のDockerに直接はいる機会がなければ問題ない。
(コンテナ系の運用があまりやったことがないので、わからない)

docs.aws.amazon.com

GCPの環境変数管理

CLOUD KEY MANAGEMENT SERVICEを使うとAWS Systems Managerと同じように使え、 Cloud Buildではビルド、テスト、デプロイ用にカスタム ワークフローの定義ができ、
CLOUD KEY MANAGEMENT SERVICEの復号化を起動時タスクで行わせることができる。
GCP上で権限管理や変更履歴を残すことができる(はず)。

暗号化されたリソースの使用  |  Cloud Build  |  Google Cloud

herokuの環境変数

herokuではコマンドで環境変数を追加することができる
権限コントロールが可能だが、細かいコントロールはできなきないかもしれない。

qiita.com

qiita.com

さいごに

最終的にはRailsから離れてしまった気がしますが、 Railsやcredentials.yml.encの範囲だけで考えず、 サービス全体からみて防げるような仕組みを選択できればといいのかなと思います。