こんにちは、Speee唯一の踏韻エンジニア@mncです。
ライフスタイルメディア事業でヌリカエというサービスのエンジニアをしています。
Speeeでは半期に一度SpeeeKaigiというエンジニアのお祭りを開催しています。
今回は、「本番データを安全,簡単に利用する」というテーマで話しました。
SpeeeKaigiについてはこちらを参考にしてください。
スライド
背景
本番データを使用したテストにはいくつものメリットがあると思います。
- ユーザー目線にたってテストができる
- 色々なパターンのデータでテストができる
- パフォーマンスの検証ができる
しかし本番データを利用するためには個人情報の保護が必要で、これが結構な手間だと感じていました。
作ったもの
そこでコマンド一発で指定したカラムをマスクしてダンプファイルを吐き出すmozaicというGemを作りました。
使い方
↓のようにYAML形式で「どのテーブルのどのカラムをどんなマスク方式でマスクするか」を記載します。
# tables.yml --- user: root # credentialsはENVから読み込めるようにする予定 host: localhost port: 3306 db: name: sample_development rdbms: mysql tables: - name: owners columns: - name: phone_number method: tel # Data Masking方式 - name: users columns: - name: mail method: email # Data Masking方式
その後、以下のようにコマンドを実行するとマスクしたダンプファイルが生成されます。
コマンド実行
$ mozaic tables.yml --path sample
吐き出されたダンプファイル
# テーブル定義のdumpは省略 INSERT INTO admin_users (id, sei, mei, email, tel, password_digest, status, created_at, updated_at) VALUES ('1', '###', '##', 'cfcd208495d565ef66e7dff9f98764da@example.com', '08000000000', '', '0', '2017-08-01 14:00:08 UTC', '2017-08-01 14:00:08 UTC'), ('2', '###', '##', 'c4ca4238a0b923820dcc509a6f75849b@example.com', '03-1000-0000', '', '0', '2017-08-01 14:00:08 UTC', '2017-08-01 14:00:08 UTC'), ('3', '#####', '####', 'c81e728d9d4c2f636f067f89cc14862c@example.com', '050-2000-0000', '', '0', '2017-08-01 14:00:08 UTC', '2017-08-01 14:00:08 UTC'), ('4', '###', '###', 'eccbc87e4b5ce2fe28308fd9f2a7baf3@example.com', '+813000000000', '', '0', '2017-08-01 14:00:08 UTC', '2017-08-01 14:00:08 UTC'), ('5', '###', '##', 'a87ff679a2f3e71d9181a67b7542122c@example.com', '0354000000', '', '0', '2017-08-01 14:00:08 UTC', '2017-08-01 14:00:08 UTC'), ('6', '####', '####', 'e4da3b7fbbce2345d7772b0674a318d5@example.com', '090-5000-0000', '', '0', '2017-08-01 14:00:08 UTC', '2017-08-01 14:00:08 UTC'); INSERT INTO owners (id, sei, mei, sei_kana, mei_kana, tel, email, address, created_at, updated_at) VALUES ('1', '######', '######', '###', '##', '08000000000', 'cfcd208495d565ef66e7dff9f98764da@example.com', '', '', ''), ('2', '##', '####', '###', '####', '03-1000-0000', 'c4ca4238a0b923820dcc509a6f75849b@example.com', '', '', ''), ('3', '######', '######', '##', '###', '+812000000000', 'c81e728d9d4c2f636f067f89cc14862c@example.com', '', '', ''), ('4', '#####', '######', '##', '###', '090-3000-0000', 'eccbc87e4b5ce2fe28308fd9f2a7baf3@example.com', '', '', '');
このGemの特徴
カラムごとにData Masking方式を切り替えられること
デフォルトで以下のData Masking方式が用意されています。
これにより、より本番のデータに近い形式でマスクできます。
また、DBのUnique制約も回避できます。
方式 | マスク方法 |
---|---|
tel | 電話番号の体裁を保ったままマスクする |
メールアドレスの体裁を保ったままマスクする | |
shuffle | 各レコードの順番を入れ替える |
blackout | 任意の文字、数字で埋める |
適切なData Masking方式がなかったら、ユーザーが自分でRubyのマスク処理を行えること
maskメソッドとコンストラクタを持つRubyのクラスを指定ディレクトリに格納し、YAMLの設定ファイルにクラス名を小文字で記載すると独自のマスク処理を行えるようにしました。
module Mozaic::MaskMethod::Plugin class SampleMask def initialize(records, column_name); ;end def mask; ;end end end
まとめ
基礎の部分の実装はできたので、今後は以下の対応を行いOSS化しようと思います。
- クレデンシャルをENVから読み込めるようにする
- 大規模データでも利用できるようにする
- 独自のマスク処理をPluginで追加できるようにする
- PostgreSQL対応
反省
今回初参加だったためSpeeeKaigiの雰囲気がわからずお硬いテーマで話してしまいました。
みんな遊び心たっぷりの発表で非常に楽しかったため、次回は僕が大好きなHipHopとラップをテーマに韻を踏みながら発表しようと思います。