Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Row Level Securityはマルチテナントの銀の弾丸になりうるのか / Row Le...
Search
yudppp
August 31, 2019
Technology
34k
23
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Row Level Securityはマルチテナントの銀の弾丸になりうるのか / Row Level Security is silver bullet for multitenancy?
builderscon 2019の発表資料です
yudppp
August 31, 2019
More Decks by yudppp
See All by yudppp
開発者にもコーディングエージェントにも働きやすい環境を整える
yudppp
0
90
型安全なDrag and Dropの設計を考える
yudppp
5
1k
未知のプログラミング言語にChatGPTと共に挑む
yudppp
0
530
SaaSフロントエンド開発の現場で求められる技術 / Technologies for SaaS Frontend Development in the Field
yudppp
2
280
2019年 HRBrainの技術的挑戦 / hrbain technology challenge 2019
yudppp
3
1.5k
Web開発を支えるマイグレーションツールについて / sqldef introduction for psql users
yudppp
2
3.7k
ISUCON向けのツールを作った話 / isutools
yudppp
1
340
Webサービス開発に必要な統計学入門 / study of statistics for web developers
yudppp
1
360
メジャーな Live Reloaderの違いをちゃんと調べて見た / Compare major live reloader of Go
yudppp
1
2k
Other Decks in Technology
See All in Technology
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
110k
ヘルスケア領域における AI 活用と その安全性担保のための取り組み (Leveraging AI in Healthcare and Our Efforts to Ensure Its Safety) - Google I/O Extended Tokyo 2026, July 11, 2026
zettaittenani
0
420
シンガポールで登壇してきます
yama3133
0
240
関数型の考えを TypeScript に持ち込んで、テストしやすい純粋関数を増やす / Pure at the Core, Effects at the Edge: Bringing Functional Thinking into TypeScript
kaminashi
2
130
Amplify Gen2でbackend.tsにCDKを定義する/しない事によるCDKの挙動の違いとユースケース
smt7174
1
390
AICoEでAIネイティブ組織への進化
yukiogawa
0
190
最適な自走を最小限の支援で — M&Aで拡大する組織で少人数SREが挑んだ1年 / SRE NEXT 2026
genda
0
1.4k
End-to-Endで考える信頼性 —LINEアプリにおけるクライアント開発×SRE連携の実践
maruloop
4
4.5k
「ちゃんとやっている」は独りよがりだった ― 不安に寄り添うインシデント対応へ / Towards incident response that addresses anxieties
chmikata
1
5.9k
ゴールデンパスは敷いただけでは道にならない ─ 企画部門のエンジニアが技術標準を事業価値に変えるまで
mhrtech
1
200
企業でAWS Organizationsを動かすための組織設計の考え方
nrinetcom
PRO
1
110
人を動かすのは時間ではなく、納得感 〜新任EMが入社3ヶ月、組織を2回変えた話〜
kakehashi
PRO
3
270
Featured
See All Featured
Done Done
chrislema
186
16k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.7k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.3k
The browser strikes back
jonoalderson
0
1.4k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.6k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Deep Space Network (abreviated)
tonyrice
0
230
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
300
Building an army of robots
kneath
306
46k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
230
Transcript
RowLevelSecurityは マルチテナントの 銀の弾丸になりうるのか #builderscon 2019 (20 min)
⾃⼰紹介 @yudppp 株式会社HRBrain CTO 好きな⾔葉: 冪等性 Go / TypeScript /
React ◦△□ - https://blog.yudppp.com/ いつかSaaSのDevカンファレンス開くのが夢
⽬標評価管理クラウド
導⼊企業500社以上の HRTechのSaaSを 週2リリースのペースで 運⽤・改善を ⾏なっています。
テナントとは • SaaSを利⽤する組織の単位のこと • HRBrainだと企業のこと • HRBrainだと企業の中にユーザーがいる • テナント間でのデータをやりとりはしない
SaaSのアーキテクチャ
アーキテクチャ • シングルテナントアーキテクチャ(ASP) • マルチテナントアーキテクチャ(SaaS)
シングルテナントアーキテクチャ اۀ" اۀ# اۀ$ اۀ"͚ "1αʔόʔ اۀ"͚ %# اۀ"͚ Πϯϑϥ
اۀ#͚ "1αʔόʔ اۀ#͚ %# اۀ#͚ Πϯϑϥ اۀ$͚ "1αʔόʔ اۀ$͚ %# اۀ$͚ Πϯϑϥ
シングルテナントのメリット • ⽐較的安全 • 特定のテナントでアクセスが増えても場合に 他の会社は影響を受けない • DB障害時の影響範囲がテナントごとになる
シングルテナントのデメリット • サーバーが完全に分かれているのでデプロイ をテナントごとに⾏う必要がある • テナントごとにサーバーを⽤意するためコス トがかかる • 単価がすごく⾼く、リリース頻度が少ないも のであれば成り⽴つ
マルチテナントとは • ⼀つのシステムで複数利⽤者組織の情報やア プリケーションを管理すること ࢀߟ4BB4͚4-"ΨΠυϥΠϯܦࡁ࢈ۀল IUUQXBSQEBOEMHPKQJOGPOEMKQQJEXXXNFUJHPKQDPNNJUUFFNBUFSJBMTEPXOMPBEpMFTHDKQEG
マルチテナントアーキテクチャの種類 • クラウド内での単純な仮想化により、ハード ウェアのみを共有 • 1つのアプリケーションで、テナントごとに 異なるデータベースを使⽤ • 1つのアプリケーションでデータベースを共 有
(最も効率的な真のマルチテナンシー) ࢀߟ8FCΞϓϦέʔγϣϯΛϚϧνςφϯτܕ4BB4ιϦϡʔγϣϯʹม͢Δ IUUQTXXXJCNDPNEFWFMPQFSXPSLTKQDMPVEMJCSBSZDMNVMUJUFOBOUTBBTJOEFYIUNM
1つのクラウドサーバーに全ての企業 اۀ" اۀ# اۀ$ اۀ"͚ "1αʔόʔ اۀ"͚ %# اۀ#͚ "1αʔόʔ
اۀ#͚ %# اۀ$͚ "1αʔόʔ اۀ$͚ %#
1つのクラウドサーバーに全ての企業のメリット • 1テナントごとのスケールはしやすい • アプリケーションのリリースがテナントごと にできる(テナントごとに異なるVersionのア プリケーションがありえる) • 特定のテナントでアクセスが増えても場合に 他の会社は影響を受けにくい
1つのクラウドサーバーに全ての企業のデメリット • テナントごとにアプリケーションサーバーや データベースを個別に⽤意する必要がありコ ストが⾼い • デプロイをテナントごとに⾏う必要がある。 • こちらをシングルアーキテクチャに含めてし まう場合もある
1つのアプリケーションで異なるDBを使⽤ اۀ" اۀ# اۀ$ اۀ"͚ %# "1αʔόʔ اۀ#͚ %# اۀ$͚
%#
• 物理データベースは1つで論理データベース を分けているケースが多そう • アプリケーションは全てのテナントで同じ サーバーを利⽤する • DBを⽔平分割している状態に近いのでDB⽬ 線ではスケールさせやすい 1つのアプリケーションで異なるDBを使⽤のメリット
• DBのスキーマ変更のマイグレーションをテナ ントごとに⾏う必要がある 1つのアプリケーションで異なるDBを使⽤のデメリット
1 つのアプリケーションでDBを共有 اۀ" اۀ# اۀ$ "1αʔόʔ %#
• 最も効率的な真のマルチテナンシー • スキーマの変更のマイグレーションの更新が ⼀回で済む • インフラコストが⼀番安くなる 1 つのアプリケーションでDBを共有のメリット
• DBに障害が起きた時に全テナントが影響を受 ける • アプリケーションが複雑になりやすい • セキュリティに不安がある 1 つのアプリケーションでDBを共有のデメリット
どんな不安があるのか • あるテナントが別のテナントのデータを⾒れ てしまう可能性がある(data violation)
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ こんな感じのusersテーブルがあった時に
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ 本来Where句を指定するところを 4&-&$5 '30.VTFST 8)&3&UFOBOU@JElձࣾ#z
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ 本来Where句を指定するところを 4&-&$5 '30.VTFST 8)&3&UFOBOU@JElձࣾ#z
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ Where句を指定忘れてしまうと 4&-&$5 '30.VTFST
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ Where句を指定忘れてしまうと 4&-&$5 '30.VTFST ͪΖΜ શͯͷձࣾͷ ϝϯόʔใ͕
औΕͯ͠·͏
複雑なアプリケーションになると 絶対起きないとはいえない
これらのメリデメを受けて 弊社のケースについて考える
導⼊企業500社以上の HRTechのSaaSを 週2リリースのペースで 運⽤・改善を ⾏なっています。 弊社のケース(再訂)
ビジネスモデル的に 100社導⼊しただけでは 会社が成り⽴たない
マルチテナントアーキテクチャ(再訂) • クラウド内での単純な仮想化により、ハード ウェアのみを共有 • 1つのアプリケーションで、テナントごとに 異なるデータベースを使⽤ • 1つのアプリケーションでデータベースを共 有
(最も効率的な真のマルチテナンシー)
リリース後も 継続的に機能追加によって スキーマ変更が必要に なることがわかっていた
マルチテナントアーキテクチャ(再訂) • クラウド内での単純な仮想化により、ハード ウェアのみを共有 • 1つのアプリケーションで、テナントごとに 異なるデータベースを使⽤ • 1つのアプリケーションでデータベースを共 有
(最も効率的な真のマルチテナンシー)
⽬標や評価の情報は もちろんとても⼤事 (⽬標が他の会社に漏れたら⼤問題)
マルチテナントアーキテクチャ(再訂) • クラウド内での単純な仮想化により、ハード ウェアのみを共有 • 1つのアプリケーションで、テナントごとに 異なるデータベースを使⽤ • 1つのアプリケーションでデータベースを共 有
(最も効率的な真のマルチテナンシー)
全ての選択肢が なくなってしまった、、、
何かを犠牲にするしか、、
事例について 調べて⾒た
Bit Journeyさん • apartment gemを利⽤ • 1つのアプリケーションで、テナントごとに 異なるデータベースを使⽤した場合に便利に なるライブラリー? ࢀߟSBJMTENͰϚϧνςφϯτɾΣϒΞϓϦͷΛ͠·ͨ͠
IUUQTHGYIBUFOBCMPHDPNFOUSZ
SmartHRさん • apartment gemからCitus Cloud(DBaaS)へ移 ⾏ • マイグレーションは⾟くなりがち • なるほど:thinking:
ࢀߟͭΒ͘ͳ͍ϚϧνςφϯγʔΛٻΊͯશͯݟͤ·͢ʂ4NBSU)3σʔλϕʔεҠߦϓϩδΣΫτͷཪଆ IUUQTTQFBLFSEFDLDPNQVSJOUBJCVJMEFSTDPO
Viewを使ってマルチテナントを実現する⽅法 • 最も効率的な真のマルチテナンシーをViewを使って実現 する • テナント×テーブルごとにViewを作り権限管理を⾏う。 • SELECT/UPDATE/DELETEに対してはViewから⾏う • INSERTはオリジナルのテーブルに⾏う必要があり安全
かどうかはアプリケーションの実装依存になってしま う。
他にも⾊んな⼈に聞いたり、 調べたりしているうちに ⾒つけた
我らの銀の弾丸
Row Level Security
Row Level Securityとは • データベーステーブル内の⾏へのアクセスを 制御できる • OracleやPostgreSQL(9.5以上)やSQL Server(13.x以上) などで実装されている
• (以降RLSとする。)
権限ごとにRoleを作って දऔక Ϧʔμʔ ϝϯόʔ શͯݟ͑Δਓ ࣗͷ νʔϜϝϯόʔͷΈ ݟ͑Δਓ ࣗͷใͷΈ ݟ͑Δਓ
දऔక ։ൃϦʔμʔ ։ൃϝϯόʔ Ӧۀ こんな感じのusersテーブルがあった時に
දऔక Ӧۀ 代表取締役のロールでアクセスすると 4&-&$5 '30.VTFST ։ൃϦʔμʔ ։ൃϝϯόʔ
දऔక Ӧۀ 代表取締役のロールでアクセスすると શͯݟ͑Δ 4&-&$5 '30.VTFST ։ൃϦʔμʔ ։ൃϝϯόʔ
දऔక Ӧۀ 開発リーダーのロールでアクセスすると 4&-&$5 '30.VTFST ։ൃϦʔμʔ ։ൃϝϯόʔ
දऔక Ӧۀ 開発リーダーのロールでアクセスすると ։ൃϝϯόʔͷ ใͷΈݟ͑Δ 4&-&$5 '30.VTFST ։ൃϦʔμʔ ։ൃϝϯόʔ
雑なQuery叩いても 権限範囲のデータしか ⾒えなくて安全
マルチテナントに応⽤していく
テナントごとにRoleを作る اۀ" اۀ"ͷใͷΈ ݟ͑Δ اۀ# اۀ#ͷใͷΈ ݟ͑Δ اۀ$ اۀ$ͷใͷΈ ݟ͑Δ
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ こんな感じのusersテーブルがあった時に
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ 会社Bのロールでアクセスすると 4&-&$5 '30.VTFST
ձࣾ" ձࣾ# ձࣾ# ձࣾ$ 会社Bのロールでアクセスすると 4&-&$5 '30.VTFST ձࣾ#ͷϝϯόʔͷ ใͷΈݟ͑Δ
これは安⼼!
Tableの実体⾃体は 全てのテナントで共通なので マイグレーションも楽々
実際に導⼊してみました (PostgreSQL v10.4)
最初の実装や検証が ⼤変そうだったけど なんとか導⼊しました。 (リリース三ヶ⽉前に⾃分以外のメンバーが1ヶ⽉くらいで諸々対応してくれた記憶)
どうやっているか① • 全てのテーブルにcompany_idのカラムを⽤意 • サブドメインをテナントごとに追加する • Ex) mosquitone.hrbrain.jp
どうやっているか② • テナントごとにロールを⽤意 • RLSを利⽤するテーブルに下記のPolicyを追加 • テナントごとに別のコネクションを使う
そしてリリース1ヶ⽉半前
⼤量のデータを⼊れて 確認していた時に 問題が発覚した
GET /usersheets 1.8[sec]
pprofで諸々確認 (GoのPeformance計測ツール)
DBアクセスしている層が 想定より数倍遅い
:thinking:
⼀度試しにRLSを 使わないでみたら
レイテンシーが4分の1に
RLSを⼊れたことによって 起きていることはわかった
ただ安全第⼀ RLSをやめる訳にはいかない
N+1とIndex周りの修正をして 1秒以内にできたのでリリース
ただし根本解決はされないまま
リリース後の落ち着いた タイミングで再挑戦
検証結果
コネクションの使い⽅ • RLSを利⽤していない時は全てのコネクショ ンプールをまとめて管理していた。 • RLSを利⽤時はテナントごとにロールを作っ ていた結果、コネクション管理が煩雑になっ ていて、そこでオーバーヘッドが⽣じてい た。
リクエストごとにコネクションを張るように変更 • Middlewareでコネクションを発⾏して、 contextに詰める(本当はcontext使いたくない) • リクエストの終了時にClose
リクエストごとにコネクション貼ってみた結果 • 遅かった特定のAPIで調査 • 中央値、平均値を⾒る限りすごく速くなった。 • 速くなったが詰まる時は詰まってそう。 NFBO λΠϧ λΠϧ
λΠϧ NBY #FGPSF NT NT NT NT T "GUFS NT NT NT NT NT
テナントごとのロールについて • RLSを適応したい全てのテーブルに下記のような POLICYを追加していた。 • current_userを⽤いて、dbのユーザーをどの⾏に 対して権限があるかを判断していた。
Indexについて • テーブルに下記のUNIQUE INDEXを貼っていた • リクエスト⾃体は • 叩いた時にindexが効いていなかった。
EXPLAIN結果 • 全件検索してからFilterしている、、
EXPLAIN結果 • company_idを必ずつけるようにすれば問題起きなかった。
USINGしている中⾝がよくない • ロール名に直接company_idではなく prefixをつけていたそのせいで⾃動で INDEX効いていなかった • もともと数字だけでやろうとしていたが ロール名に数字始まりはInvalidだった。
ロールの作り⽅を変更した • 下記のようにcurrent_settingを利⽤したPOLICYを 作成すればテナントごとのロールが不要だった。 • またこの場合はリクエストごとに予めテナントを セットしておく必要がある
EXPLAIN結果 • ちゃんとINDEXかかった! • どちらにしてもcompany_id始まりのINDEXを貼るべき
クエリーパフォーマンス • ある簡単なAPIを並列で実⾏した時に1.4倍くらい時間 がかかるようになっていた λΠϧ λΠϧ λΠϧ 3-4ͳ͠ NT NT
NT 3-4͋Γ NT NT NT
結論
銀の弾丸ではなかった。
マルチテナントにRLSを使うメリット • 安全に「最も効率的な真のマルチテナン シー」が実現できた。
マルチテナントにRLSを使うデメリット • コネクションの管理が煩雑になってしまっ た。 • パフォーマンスが多少悪くなる。 • 導⼊事例が少なく検証しないとわからないこ とが多い。
この先使う上での不安事項 • DBを⽔平分割していく必要が出た場合にどうするか • マイクロサービスにしてDBも垂直分割していく想 定はあるが、それでも増えた時にどうするか • 今利⽤されている⼈数の10倍、20倍のテナントが ⼊ってきた場合に問題なくRLSが動くのか •
テナントをまたがるユーザーを作りたくなった時にど うするか
まとめ • SaaS作る時にパフォーマンスをそこまでシビ アに作る必要がないものを安全に作りたいの であればオススメ • データが増えた時にまた別の対策が必要
参考資料 • SaaS 向け SLA ガイドライン - 経済産業省 (http://warp.da.ndl.go.jp/info:ndljp/pid/ 11094748/www.meti.go.jp/committee/materials/downloadfiles/g80207c05j.pdf)
• マルチテナント SaaS データベース テナント パターン(https://docs.microsoft.com/ja- jp/azure/sql-database/saas-tenancy-app-design-patterns) • Web アプリケーションをマルチテナント型 SaaS ソリューションに変換する(https:// www.ibm.com/developerworks/jp/cloud/library/cl-multitenantsaas/index.html) • PostgreSQL: Documentation: 11: 5.7. Row Security Policies (https:// www.postgresql.org/docs/current/ddl-rowsecurity.html) • PostgreSQLのRow Level Securityを使ってマルチテナントデータを安全に扱う - HRBrain blog (https://times.hrbrain.co.jp/entry/postgresql-row-level-security)