問題と背景
ある企業が2つのクラウドと1つのプライベートクラスタでマルチテナントマイクロサービスを運用しています。環境ごとに異なるチームが運用しており、本番環境はステージング環境から分離されている必要があります。決済サービスがレポートサービスを呼び出しますが、長期有効なAPIシークレットやクラウド固有のロールをイメージ内にコピーすることはできません。信頼ドメイン間でフェデレーションされたワークロードIDを設計してください。
ワークロードには、短命で検証可能なIDが必要です。受信側は、承認された外部信頼ドメイン、SPIFFE ID、オーディエンス、およびビジネスアクションのみを信頼しなければなりません。SPIFFE IDの命名、SPIRE ServerとAgent、ノードおよびワークロードのアテスト、X.509-SVIDまたはJWT-SVID、外部バンドルの取得、認可マッピング、ローテーション、失効、キャッシュ、ディザスタリカバリ、および静的クレデンシャルからの移行について網羅してください。
以下の不変条件(invariants)を維持してください:
- IDソースは、マシンがネットワークアドレスを持っていることだけでなく、どの制御されたプロセスが実行されているかを証明する。
- 信頼ドメインのバンドルは、すべての外部ワークロードに対してローカル権限を自動的に付与するわけではない。
- 受信側は、宣言された制限時間内に期限切れまたは失効したSVIDの受け入れを停止する。
- 秘密鍵はワークロードまたは制御された鍵マネージャーによって生成され、コントロールプレーンは長期有効な秘密鍵を配布しない。
- フェデレーションはIDと信頼素材を交換し、リソースサービスは引き続きビジネス認可を実行する。
面接官が評価しているポイント
優れた回答は、信頼ドメイン、SPIFFE ID、SVID、SPIRE Server、Agent、およびWorkload APIの間の境界線を明確に引きます。SPIFFEはIDの命名と検証可能なドキュメントを定義し、SPIREはノードとワークロードのアテストおよびSVIDの発行を実装します。IDは権限そのものではありません。spiffe://prod.example/ns/payments/sa/worker は、レポートサービスでの許可ポリシーを依然として必要とします。
2つ目の評価ポイントはフェデレーションです。SPIFFE Federationは、設定およびTLS認証されたバンドルエンドポイントを介して公開信頼素材を交換します。受信側はURLがどの信頼ドメインを表しているかを把握している必要があり、リクエストから任意のドメインのルートをダウンロードしてはなりません。Workload APIは外部バンドルを返すことができ、検証側はSVIDの信頼ドメインに一致するバンドルを選択します。
3つ目の評価ポイントは証明チェーンです。ノードアテストはAgentのノードを証明し、ワークロードアテストは信頼されたカーネル、kubelet、またはコンテナランタイムの属性を登録セレクターと照合します。名前空間、ラベル、または自己主張されたクライアントIDだけでは、盗難されたサービスクレデンシャルを防ぐのに十分ではありません。
最後に、運用面について議論します。フェデレーションバンドルの期限切れ、ルートキーのローテーション、Agentの切断、古いキャッシュ、コントロールプレーンの単一障害点、クラウド間のクロックスキュー、SVIDを読み込めないレガシーサービス、および検証を無効にしないロールバックです。
最初に明確にすべき質問
- どの信頼ドメインが本当に信頼を必要としているか? 決済サービスがレポートを呼び出すだけの場合、完全メッシュの信頼グラフを構築せず、単方向または最小限のエッジを定義します。
- X.509-SVIDかJWT-SVIDか? mTLSと接続IDは長期接続のサービスリンクに適しています。クラウド間のHTTPまたは外部OIDCリソースにはJWTオーディエンスが必要になる場合があります。検証キャッシュと漏洩リスク期間が異なります。
- 外部バンドルエンドポイントを誰が運用しているか? 1つの企業であればガバナンスを共有できますが、別企業の場合は明示的な公開素材、TLS ID、およびレビュー済みのドメインマッピングが必要です。
- 失効目標(revocation target)は何か? 例えば、SVIDの最大有効期間15分、バンドルポーリング60秒、緊急失効後5分以内の新規接続遮断などです。
- ワークロードはどのように自身を証明するか? Kubernetes ServiceAccount、クラウドインスタンスドキュメント、TPM、および制御された1回限りのジョイントークン(join token)では前提条件が異なります。
- レガシーサービスはSPIFFEを利用できるか? できない場合、サイドカーやゲートウェイが制限された方法で変換できるか? そのIDと権限には独自の境界が必要です。
30秒での回答
「本番、ステージング、オンプレミス用に独立した信頼ドメインを作成し、テナントシークレットを含まない安定したSPIFFE IDを割り当てます。各ドメインのSPIRE Serverが登録エントリを保持します。Agentは自身のノードを証明した後、ローカルプロセスの属性を使用してワークロードアテストを行い、ワークロードはWorkload APIから短命のX.509-SVIDまたはJWT-SVIDを取得します。
決済ドメインは、レポートドメインの外部バンドルエンドポイントのみを設定し、ドメイン、TLS ID、および許可されたマッピングを固定(ピン留め)します。レポート側は署名、SVIDの有効期限、オーディエンス、ピアバンドルを検証し、完全なSPIFFE ID、環境、テナントコンテキスト、およびアクションを認可します。バンドルとSVIDの更新にはストリーミングAPI、短いTTL、およびバージョンメトリクスを使用します。コントロールプレーンが利用できない場合、事前に検証された有界な素材で低リスクなトラフィックを処理できますが、高リスクな新規接続はフェイルクローズします。移行では古いクレデンシャルとSVIDを並行稼働させ、サービスプール単位でカナリアリリースを行い、監査と失効の目標が実証された後にのみシークレットを削除します。」
ステップごとの設計
ステップ1:信頼ドメインの分割とIDの命名
信頼ドメインは、IDの名前空間であり、信頼のルート(root of trust)の境界です。本番、ステージング、PCI環境、または個別に管理される組織には、単一のグローバルルートではなく個別のドメインを使用する必要があります。IDの例は次のとおりです:
spiffe://prod.example/ns/payments/sa/worker
spiffe://reports.partner/ns/analytics/sa/readerパスは、Pod名、IP、または短命なデプロイハッシュではなく、安定したビジネスプリンシパルとガバナンススコープを表現する必要があります。バージョン、テナント、リージョンは、セレクター、ポリシー入力、またはトークンクレームとして扱うことができます。すべてのデプロイをIDにエンコードすると、ローテーションと認可のメンテナンスがフリート全体の移行作業になってしまいます。
フェデレーションを明示的なエッジとして記録します:prod.example は reports.partner のバンドルを検証できますが、それはオーディエンス reports-api かつアクション ReportRead に対してのみです。受信側は、両方のドメインがSPIFFEを使用しているという理由だけで呼び出しを許可してはなりません。
ステップ2:Server、Agent、登録エントリの確立
SPIRE Serverは、登録エントリ、署名素材、およびノード認可を保存します。Agentは各ワークロードノードで実行され、ローカルのWorkload APIを公開します。Serverは、1つのノード侵害による影響範囲(ブラスト半径)を制限するため、そのAgentが管理を許可されているエントリのみを送信します。
エントリには、SPIFFE ID、親SPIFFE ID、セレクターセット、許可されたSVIDプロファイル、およびオーディエンスをバインドする必要があります。セレクターは、信頼されたオーケストレーターまたはノードのプロパティ(Kubernetes名前空間、サービスアカウント、イメージダイジェスト、クラウドインスタンスIDなど)から取得します。ユーザーが編集可能なラベルのみに依存したり、任意の構成文字列をアテストの証拠として扱ったりしてはなりません。
ステップ3:2段階のアテストの設計
ノード起動時、Agentはクラウドインスタンスドキュメント、Kubernetes ServiceAccount、TPM、または1回限りのジョイントークンを使用して自身のIDを証明します。Serverは独立して証明を検証し、AgentのIDを発行します。次に、ワークロードはUnixドメインソケットまたは制限されたエンドポイントを介してWorkload APIを呼び出します。Agentは、プロセスID、カーネル、kubelet、またはコンテナランタイムのファクトを使用してセレクターを取得し、登録エントリと照合してSVIDを返します。
これが、Workload APIが通常のネットワーククライアント認証を使用する必要がない理由です。Agentはローカルの呼び出し元を帯域外(out-of-band)で識別します。ソケットのアクセス権、名前空間の分離、ホストカーネルやkubeletへの信頼は脅威モデルに含まれます。Agentが呼び出し元を識別できない場合、デフォルトの高特権IDを返すのではなく PermissionDenied を返す必要があります。
ステップ4:SVIDプロファイルの選択と鍵の取り扱い
X.509-SVIDはmTLSおよび接続レベルのサービスIDに適しています。JWT-SVIDは、アサーションとともに audience を伝播する必要があるHTTPまたは外部OIDC交換に適しています。JWT-SVIDの検証側は、サブジェクト信頼ドメイン用のバンドルを使用する必要があります。任意のJWKSは同じ信頼ルートではありません。
SVIDは短命にし、Workload API経由でストリーミング配信される必要があります。ワークロードまたはAgentの鍵マネージャーが秘密鍵を生成し、制限されたメモリまたはファイルディスクリプタ内に保持します。Serverは対応する公開鍵に署名しますが、長期有効な秘密鍵をイメージ、環境変数、または通常の構成ファイルに書き込むことは決してありません。複数のIDを持つワークロードは、hint または内部/外部オーディエンスの明示的な選択を使用して、デフォルトIDが悪用されないようにすることができます。
ステップ5:ドメイン間バンドルフェデレーションを安全に確立
フェデレーションコントロールプレーンは、外部ドメイン、バンドルエンドポイント、エンドポイントプロファイル、TLS証明書、および許可されたSPIFFE IDプレフィックスをレビューします。クライアントは、URLがどの信頼ドメインを表しているかを事前に認識しています。TLS認証はトランスポートエンドポイントを証明しますが、返されたバンドルには依然としてドメイン、バージョン、署名、および有効期限のチェックが必要です。
外部バンドルはバージョン管理されたトラストストアに保存します。ピア検証中、SVIDの信頼ドメインによってバンドルを選択し、一致するものがない場合は拒否します。外部バンドルをローカルの発行ルートにしてはならず、一時的なリダイレクトを理由に構成を恒久的に置き換えてはなりません。ポーリング、ETag、有効期限、および最後に成功したバージョンは監視可能である必要があります。
ステップ6:リソース認可へのIDのマッピング
レポートサービスのPEP(ポリシー施行ポイント)は、mTLSピアまたはJWT-SVIDを検証し、完全なSPIFFE ID、信頼ドメイン、オーディエンス、テナント、およびアクションをPDP(ポリシー決定ポイント)に送信します。ルールの例は次のとおりです:
allow if trust_domain == "prod.example"
and spiffe_id == "spiffe://prod.example/ns/payments/sa/worker"
and audience == "reports-api"
and action == "ReportRead"
and tenant == resource.tenantネットワークの到達可能性、有効なSVID、およびフェデレーションエッジは、ビジネス上の権限を構成するものではありません。リソースサービスは引き続き、テナントの所有権、行レベルのアクセス権、承認、およびレート制限をチェックします。ワークロードIDがクラウドIAMまたは外部OIDCサービスにアクセスする必要がある場合は、オーディエンス、スコープ、SVID TTL、および目的にバインドされた制限付きブローカーを使用します。広範なクラウドロールをすべてのワークロードに渡してはなりません。
ステップ7:ローテーション、失効、キャッシュ整合性の調整
SVIDの有効期限切れは、Workload APIストリームを通じて処理されます。クライアントは証明書と鍵をアトミックに置き換え、新しい接続が最初に新しい素材を使用できるようにします。信頼バンドルのローテーションは、古いルートと新しいルートの有界なオーバーラップを使用します。検証側が新しいバージョンをロードし、古いSVIDと接続がドレインされた後にのみ、古いルートを削除します。緊急の侵害時は通常のオーバーラップを使用せず、失効または拒否バージョンを公開し、受け入れウィンドウを短縮します。
バンドルバージョン、発行者、信頼ドメイン、SVIDの有効期限、およびポリシーバージョンをキャッシュします。宣言された5分の失効目標を達成するには、接続確立、JWT検証、およびサイドカーキャッシュが5分以内に更新を反映する必要があります。長期接続には有界な証明書有効期間によるドレインが必要です。既存の接続を処理せずにコントロールプレーンのデータベースを変更しただけでは、失効の完了とは言えません。
ステップ8:スケール、障害、移行の計画
SPIRE Serverのリソース使用量は登録エントリ数とともに増加し、単一インスタンスは障害点となります。リージョンまたは信頼ドメインごとにシャーディングし、HAのために複数のServerを使用し、各Agentが受信するエントリを制限し、発行レイテンシ、Agent数、エントリ数、Workload APIリクエスト数、およびバンドル遅延を監視します。完全メッシュのフェデレーションマップは避け、制御されたエッジまたはブローカーを使用します。
コントロールプレーンが利用できない場合、有効期限内のSVIDは低リスクな既存の接続を有界に維持できますが、システムが無期限にIDを発行し続けてはなりません。バンドルの期限切れ、ノード証明の失敗、鍵マネージャーの障害、または不明なドメインマッピングが発生した場合、高リスクな新規接続はフェイルクローズする必要があります。静的シークレットの移行中は、両方のパスを並行して実行し、サービスプールごとにカナリアリリースを行い、監査と失効を検証してから古いシークレットを削除します。ロールバックは依然として制御されているパスに戻ることであり、認証を無効化することではありません。
模範解答
「本番、ステージング、パートナー環境を信頼ドメインに分離し、ワークロードには安定したSPIFFE IDを使用します。各SPIRE Serverが登録エントリと発行ルートを保持します。Agentがノードを証明した後、ローカルのWorkload APIがプロセスとオーケストレーターの属性を使用してワークロードアテストを実行します。ワークロードはmTLS用の短命なX.509-SVIDまたは固定オーディエンス用のJWT-SVIDを取得し、秘密鍵はワークロード、Agent、または制御された鍵マネージャー内に留まります。
決済とレポートの間には、レビュー済みのフェデレーションエッジを1つ設けます。クライアントはエンドポイントとドメインを固定し、TLS、バンドルバージョン、有効期限を検証します。ピア検証ではSVIDの信頼ドメインによって外部バンドルを選択し、一致しない場合は拒否します。レポート側はSVID、発行者、オーディエンス、有効期限を検証し、完全なSPIFFE ID、テナント、アクションを認可します。フェデレーションは検証素材を提供するだけであり、ビジネス権限を付与するものではありません。
SVIDとバンドルはストリーム、短いTTL、バージョンメトリクス、有界なステール素材を通じてローテーションされ、長期接続は証明書の有効期間に基づいてドレインされます。証明やコントロールプレーンの障害時に不明なIDが発行されることは決してなく、高リスクな呼び出しはフェイルクローズします。静的シークレットの移行では、すべてのサービスがID、認可、および復旧の境界を実証できるようになるまで、並行パス、カナリアリリース、失効訓練、および監査の照合を使用します。」
よくある間違い
- すべてのクラスタで単一の信頼ドメインを共有する。 1つのルートまたは構成の漏洩がすべての環境に波及します。ガバナンスとリスクに応じてドメインを分割してください。
- SPIFFE IDをビジネス認可として扱う。 IDは『誰であるか』に答えるだけです。リソースサービスは依然としてオーディエンス、テナント、アクション、および所有権をチェックする必要があります。
- ノードアテストのみを実施する。 ノード上の悪意のあるプロセスがサービスになりすます可能性があります。ワークロードセレクターも併用してください。
- 可変なPod名やIPを長期的なプリンシパルとして使用する。 再構築や移動によって認可が破損します。安定したIDとポリシーセレクターを使用してください。
- フェデレーションURLを信頼ルートとして扱う。 ドメインを事前設定し、TLS、バンドル内容、バージョン、および有効期限を検証してください。
- 外部バンドルからのすべての外部プリンシパルを許可する。 フェデレーションは検証素材を提供するだけです。ポリシーによってIDプレフィックス、オーディエンス、アクション、およびテナントを制限する必要があります。
- 長期有効な秘密鍵をイメージや環境変数に配置する。 コピーによって漏洩します。ワークロードまたは鍵マネージャーの境界で生成およびローテーションしてください。
- 古いバンドルやSVIDを無期限に受け入れる。 これは失効要件に違反します。バージョン、TTL、接続期間を追跡し、制限時間を超えたら拒否してください。
- コントロールプレーンの停止時にデフォルト許可(default-allow)にする。 不明なIDが権限を取得してはなりません。有界な古い素材を使用するか、リスクに応じてフェイルクローズしてください。
- 監査と認可を行わずにmTLSへ移行する。 暗号化はビジネス上の許可を証明しません。ピアID、ポリシーバージョン、テナント、および決定結果を記録してください。
フォローアップの質問と回答
2つの信頼ドメインで双方向通信が必要な場合、双方が互いのバンドルをインポートする必要がありますか?
必ずしもそうではありません。決済サービスがレポートを呼び出すだけであれば、単方向のエッジを作成します。レポート側は決済側の外部バンドルを信頼しますが、決済側はレポート側を信頼する必要はありません。レポート側からも呼び出しを開始する場合にのみ、個別のオーディエンスとポリシーを設定して逆方向のエッジを追加します。相互信頼は完全な認可を意味しません。
クラウドプロバイダーのワークロードIDを直接使用しないのはなぜですか?
クラウドIDは単一クラウドのコントロールプレーン内では有用ですが、マルチクラウド、プライベート、およびパートナー環境では発行者、SDK、ポリシーが異なります。SPIFFEはポータブルな命名、SVID、およびバンドル交換を提供します。外部のクラウドIAMは依然として制限付きのOIDCフェデレーションブローカーを使用できます。SPIFFEはビジネス認可を置き換えるものではありません。
認証されていないWorkload APIは安全ですか?
ソケットを開かれたネットワークAPIとして扱うのではなく、帯域外のプロセス識別に依存しています。ソケットまたはエンドポイントのアクセス権を制限し、ホストと名前空間を分離し、カーネル、kubelet、またはコンテナランタイムのファクトに対して登録エントリを照合します。識別不能な呼び出し元は拒否され、デフォルトで強力なSVIDを受け取ることは決してありません。
外部バンドルエンドポイントが一時的に利用できない場合はどうなりますか?
バージョンと有効期限が付与された最後の信頼済みバンドルを保持します。最新である間は、既存の低リスク接続を検証できます。最大ステール期間を超えた場合、または高リスクな新規接続の場合は、フェイルクローズします。古いルートを無期限に受け入れるのではなく、バンドル遅延、最後に成功したバージョン、および拒否数を監視します。
長期接続はSVIDのローテーションと失効をどのように処理しますか?
Workload APIが新しい素材をストリーミング配信し、クライアントはアトミックに更新して新しい接続に新しい証明書を使用します。最大証明書有効期間または失効ウィンドウによってドレインし、高リスクなコミットの前にポリシーを再チェックします。確立された接続を処理せずにファイルを置き換えるだけでは、古いIDが排除されたことの証明にはなりません。
セレクターが偽造されないことをどのように証明しますか?
セレクターは信頼されたノードまたはオーケストレーターのAPIから取得され、ServerまたはAgentによって検証されます。ユーザーが編集可能なラベルは単なるヒントに過ぎません。イメージダイジェスト、サービスアカウント、名前空間、プロセスプロパティ、およびノード証明を組み合わせ、登録の変更を監査および承認します。
静的シークレットの移行をどのようにロールバックしますか?
古いシークレットとSVIDを並行して受け入れ、サービスプール単位でSVIDを有効化し、両方のパスの成功、認可、および失効を記録します。障害発生時は新しい発行を停止し、依然として制御されている古いシークレットに戻し、問題を修正した後にカナリアリリースを再開します。廃止の証拠と削除ゲートを定義してください。認証を無効化することをロールバックにしてはなりません。