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
33k
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
型安全なDrag and Dropの設計を考える
yudppp
5
1k
未知のプログラミング言語にChatGPTと共に挑む
yudppp
0
520
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.6k
ISUCON向けのツールを作った話 / isutools
yudppp
1
330
Webサービス開発に必要な統計学入門 / study of statistics for web developers
yudppp
1
360
メジャーな Live Reloaderの違いをちゃんと調べて見た / Compare major live reloader of Go
yudppp
1
2k
今年お世話になったnpm module
yudppp
1
960
Other Decks in Technology
See All in Technology
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
2
410
2026TECHFRESH畢業分享會 - Lightning Talk - 打造精準高效的 MCP 設計模式與測試實務
line_developers_tw
PRO
0
720
自律型AIエージェントは何を破壊するのか
kojira
0
150
EventBridge Connection
_kensh
5
690
Dario Amodi『Policy on the AI Exponential』を理解する
nagatsu
0
210
【Cyber-sec+】経営層を"動かす"ための考え方
hssh2_bin
0
120
2026TECHFRESH畢業分享會 - Lightning Talk - 資料也要 CI/CD? 用 Airbyte 自動化資料同步
line_developers_tw
PRO
0
720
Oracle AI Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
6
1.9k
Agentic Web
dynamis
1
200
非エンジニアがClaudeと挑んだ「1ヶ月間プロダクト30本ノック」
askokc
0
270
2026TECHFRESH畢業分享會 - AI 時代的人生存檔點
line_developers_tw
PRO
0
730
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development with AI-DLC
yoshidashingo
0
170
Featured
See All Featured
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
230
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
600
Abbi's Birthday
coloredviolet
2
8k
Tell your own story through comics
letsgokoyo
1
950
How GitHub (no longer) Works
holman
316
150k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
GitHub's CSS Performance
jonrohan
1033
470k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Mobile First: as difficult as doing things right
swwweet
225
10k
A Soul's Torment
seathinner
6
2.9k
Visualization
eitanlees
152
17k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
570
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)