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
Go×RLSで複数テナントのデータを安全に扱う/secure-data-access-with...
Search
Sh0He1666
October 02, 2023
Programming
0
950
Go×RLSで複数テナントのデータを安全に扱う/secure-data-access-with-go-rls-in-multi-tenant-environment
Sh0He1666
October 02, 2023
Tweet
Share
More Decks by Sh0He1666
See All by Sh0He1666
ログ調査で分からなかった原因が、New Relicのトランザクションで一瞬で解決した話
sh0he1666
0
10
Other Decks in Programming
See All in Programming
バッチ処理を「状態の記録」から「事実の記録」へ
panda728
PRO
0
140
エンジニアとして高みを目指す、 利益を生み出す設計の考え方 / design-for-profit
minodriven
24
12k
CSC509 Lecture 05
javiergs
PRO
0
300
なぜGoのジェネリクスはこの形なのか? Featherweight Goが明かす設計の核心
ryotaros
7
1.1k
その面倒な作業、「Dart」にやらせませんか? Flutter開発者のための業務効率化
yordgenome03
1
110
All About Angular's New Signal Forms
manfredsteyer
PRO
0
100
私達はmodernize packageに夢を見るか feat. go/analysis, go/ast / Go Conference 2025
kaorumuta
2
520
CSC305 Lecture 05
javiergs
PRO
0
210
NixOS + Kubernetesで構築する自宅サーバーのすべて
ichi_h3
0
520
After go func(): Goroutines Through a Beginner’s Eye
97vaibhav
0
350
コードとあなたと私の距離 / The Distance Between Code, You, and I
hiro_y
0
110
XP, Testing and ninja testing ZOZ5
m_seki
3
600
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6.1k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
For a Future-Friendly Web
brad_frost
180
9.9k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Raft: Consensus for Rubyists
vanstee
139
7.1k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Building an army of robots
kneath
306
46k
Embracing the Ebb and Flow
colly
88
4.8k
Rebuilding a faster, lazier Slack
samanthasiow
84
9.2k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.7k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Transcript
Go×RLSで複数テナントのデータを安全に扱う 2023/09/28 golang.Tokyo#33 スプリームシステム株式会社 プロダクトディベロップメント部 徳丸 翔平
自己紹介 • 徳丸 翔平(@shohei36) • 普段の業務では主にJavaやGoを使ってバックエンド開発をやってます • Go歴はもう少しで1年といったところ • 低レイヤーに興味あり
モノリスからマイクロサービスへ https://acropolium.com/blog/migrating-monolith-to-microservices/
マルチテナントのデータベース戦略 https://medium.com/one9-tech/which-database-structure-to- use-in-multi-tenant-application-6f1b9af09634
マルチテナントのデータベース戦略 https://medium.com/one9-tech/which-database-structure-to- use-in-multi-tenant-application-6f1b9af09634
データベース の Row-Level Security(RLS)機能 データの読み込み時にテーブルの行レベルでアクセスを制御するデータベースの機能 テナントID ID NAME tenant01 1000
Bob tenant02 1000 Alice tenant03 1000 Taro tenant03 1000 Hanako SELECT ID, NAME FROM SOME_TABLE WHERE ID = ‘1000’ 「tenant02」が接続
プログラム側も工夫が必要… 🤔 RLSが効いたコネクションを正しく制御するには? 🤔 DBに依存せずにトランザクションをどのように表現するか? 🤔 テナント追加時の作業をゼロにしたい、、
プログラム設計方針 以下のアプローチによって実現 • データベースセッションの環境変数にセットしたテナントIDでアク セス権を制御 • Context 経由で sql.Tx を
リポジトリ にパスする
プログラム設計方針 以下のアプローチによって実現 • データベースセッションの環境変数にセットしたテナントIDでアク セス権を制御 • Context 経由で sql.Tx を
リポジトリ にパスする こちらのサンプルコードを使用して説明します https://github.com/shohei36/go-rls
環境 • WSL2 Ubuntu 20.04 on Windows • PostgreSQL 13.2
• Go 1.20
サンプルコードの構成 // アプリケーション固有のビジネスルール // トランザクション // DBなど外部システムとのアダプター // ドメインモデル //
Main関数(controllerも兼ねる) ※サンプルコードの構成 Clean Architecture
例)会員情報を更新するユースケース
登場人物
DoInTxを実行 usecase.go
sql.DB からコネクション(sql.Conn)を取得 transaction.go db.go
DBセッションの環境変数にテナントIDをセット db.go
補足:テーブルにRLSを適用するDDL pgsql/init/001_ddl.sql
sql.DBのコネクションはスレッドセーフ sql.DB の仕組み https://please-sleep.cou929.nu/go-sql-db-connection-pool.html 公式ドキュメント https://pkg.go.dev/database/sql#DB
トランザクション(sql.Tx)開始 transaction.go DoInTx
Context に sql.Tx をセット transaction.go DoInTx Sql.Tx を取り出すときに使うKey
トランザクション内の処理を実行 transaction.go DoInTx usecase.go
リポジトリのUpdateメソッドをCall usecase.go
DoInTx内でContextにセットしたsql.Txを取得 transaction.go repository.go
Update文を発行 repository.go ※RLSが効いているので、SQLのWhereの条件にtenant_idは不要
トランザクションをコミット transaction.go DoInTx
コネクションをsql.DBに返却 transaction.go DoInTx https://pkg.go.dev/database/sql#Conn.Close
まとめ • Context経由でsql.Txを渡すことで、DBに依存しない形でユースケースで トランザクションの定義が可能に • 参考:https://qiita.com/arkuchy/items/659a11767912c2ec266d • データベースセッションの環境変数にセットしたテナントIDでアクセス権 を制御 •
テナントのロールを追加する必要がなく、基本的にはテナント追加時の作業が不要 • sql.DBで管理するコネクションがスレッドセーフ • (感想)Goはマイクロサービス向きの言語であることを実感
Thank you for listening!