はじめに
本記事は any Advent Calendar #2 「マルチテナントSaaSにおけるエンジニアリング大全」 Day17 の記事です。 弊社anyのアドベントカレンダーをひとつ丸ごと占有して、ひとりアドベントカレンダーとして、筆者の「マルチテナントSaaSのエンジニアリング」への経験をすべてアウトプットしていくカレンダーです。
Webフロントエンドについては、「マルチテナントSaaS」を意識することは多くはありません。そのほとんどがバックエンドに関わる問題ではありますが、あえてフロントエンド特有の問題について触れていきたいと思います💪
フロントエンド向けサーバサイド問題
サーバサイドレンダリング、React Server ComponentsといったWebフロントエンド側の実装に、サーバ側で実行されるコードを記述することが2025年では増えてきました。それ以前もSSR/SSGの文脈でNext.jsサーバがクライアントサイドの代わりに処理を実行することもあります。これはどちらかというとフロントエンドエンジニアが触る領域になるでしょう。
サーバリソースを共有する場合、当然ながらテナント分離、データ分離を意識する必要性が生じてしまいます。下記はVercelが提供するマルチテナントアーキテクチャのスターターキットですが、サブドメイン分割を前提としてmiddleware.tsがリクエストルーティングを行う必要が生じます。
顧客ネットワーク上で通信を制限する場合の考慮
フロントエンドという観点よりも、ややネットワークレベルの話になりますが、企業によってはWebフロントエンドから直接通信する必要がある通信について考慮が必要になる場合があります。たとえばMixpanelやGoogle Analyticsといったデータ分析ツールなどのサードパーティ製の通信や、CDNや署名付きURLなどファーストパーティながらもクラウドサービスに直接接続する通信などが該当します。
社内VPNやプロキシサーバー経由の場合、こういった通信が遮断されてしまうことがあり、顧客環境に大きく依存するため、非常に厄介な問題です。提供するシステム的に対策する方法では解消しにくいため、Qastでは通信許可が必要なドメインを下記のようにまとめて提供しています。
Cookieやストレージ汚染の問題
テナント分離方法にもよりますが、例えばサブドメイン方式 (tenant-a.example.com)で、Cookieのスコープ設計(SameSite属性やDomain属性)を誤ると、ログイン状態が維持できなかったり、逆に意図せず共有されてしまったりする問題が発生することがあります。ユーザーが複数の環境にログインできる状態であれば、テナントAとテナントBの情報が混在するリスクが発生します。
またグローバルステートを利用するような状態管理をする場合にも注意が必要です。React QueryやSWR、Apollo Clientなどのデータフェッチライブラリを使用している場合、キーに「テナントID」を含めないと、テナントAのキャッシュデータ(機密情報)がテナントBの画面に表示される事故が起きます。
さいごに
基本的にWebフロントエンドにおいてはマルチテナントであることを意識する機会は多くないはずですが、細かい点で意識する箇所があり、本日はそれらを紹介してきました。明日はより制約の強いモバイルアプリについて紹介していきますね!
