トークン自動販売機を用いたGoogleクラウド上のマルチテナントSaaSにおける完全分離データ


あなたがマルチテナントSaaSを構築しているならば、安全に他の顧客からだけでなくあなた自身のデベロッパーから顧客データを孤立させることはあなたが遅かれ早かれ会話するという会話です.我々のスタートアップでは、我々の顧客のデータは非常に機密性があります、そして、我々は非常に必要に応じてソフトウェアバグと従業員による内部のアクセスに起因する不注意な露出からそれを保護するために、極端な努力に行きます.
Skribeのようなハイブリッドプール/サイロのアーキテクチャのために、これを達成する私の大好きなセキュリティ戦略は、AWSがToken Vending Machine それは顧客データを分離するためにIAMを活用する.

基本的に認可されたユーザ(1)はAPIゲートウェイ(2)を通してAPI要求を作ります.そして、それは資格証明を確認して、ダイナミックなIAM方針(3)を生成するためにカスタムAuthorizerを呼びます.動的なIAM方針はハンドラ(4)に渡されます.そして、それはリソース(5)の特定のセットにすべての更なるプロセスをロックします.このソリューションの優雅さは、開発者の手からテナントのセキュリティを扱うの負担を除去し、プラットフォームレベルにそれを移動することです.悪意のある開発者の手でさえ、一時的にテナントデータを公開するという脅迫はほとんど完全に緩和されます.

問題
Skribeは、ハイブリッドクラウド/SILOEDアーキテクチャでGoogleクラウド上で主に構築され、永遠のように感じたもののために、私はGCP上でこの同じ戦略を実装する方法を研究していました.それは、彼らの管理されたサービスの制限を与えられなかったようでした.
  • エンドポイントとAPIゲートウェイは、カスタム認証をサポートしません.
  • 動的に生成されたIAMポリシーがサポートされていません.
  • あなたがStackOverflow、RedditとGCPの独自のホワイトパッドでさえ見つける提案された解決策は、基本的に同じことを言います:「テナント保安は、アプリケーションレベルで扱われなければなりません.」
    おっ!
    しかし、試行錯誤の日の後、我々は我々がGoogleクラウドで必要とされた非常に安全なテナント隔離を与える解決を見つけました!

    解決策

    同様に、テナントA(1)のユーザは、それらのテナント(2)でユーザーをリストするために許可された要求をする.APIゲートウェイはUsersEndpoint service ( 3 )データベースにアクセスする許可を持たないので、ユーザの認証トークンをTokenVendingMachine 4).The TokenVendingMachine トークンを検証し、カスタムクレームに基づいて、セキュアバケット(5)からテナントのサービスアカウントキーファイルを取得し、UsersEndpoint サービス最後に、キーファイル( 6 )を使ってデータベースを呼び出し、結果をユーザに返すことができます.

    ステップ1:搭乗中
    新しいテナントが作成されると、テナント固有のサービスアカウントが非同期で作成され、JSONキーファイルはテナントキーファイルを含む高度にセキュリティー保護されたバケットに格納されます.

    ステップ2 :認証
    我々は、ユーザーを認証するために有効にマルチテナントとアイデンティティプラットフォームを使用します.ユーザーがログインするとき、彼らは彼らの初期のトークンをユーザーのテナントと役割のようなカスタムクレームを含んでいるカスタムメイドトークンと交換します、そして、カスタムトークンはすべての以降の要求で送られます.
    これらのカスタムクレームは次のようになります.
    {
      tn: 'tn-xyz987',
      rl: 'editor',
      rg: 1,
      ...
    }
    
    クレームは、ユーザのテナント、それらの役割およびそれらのデータが存在する領域を識別する.

    ステップ3 : APIリクエスト
    ユーザーの認証要求がAPIゲートウェイに衝突すると、それはAPIを実行するクラウドランサービスに送られます.データベースとストレージバケットは、名前付きのサービスの後ろに抽象化され、任意のリソースにアクセスするために有効なJSONキーファイルを必要とします.
    ユーザがテナント内のユーザのリストを要求するなら、APIのコードはこの擬似コードと同じくらい簡単になります.
    app.run('/users', (res: Request, res: Response) => {
      // Create a new instance of our TokenVendingMachine class
      const tvm = new TokenVendingMachine();
    
      // Request the key file using the user's auth token
      tvm.get(req.headers.authorization)
        .then(async (key: Credentials) => {
          // The tenant's database name has been embedded in the key
          const db = new Database(key);
    
          const rows = await db.query("SELECT ...");
    
          res.json(rows);
        })
        .catch((e: any) => res.status(403));
    });
    
    テイクアウェイ:開発者は、単一テナント環境であるかのようにコードを書くことができます!

    私は、あなたが何を言うつもりであるかについてわかっています..
    なぜ短い生活サービスアカウント資格を発行しないのですか?
    レイテンシーGCSバケットから既存のキーファイルを取得するのは、各リクエストの新しい資格情報を要求するのと比較して非常に高速です.確かに、これらの短命の資格情報をキャッシュすることができますが、それはあなたの目標が完全な隔離されている場合、それらを安全に格納する問題の新しいセットを作成します.
    なぜ秘密マネージャを使用してキーファイルを格納するには?
    つまり、コスト.10000オペレーションあたり0.03ドルで、コストはAPIのために速くなります.
    ストレージバケツは危険なキーファイルでいっぱいですか?
    正しく確保されていない場合.The TokenVendingMachine サービスは、そのバケット内のすべてのオブジェクトへのアクセスのみを読み込み、オンボードプロセス中にキーファイルを生成する別のサービスが書き込みアクセスを行う.彼らが永久に生きていないように、定期的にキーを循環させるバックエンドサービスもあります.

    結論
    重要なことは、アプリケーションレベルからテナントセキュリティを分離することによって、我々は我々の開発者の手からテナントセキュリティの責任を削除しながら、我々の顧客のデータの信頼性の高い、安全なストレージとアクセスを達成することです.