セキュリティ
ゼロトラストのアプリケーションアーキテクチャ
ゼロトラストとは、リクエストの送信元を理由に認可を与えないことです。実際には、ワークロードアイデンティティ、短命な認証情報、そして呼び出しごとに評価されるポリシーを意味します。
· 5分で読めます · Starone エンジニアリング
ゼロトラストは製品ではなく、アーキテクチャが備える性質です。到達元のネットワークを理由に認可されるリクエストが1つもないとき、そのシステムはゼロトラストであると言えます。すべての呼び出しが検証可能なアイデンティティを持ち、すべての呼び出しがポリシーに照らして検査され、侵害されたコンポーネントが得られるのは、そのコンポーネント自身のアイデンティティに許可されていた範囲だけです。
私たちの見方では、価値の大半は地味な3つの作業から生まれます。すべてのワークロードにアイデンティティを与えること、長期間有効なシークレットをなくすこと、そしてアプリケーションコードに散在する認可処理を、レビュー可能なポリシーへ移すことです。ネットワークのセグメンテーションは依然として重要ですが、それは信頼の根拠ではなく、第2の層としての位置づけです。
アイデンティティこそが境界である
境界型モデルは、ネットワークの内側にあるものはすべて味方であると仮定します。この仮定は、Podが1つ、ノートPCが1台、あるいは依存ライブラリが1つ侵害された瞬間に崩れます。攻撃者がそのネットワークセグメントの信頼をそのまま引き継ぐからです。その結果としてラテラルムーブメントが起こるのは、予測できることです。
場所の代わりにアイデンティティを基準にすると、各サービスが発する問いが変わります。リクエストが内部サブネットから来たかどうかは、もう問いません。呼び出し元は誰か、それを証明するものは何か、そしてこの呼び出し元がこのリソースに対してこの操作を行ってよいかを問います。考慮すべきアイデンティティは常に2つあります。呼び出しを行うワークロードと、その呼び出しの依頼主であるエンドユーザーです。
サービスアイデンティティと相互TLS
ワークロードアイデンティティは手作業で設定するものではなく、プラットフォームが発行すべきものです。一般的なモデルはSPIFFEです。各ワークロードは短命なX.509証明書を受け取り、そのアイデンティティはKubernetesのサービスアカウントやNamespaceといった、アテステーションで確認された属性から導出されます。サービスメッシュまたはライブラリがこの証明書を使って相互TLS(mTLS)を確立するため、すべての接続の両端が認証され、通信は暗号化されます。
mTLSは、それだけで解決策のすべてだと誤解されがちです。mTLSが証明するのは、どのサービスが呼び出しているかです。そのサービスがこのエンドポイントを呼び出してよいかどうかについては何も示さず、ユーザーに関する情報も運びません。認可ポリシーを重ねないまま認証だけを導入すると、暗号化されたフラットなネットワークができあがるだけです。
保存されたシークレットより短命な認証情報
環境変数に置かれた静的なAPIキーは、誰かがローテーションを思い出すまで有効であり続け、攻撃者のマシンからでも同じように使えます。短命な認証情報はその猶予を数分にまで縮め、ローテーションの負担もほとんど取り除きます。有効期限切れそのものがローテーションになるからです。
- 保存されたアクセスキーに代えて、OIDCによるクラウドプロバイダーへのワークロードアイデンティティフェデレーション
- Vaultの動的シークレットなどを用いた、リース付きでオンデマンド発行されるデータベース認証情報
- 署名付きのジョブトークンを、スコープと有効期間が限定されたデプロイ権限に交換するCIパイプライン
- 有効期間が短く、オーディエンスが制限され、リフレッシュがエッジで処理されるユーザートークン
ポリシーの判断と強制を分離する
認可は2つの部分から成ります。ポリシー強制ポイント(PEP)はリクエストを捕捉し、遮断または許可します。ポリシー判断ポイント(PDP)はルールを評価して答えを返します。両者を分けておけば、ポリシーは一度だけ記述され、バージョン管理、テスト、レビューの対象となります。各サービスに条件分岐として再実装されることはありません。
設計上の実際的な論点は、判断をどこで実行するかです。中央の判断サービスは挙動を把握しやすい反面、すべてのリクエストにネットワークホップと単一障害点を持ち込みます。私たちの基本方針はローカル評価です。Open Policy Agentのようなエンジンをサービスの隣、またはゲートウェイの内部で動かし、そこへポリシーバンドルを配布します。判断はマイクロ秒単位で完了し、コントロールプレーンが停止しても継続できます。その代償として、ポリシーの変更は遅れて伝播するため、失効のシナリオにおいてその遅延が許容できるものでなければなりません。
判断を下せない場合に何が起こるかは、あらかじめ決めておきます。状態を変更する操作やデータを公開する操作では、フェイルクローズが正解です。可用性のほうが重要な低リスクの読み取り経路では、フェイルオープンが正当化される場合もまれにあります。ただしその例外は、インシデントの最中に発覚するものではなく、事前に文書化されているべきものです。
最小権限はデータまで届かせる
よくある抜け穴は、適切に認証されたサービスメッシュの背後で、すべてのサービスが同じ強力なユーザーとしてデータベースに接続している構成です。入口でのチェックは確かに機能していますが、その奥ではどのサービスも、あらゆるデータを読み取れる「混乱した代理人(confused deputy)」になっています。
この抜け穴を塞ぐには、エンドユーザーのコンテキストを呼び出しチェーン全体に伝播させ、ホップごとに絞り込んでいきます。トークン交換を使えば、サービスは受け取ったトークンを、必要とする単一の下流オーディエンスだけにスコープされたトークンへ差し替えられます。各サービスには自身のテーブルにのみアクセスできる専用のデータベースロールを与え、データモデルが許す箇所では行レベルのポリシーでユーザーまたはテナントのコンテキストを適用します。
- サービスごとに1つのアイデンティティ。プラットフォーム共有のアカウントは使わない
- 盗まれたトークンを他の場所でリプレイできないよう、オーディエンスにスコープされたトークン
- サービス間はデフォルト拒否とし、許可する経路は一つひとつ明示的に宣言
VPNがゼロトラストではない理由
VPNはデバイスを一度認証し、その後ネットワーク上に配置します。そのネットワークから到達できるものはすべて、セッションが続く限り、そのデバイスからも到達できるようになります。これはケーブルを長くしただけの境界型モデルです。加えて、VPNコンセントレーターが価値の高い単一の攻撃対象になります。
アイデンティティ認識型プロキシはこの構図を逆転させます。アプリケーションは1つずつ個別に公開され、リクエストは1件ごとに認証・認可され、デバイスのポスチャーも判断材料に含められます。ある社内ツールへのアクセス権は、それ以外の何にも通用しません。プロキシの背後に置けないレガシープロトコルについては、VPNは引き続き妥当な選択肢です。ただし、認可ではなくトランスポートとして扱うことが条件です。
どこから始めるか、そして見送るべき場合
ゼロトラストには現実のコストがかかります。証明書基盤、ポリシーツール、デバッグ対象となる可動部分の増加、そしてそれらを理解していなければならないエンジニアリングチームです。データベースが1つで少人数のチームが運用する単一のモジュラーモノリスに、リクエストごとのポリシー評価を伴う本格的なサービスメッシュを導入するのは釣り合いが取れません。強固なユーザー認証、マネージドのシークレットストア、分離されたデータベースロールで、効果の大部分は得られます。
サービス数が多い、複数のチームが関わる、あるいは機微なデータを扱うシステムであれば、私たちはワークロードアイデンティティの導入と静的シークレットの排除から着手します。そのうえでポリシーを監査モードで導入し、強制する前に何が拒否されることになるかを観察します。実際のコールグラフを誰も計測していないシステムにデフォルト拒否のポリシーを強制することこそ、障害を引き起こす典型的な手順です。
