コンテンツへスキップ
すべての記事
約 6 分で読めます

ワークスペースはセキュリティ境界。

所有権チェックがすべての読み書きに属する理由、そしてタスク URL がアクセスを許可してはならない理由。

supastack チーム

サーバーで所有権を導出する

レコード ID は何かを識別しますが、誰が読めるかを証明しません。supastack はユーザー所有のレコードを workspaceId でスコープします。サーバーは認証済みユーザーのワークスペースを解決し、レコードの読み取りや変更時にそのスコープを含めます。

ブラウザから送信されたワークスペース ID を所有権の証明として扱わないでください。ブラウザはアクションを要求できますが、信頼されたサーバーコンテキストが誰のものかを確立しなければなりません。このルールは、タスク状態、保存されたプロバイダー設定、使用量レコード、すべての製品固有リソースに対して成立すべきです。レイアウトとコンポーネントは何を描画するかを絞れますが、描画は認可ではありません — チェックはレコードが実際に読み書きされる場所に属します。

この記事の他のすべてはそのルールから導かれます:所有権は導出されるものであり、要求されるものではありません。クライアント送信の workspaceId がどこかで信頼された瞬間、他のすべてのチェックは装飾になります。認証の記事がこの境界の上流でセッション自体がどう確立されるかをカバーしています。

メンバーシップも境界の一部

スコープはレコードがどのワークスペースに属するかに答え、メンバーシップはこのユーザーがそのワークスペースに属するかに答えます。両方をサーバーで解決します。supastack は個人用と組織用のワークスペースを owner・admin・member ロールでモデル化しています — ワークスペースガイドがそのモデルを文書化しています。

ロールは 2 つ目の軸を加えます:メンバーは admin だけが変更できるものを読めます。2 つのチェック — 「このワークスペースに属するか」と「この操作を実行できるか」— を区別したままにすれば、降格や削除も他のすべてと同じ境界で効果を持ちます。招待と削除は管理者の後付けではなく、同じライフサイクルの一部です。

メンバーシップ変更は即座に効果を持たなければなりません。削除されたメンバーの次のリクエストは、キャッシュされたトークンがたまたま期限切れになるときではなく、境界で失敗すべきです — これも、チェックが以前発行された認証情報の内部ではなくレコードが読まれる場所に置かれる理由です。

失敗すべきリクエストをテストする

所有者がレコードを取得できるテストはハッピーパスを証明します。分離は証明しません。同じレコードを要求する二番目のワークスペース、匿名リクエスト、別の所有者を名乗る書き込みと組み合わせてください。

永続化された結果と同じくらい外部の振る舞いをアサートします。拒否されたリクエストは別のワークスペースのデータを変更すべきではなく、エラーレスポンスは秘密や生のデータベース詳細を漏らすべきではありません。これらのチェックは実装が変わっても境界のレビューを保ちます。

  • 2 つ目のワークスペースが同じレコード ID を要求 — 拒否。
  • 匿名リクエストが同じエンドポイントに到達 — 拒否。
  • ワークスペースから削除されたメンバーが再試行 — 拒否。
  • 書き込みが別の所有者やワークスペースを指定 — 拒否。何も変更されない。
  • エラーレスポンスは汎用的なまま — 秘密もスキーマ詳細もなし。

ルールを製品に持ち込む

新しい製品テーブルを追加するとき、画面を作る前にその所有権を決めます。永続化モデルに workspaceId を含め、既存のサーバー境界を通じてワークスペースを解決し、リストと詳細の両方の操作でそのコンテキストを使います。

バックグラウンドワーカーも同じ注意が必要です。キューされたタスクは正しいレコードを読み込むのに十分な信頼コンテキストを運び、プロバイダー認証情報はサーバーに留まるべきです。ベア ID で行を読み込むスケジュールジョブも境界の内側にあります。一貫した所有権ルールは、ルートごとの例外の集まりより維持が簡単です。

API 面も同じ境界に属します。ワークスペース API キーと署名付き送信 webhook はワークスペースのスコープを携えます — キーはテナントをまたいで読む手段になってはならず、webhook ペイロードは隣人のレコードを運んではなりません。API モジュールガイドがその面の形をカバーしています。

ワークスペース分離についてよくある質問

