メルペイ社内ツールのお話

Merpay Advent Calendar 2019の5日目です。

メルペイ社内ツールのお話をしようと思います。
“個人事業主の集まりかよ”と評されることもある、メルペイソリューションチームの一員である、vvakameさんが開発・管理しているツールやシステムの紹介をします。今まであんまり外に出したことがなかったので。
mercari/datastoreなどのオープンになっているものや、OSSへのPRなどの社外からも観測可能なものは今回は割愛します。

そもそも、ソリューションチームとは?

vvakame(TypeScript, Go, GraphQLなど)、sinmetal(GCPほぼ全部 最近Spanner)、orfeon(Dataflowなど)の3名で構成される、何かを適当にいい感じにするチームです。
メンバー募集中なので興味がある方は適当にアポイントを取ってください。Job Descriptionとかも特に用意されていない…!

他に、エキスパートチーム(主にコミュニティ活動など社外活動を行う)と、アーキテクトチーム(主に真面目に社内の問題を検討したり設計を行う)があり、よく混同されます。

siege

用途・実績

データを暗号化して保存するためのソリューションが必要でした。これは、万一の流出の際に被害を抑える意味合いもありますし、開発者が運用に際してセンシティブな情報に極力関わらずに仕事をするためにも重要です。
当初、ある個人情報を管理するマイクロサービスのスループットが思わしくなく、それを改善するために開発されました。
現在、複数のマイクロサービスで利用されていて、今後も導入するマイクロサービスが増えそうです。

名前小噺

読み方は シージ です。siegeの意味を調べると“包囲作戦”などとなっています。
データをガッチリ守るための包囲ということですね!落ち着いて考えるとデータは守られる側で、包囲される側ではないと思われますが、冷静になってはいけません。

本当はRainbow Six Siegeというゲームの実況動画を見ていた時期があったのでそこから取りました。本人の腕前はソロキャンペーンがクリアできなくて詰まる程度の腕です。

解説

siege(的な何か)が必要である!という声があがったのはメルペイのリリースも迫りつつある2018年11月末。Google Cloud KMSを利用してのデータのencrypt/decryptが検討されていましたが、扱うべきデータ量が多く、レイテンシに問題がありました。これはアプリケーションの性質とGoogle Cloud KMSの組み合わせ方が悪かったことに起因しています。Google Cloud KMSは全データが通過するようなパイプラインではなく、少量のデータを処理する用途であるためです(※当時のログによるとQuotaは600/min 現在は60,000/minまで増やせるらしいので状況が変わっているかもしれません)。
そんなわけで運用上色々と課題があるため、独自のencrypt/decryptを行うソリューションを模索することになりました。そこで白羽の矢が突き刺さったのがソリューションチームで、ライブラリやフレームワークの開発を趣味としている僕でした。

当初、データ保護専用のマイクロサービスを開発する案もあり、siege-clientとsiege-serverという構成を考えていた気がします。
ところが、設計を検討している時に数々の短時間で解決が難しく、無理をすると負債化しそうな課題があがり、最終的にはHashiCorp Vaultとそれをwrapするライブラリであるsiege-clientという構成になりました。
セキュリティ上の問題はHashiCorp Vaultが持っている機能で概ね解決できます。

API設計的には、Google Cloud KMSからKeyRingなどを省いたものにしています。これは、Google Cloud KMSからの移行を容易にするためでした。
が、社内の使い方を見てるともっと単純なシリアライザっぽく使えたほうがわかりやすく便利だった気がします。
また、デフォルトの実装では一旦encrypt/decryotに必要なKeyを取得した後はそれをキャッシュし、完全ローカルで動作するようになっています。
siegeのバックエンドとして動作検証をバッチリ行ったのはHashiCorp Vaultだけですが、他にGoogle Cloud KMSを使うもの、完全にインメモリで動くもの(主にテスト用)も一応作ってあります。
他に社内のセキュリティ規格を満たすため、利用する暗号化規格の確認やKey Rotateの仕組みの実装を行いました。

