jsでEncrypted Secretsライクなライブラリを実装した

Webアプリケーションを開発していく中でAPIキーやパスワードなどの機密情報をどのように管理していくかは常に頭を悩ます課題となっています。 これまで機密情報は環境変数を使用する、設定ファイルをGit管理しないなどの方法を取ることが多かったのではないでしょうか。

機密情報の管理方法として、Ruby on Railsではバージョン5.1からEncrypted secretsという解決策を打ち出しています。 Encrypted secretsは機密情報を含むファイルを暗号化した状態でバージョン管理システムにコミットし、復号化のためのキーのみを環境変数やVCS管理外のファイルで保存する方法を取ります。

Rails 5.1: Loving JavaScript, System Tests, Encrypted Secrets, and more | Riding Rails

暗号化をしているとは言え機密ファイルをGit管理するのはよくないケースはあるのかもしれません*1が、殆どのケースでは「なんで今までこれを採用しなかったのか」と思うほどの便利に使っています。

今回はRailsで便利と感じたEncrypted secretsの仕組みをReact Nativeで使用することを見据えてjs実装してみました。 リリースノートを見るとこの機能はsekretsというGemを参考に開発を進められたようなので、私もsekretsのコードを参考にしています。

github.com

成果物

Githubにあげていますが、現状Productionでは使用していません。 標準入力を取得する部分でOS依存のコードとなっているためWindowsでは動作しないです。

GitHub - kuranari/js-secrets: js-secrets is command line tool and library used to securely manage encrypted files and settings in your javascript applications and git repositories.

INSTALL

$ npm install -g js-secrets

How to use

setup

$ js-secrets setup
created: .secrets.key
created: secrets.yml.enc

js-secrets setupでkeyファイル.secrets.keyと暗号化された機密ファイルsecrets.yml.encが生成されます。

read

$ js-secrets read
awesomeValue: 42

js-secrets readで機密ファイルを復号化し、標準出力に表示します。

write

$ echo 'hello: world' | js-secrets write
$ js-secrets read
hello: world

標準入力を暗号化し、secrets.yml.encに保存します。

edit

$ EDITOR=vi js-secrets edit

環境変数(EDITOR)で指定したエディタで機密ファイルを編集します。 編集後は自動で暗号化されsecrets.yml.encファイルに保存されます。

.secrets.keyはgitignoreに追加する必要があります。

ファイルからの読み込み

const { load, fetchKey } = require('js-secrets');

const settings = load('./secrets.yml.enc', fetchKey({ path: './.secrets.key' }))
console.log(settings);

感想

  • sekretsが.gitignoreの更新や、keyファイルの探索、Capistranoのタスクを含んでいるなど、細かいところに気の利いたライブラリと感じました。
  • 自分のライブラリ方はと言うと、コマンドラインオプションへの対応やら、jsファイルで.encファイルや.keyファイルを明示しなければならないなど自分自信で「このライブラリのAPIイケてないな」と思う部分も多いです。
  • READMEが圧倒的に足りなく、OSSとして普及させるための技術以外のハードルがあるなと思っています
  • とは言え、飽きる前に一通りの機能を実装してソースとブログ公開ができたのは技術的に一歩踏みだせた感があります🎉

*1:「本番環境のDBのパスワードは特定の人しか閲覧できないようにする」等