マルチテナント分離はどのプロジェクトでも同じ一握りの質問を生じさせます。早めに決着しておく価値があるのはこれらです。

  • アプリケーションレベルのスコープで十分ですか、それとも行レベルセキュリティが必要ですか? — すべての読み書きでのサーバー強制スコープは、ほとんどの SaaS の脅威モデルをカバーします。データベース RLS は多層防御を加えますが、境界チェックの代替にはなりません — ワーカーと API キーにも同じルールが必要です。
  • ワークスペース間の共有はどうあるべきですか? — スコープを弱めるのではなく、明示的にモデル化します — 招待、メンバーシップ行として。「リンクを持つ全員」は事故ではなく、独自のチェックを持つ設計された機能であるべきです。
  • マルチテナントアプリで最初に壊れるものは? — 便利な経路です:復旧リンク、管理ツール、ベア ID でレコードを読むバックグラウンドワーカー。通常のスコープを通らずにレコードに触れるすべてのコードパスを監査してください。
  • 既存テーブルにスコープをどう追加しますか? — workspaceId を追加し、バックフィルし、読み書きで強制してから UI に触れます。境界が想定ではなく証明されるよう、ネガティブテストを先に出荷してください。
  • ページが保護されていればサーバーアクションにチェックは要りますか? — 要ります。ページガードは画面を隠しますが、操作を認可しません。すべてのアクションは独立してセッションとワークスペースを解決します。

よくある質問

14 件の質問

supastack とは何ですか?

supastack は AI SaaS 製品を構築するためのモジュラー基盤です。共通インフラをまとめて提供するので、製品固有の機能に集中できます。

Web とモバイルに対応していますか?

はい。supastack には Web とモバイル体験の出発点として Next.js アプリと Expo アプリが含まれています。

どの認証が含まれていますか?

Better Auth がメール/パスワード、OTP、ソーシャルログインをカバーします。個人ワークスペースはアカウントと一緒にプロビジョニングされ、初日からレコードが境界内に収まります。

AI はどうサポートされていますか?

supastack には設定可能なマルチプロバイダー AI、使用量追跡、予算、暗号化された自前キー(BYOK)サポートが含まれています。

サブスクリプションはどう管理されますか?

このキット上に構築された製品では、Stripe 課金・サブスクリプション・権限が有料アクセスの基盤になります。プロバイダーの秘密はサーバー側に留まります。

製品固有のコードはどこに置きますか?

製品固有の機能は別のコードベースに置き、製品側が supastack の基本モジュールを設定・統合します。

supastack の価格は?

キットは生涯アップデート付きの一回払いです:単一フレームワーク 249 ドル(期間限定のローンチ価格 — 通常価格 349 ドルから 100 ドル割引)、または全フレームワーク(Next.js・iOS・Android)499 ドル(期間限定のローンチ価格 — 通常価格 599 ドルから 100 ドル割引)、追加開発者シート 1 席 75 ドル。キットのサブスクリプションはありません。このサイトのチェックアウトはライセンスキーをメールで配信し、GitHub 招待でリポジトリアクセスを提供します。

ワークスペースはどうデータを囲いますか?

ユーザーレコードは workspaceId でスコープされます。認証、権限、AI 使用量、課金イベント、監査エントリは個人ワークスペースの境界内に留まります。

バックグラウンドジョブはどう機能しますか?

Trigger.dev が明示的なジョブランタイムです。JobRunner コントラクトは enqueue・status・cancel のみを約束し、ワークフロー意味論は Trigger.dev 固有で明示的です。

メールとアウトリーチの違いは?

トランザクションメールはタスク完了通知などの製品ワークフローをカバーします。コールドアウトリーチやキャンペーンは製品自身に属し、このキットのメールモジュールの外です。

モバイルの購入はどのように機能しますか?

モバイルでは RevenueCat によるネイティブ購入と復元に対応し、アクセス権をサーバーで検証します。公開前にストアアカウントを設定し、実機テストを完了してください。Web 課金は別に管理します。

AI プロバイダーのキーはどこにありますか?

BYOK 認証情報は暗号化され、サーバー側に留まります。キーはログでサニタイズされ、使用量と予算はワークスペースレベルで可視です。

チェックアウトで使える支払い方法は?

Stripe ホストのチェックアウトはカードを受け付け、Stripe アカウントでウォレットを有効にすれば Alipay と WeChat Pay も提供できます——中国の購入者に便利です。ウォレット認可は非同期で確定するため、決済完了と同時にライセンスページが更新されます。

返金を受けることはできますか?

リポジトリへのアクセス権を取得した後は、supastack は永久にあなたのものとなるため、返金はできません。ですがご安心ください。生涯アップデートを含む完全なソースコードを入手し、ご自身やクライアントのために無制限にプロダクトを構築・公開できます。コードの転売や、リポジトリをスターターキットやテンプレートとして再配布することのみ禁止されています。

JA