利用しているHashiCorp Vaultの機能をざっくり解説します。

  • Namespaces (Enterprise版のみ)
    • マイクロサービスごとに独立した名前空間を利用
  • Transit Engine
    • encrypt/decryptを行うエンジン
  • KV Secrets Engine v2
    • いわゆるデータストレージ的なもの
    • CAS(Check-And-Set operation)のサポートが嬉しい

これらの機能を組み合わせて動作します。

  1. ローカルでの処理に使うData KeyをKVから取得
  2. 存在しなかったらTransitにData Keyを作成してもらい保存
  3. encrypt/decryptの要求が来たら、ローカルでいい感じに処理する

という感じですね。
実際はもうちょっと異常ケースや分散環境での整合性確保のための考慮がありますが、だいたいこんなものです。今のところ、問題が発生したりせず、Issueなどもほぼ立たず平穏です。
最初にキャッシュを作り後はローカルで動作する機能は性能面や運用面で良い面があり、実際にストレージ側でトラブルが起こった時もお客様に影響がない範囲に抑えることができました。新規Podの立ち上げができなくなった報告を聞いた時はかなり焦りました…。
他にも、orfeonさんがsiegeで処理されたデータをまとめてdecryptするためのDataflow Templateを社内ソリューションとして整備してくれました。大量のデータを処理したいときにすべてをHashiCorp Vaultに投げつけるのは厳しいので、この面でも良い方向に働きました。siegeはGo製ですが、orfeonさんは諸々の処理をJavaで書き起こしたそうです。大変だなぁ…。

僕がsiege-clientを作成し、その後プロダクト開発のみんながこれを使い続けていられるのには、2つのチームの貢献が非常に大きいです。

まず1つ目がセキュリティチーム。僕はセキュリティについては専門ではないですが、encrypt/decryptのソリューションを作成することになりました。そこで、セキュリティチームがメンテしている社内セキュリティ標準やガイドラインに沿って技術選定や確認を行い、次いでDesign Docのレビューや、Goコードの実装方法のレビューをも依頼することができ、安心して作業をすすめることができました。
セキュリティチームは社内から非常に気楽に相談をすることができ、協力もしてくれる非常に心強く頼もしい存在なのです。

そして2つ目がSREの方々。HashiCorp Vaultの運用(やHashiCorp社との契約のハンドリングなど)を行ってくれています。僕はライブラリ作って提供するだけで済んでいるのは、彼らが毎日(今日も!)、サービスのお守りをしてくれているからなのです。

そんなメルカリ・メルペイ社の素晴らしいチームの支援のもと、siegeは今日も元気に暗号化したり復号したりしているのです。
たぶん、僕やあなたの個人情報も。

gchammer

用途・実績

プロダクト開発と運用を行うにあたり、本番のDB(我々の場合主にGoogle Cloud Spanner)にアクセスしたい場合があります。
メルペイ社は金融サービスを提供しているため、本番のDBに直接アクセスするというのはおっかないですし、格納されている個人情報も可能な限り参照したくありません。
そこで、DBへのアクセスを可視化し、クエリの内容をレビューした上で実行し、さらにそのログも取りたい… というところで、DML申請ツールであるgchammerが生まれました。

名前小噺

sinmetalがつけました。読み方は じーしーはんまー です。
Spannerはスパナ(工具)なので、工具繋がりで、あと本番DBをボーン!!!!!とぶっ叩くのでハンマーにしました!gcはGoogle Cloudです!!
って言ってました。物騒だなぁ。

解説

チーム内で実行するDMLをレビューして問題がないか確認の上、SREチームに実行を依頼し、実行結果を何らかのセキュアな方法で開発者に返す。そんな辛い運用が常態化していたため、これを解消しもっと前向きな仕事に使う時間を増やしたい!という話だった気がします。
人間によるオペレーションは一定の割合でミスが発生しますし、障害発生時にやり取りのコストが嵩むのは精神的にもよくありません。
これを解決するため、sinmetalと僕でいい感じのアプリを作りました。

実際の画面はこんな感じ。

f:id:vvakame:20191204202007p:plain
gchammerの画面

ちょいちょい不便な要素が見つかるたびに相談が来て、改善が続けられています。
実装的にはGraphQLで組まれていて、サーバ側はAppEngine+gqlgenで動いています。クライアント側はReactとApolloです。Spanner周りや権限チェック周りのコードはsinmetalがガッツリ書いております。
ある種僕の遊び場の側面もあり、新しいことはこのプロジェクトか、技術書典公式Webのどちらかが実験台になっています。

このプロジェクトでもセキュリティチームのお世話になっていて、彼らに侵入テストなどを行ってもらった結果、いくつかの改善点を見つけてもらうことができました。
ほんま頼りになるな!セキュリティチームがいる会社最高!

あと、各種本番DBにgchammerからアクセスするための権限管理の運用はterraformで行われています。そのため、gchammer利用開始のための手続きもGitHub上でPRを出せば済むようになっています。
ほんま便利やな!SREやマイクロサービスプラットフォームチームがいる会社最高!

user-tkool

用途・実績

アプリ開発時に、テスト用のユーザを開発環境や検証環境で作るのが辛い!めんどくさい!手順がわからない!という問題がありました。
実際、AccessTokenやらが欲しくても、それを作る手順は煩雑で、社内wikiにいくつも記事がありますし、ノウハウを知っている人を探して質問攻めにしたこともあります。
これを簡単に行えるようなツールがあれば、多くの人が楽をできることは明白です。

名前小噺

某R○Gツクールの名前にあやかって、user-tkoolでいいんじゃない?となってこの名前です。よって、読み方は ゆーざーつくーる です。
最近はnon-native Japaneseの人には発音が難しいし、つくる(TUKURU)とツール(TOOL)も結びつきにくいので、若干改名の機運を感じないでもない!

解説

当初の立ち上げメンバーがいたのですが、残念ながら退職してチームを離れてしまったので、現在は僕とQAチームのokamotokさんが引き継いで開発を行っています。
やはり実際に苦しんでいる人が絡むとドンドン追加機能案が出てきてすごい…!
僕はリファクタリングやレビューがメインで、新規開発はokamotokさんがバンバンPRを投げて来てくれます。圧倒的当事者意識を感じる…!

user-tkoolは利便性の観点から、Slackコマンドとして実行されています。誰かが使っている様子を見ると、他の人も使い方がわかります。

f:id:vvakame:20191204202208p:plain
user-tkoolでユーザを作ったりしている様子

実際に使っている様子はこんな感じです(微妙な情報が多いので色々隠しています)。アプリケーションとかで利用するのに十分な情報が含まれているので、任意の状態のユーザを作り出してテストに利用することができるそうです。
メルペイでは本人確認のための方法も複数あり、ポイントも複数形式あったりしていますが、user-tkoolでは色々なオプションが提供されていて、任意の状態を作り出すのが今までに比べると格段に楽になりました。

“こうすればできる”というドメイン知識を蓄え、更新し続けていたokamotokさんの力が光ります。

もちろん、このツールは開発環境と検証環境でしか動きません。それらの環境でのみ利用可能な認証方法などの基盤を整備しているIDプラットフォームチームの仕掛けのおかげで比較的簡素に実装ができています。

また、セキュリティチームとSREチームについても、user-tkoolではご迷惑をかけたりサポートの手間をかけていただいています。ありがとうございます本当に!

終わりに

メルペイではミッション・バリューに共感できるソリューションなエンジニアを募集しています。我こそは!という方はソリューションチームの誰かに適当にアポイントを取ってみてください。

明日は @miisan さんによるメルペイのQA(品質保証)チームについての記事となります。お楽しみに!