注目のSPIFFE、その概要とKubernetesへの導入方法
はじめに
「KubeCon + CloudNativeCon」でのセキュリティに関するセッションで紹介されたり、IstioをはじめとしたService MeshプロダクトのWorkload Identityとして採用されたりと、最近になりCloud NativeコミュニティでSPIFFEの名を耳にすることが多くなってきました。本記事では、SPIFFEが求められた背景やSPIFFEの概要、Kubernetesへの導入方法などを紹介していきます。
SPIFFEが求められた背景
マイクロサービスアーキテクチャ、コンテナオーケストレーター、クラウドコンピューティングのような分散システムを利用している環境では、サービスのスケーリングなどに伴いノードやアプリケーションが頻繁かつ動的に分散配置されるため、アプリケーションに割り当てられるIPアドレスが短期間で変化してきます。
このような環境では、ネットワークポリシーなどでIPアドレスを元にサービス間の通信を制御する従来のセキュリティ手法を運用することが非常に難しくなってきており、ネットワークセキュリティのためにIPアドレスに依存せずアプリケーションを安全に識別する仕組みが必要になってきています。
こういった背景を受けて登場したのがSPIFFEです。
SPIFFEとは
SPIFFE(Secure Production Identity Framework For Everyone)はソフトウェアを安全に識別するための標準仕様です。SPIFFEが導入されたシステムでは、通信を行うワークロード同士が異なる環境(オンプレミス、AWS、Azure、GCP、Kubernetesなど)で稼働していても、統一された識別子と統一された認証方式での安全な相互認証により通信相手を識別できます。ワークロードの定義についてはこちらを参照ください。
SPIFFEの策定とエコシステムの開発を目的としたSPIFFEプロジェクトは、GlueCon 2016でKubernetesの共同創設者(最初に開発した3人のうちの1人)であるJoe Beda氏から発表された「The Original SPIFFE Design Doc」で提案されて始まったもので、SPIFFE自体はScytale、Google、Heptio、Tigeraのエンジニアにより策定されました。豆知識ですが、SPIFFEのロゴに使用されている2色のカラーコードは提案者のラストネームBedaを使用して#00bedaと#beda00となっています。
それでは、SPIFFEで標準化されている仕様を紹介していきます。
SPIFFE ID
SPIFFE IDはワークロードの識別子となるURI形式で構造化された文字列です。SPIFFE IDはSPIFFEの基礎となる仕様で以下のようなフォーマットで表現されます。
URIのホスト部に定義するTrust Domainは組織、部門、実行環境などワークロードのセキュリティ境界を描くためのもの(パブリックなDNSへの登録は不要)で、基本的には同一のTrust Domainが定義されたSPIFFE IDを持つワークロード同士が相互認証できる仕様になっています。異なるTrust Domainを持つワークロード同士での相互認証を実現する方法は後述します。
以下は、SPIFFE IDの例です。この例に示すとおり、SPIFFE IDは要件に合わせて自由な粒度で設計することができます。
SVID
SVID(SPIFFE Verifiable Identity Document)は通信相手に自身の SPIFFE IDを提示するためのドキュメント(文書ファイル)で、以下のコンポーネントから構成されています。必要に応じてこれらのコンポーネント以外に任意の情報を含めることも許容されています。
- 単一のSPIFFE ID
- 有効なデジタル署名
- 任意の公開鍵
ワークロードが自身のSVIDを別のワークロードに送信し、自身の身元を示すSPIFFE IDを提示するという使用用途から、機能性としては現実世界でのパスポートに相当するものとイメージしてもらえればと思います。このような表現をしているとおり、SVIDには現実のパスポートと同様に偽装に対する耐性と自身の身元を証明できる仕組みが備わっています。
それでは、SVIDのデータフォーマットとして、どのようなものが標準化されているかを見ていきましょう。SPIFFEではX.509証明書形式のX.509 SVIDとJWT形式のJWT SVIDの2種類のSVIDが標準化されており、いずれも暗号技術を利用して通信相手のSPIFFE IDの信頼性を検証できる(=SVIDに含まれるデジタル署名を検証することで内容が改ざんされていないかを確認できる)特性を持っています。
どちらのSVIDを利用するかはSPIFFEを導入するシステムの要件に依存しますが、JWT SVIDはリプレイアタックを受ける危険性があるため、可能な限りX.509 SVIDの利用が推奨されています。L7プロキシやロードバランサーなどによりワークロードの前段でTLS終端がされてしまうようなケースでのみJWT SVIDを利用すると良いでしょう。
X.509 SVIDはSubject Alternative Name(SAN)のURIにSPIFFE IDをセットする仕様で、JWT SVIDはsubクレームに自身のSPIFFE IDをaudクレームに通信相手を識別する文字列(SPIFFE ID、任意の文字列どちらでも良い)をセットする仕様になっています。
先述の通り、SPIFFEは基本的に同一のTrust Domainが定義されたSPIFFE IDを持つワークロード同士が相互認証できる(=SVIDの信頼性を検証できる)仕様なので、Trust Domain毎にワークロードのSVIDを発行する固有の署名機関を持つ必要があります。SVID自体は署名機関が発行しますが、ワークロードがSVIDを取得するには後述のWorkload APIにリクエストする必要があることに注意してください。
また、署名機関にも自身のSVIDを持たせる(署名機関に割り当てるSPIFFE IDはパスを持ってはいけない制約がある)必要があり、ワークロードのSVIDの署名には署名機関が持つSVIDと対になる秘密鍵を使用します。これはワークロードのSVIDが偽造されていないかを署名機関のSVIDで検証できることを意味します。
さらに、この署名機関は必要に応じて外部の署名機関と連携させてPKIツリーなどのトラストチェーンを構成することも許容されています。その場合には、ワークロードのSVID検証を行う際に署名機関のSVIDに加えて、外部の署名機関の公開鍵が必要になります。
Trust Bundle
ここまでの説明で「署名機関の公開鍵」と表現していたものはTrust Bundleと呼ばれ、SVIDと同様にワークロードが後述のWorkload APIへリクエストすることで取得できます。
さらにSPIFFEではTrust Bundleと併せてBundle Endpointという仕組みも定義されています。これはTrust BundleをRFC 7517に準拠したJWK Setとして表現し、署名機関がHTTPSのエンドポイントとして公開する仕組みとなっています。このTrust Bundleを配布する仕組みはOpenID Connectのjwks_urlの仕組みと完全な互換性を持たせる必要があります。
この仕組みを利用して異なるTrust Domain間の署名機関でTrust Bundleを交換(SPIFFEではこれをFederationと呼んでいる)することで、あるTrust DomainのワークロードがWorkload APIを介して別のTrust DomainのTrust Bundleを取得できるようになります。これは異なるTrust Domainを持つワークロード同士での相互認証が可能になる(=異なるTrust Domainを持つSVIDはFederationされたTrust Bundleで信頼性を検証できる)ことを意味します。さらに、OpenID Connect互換なシステムであれば外部のシステムとも連携でき、JWT SVIDを外部のクラウドサービスの認証に使用する(クラウドサービスはBundle Endpointから提供されるTrust BundleでJWT SVIDを検証する)といったことも実現できます。
同一のTrust Domainを持つワークロード同士、異なるTrust Domainを持つワークロード同士、それぞれの相互認証がどのように実現されるかは、後述の「ワークロード同士が相互認証するフロー」で紹介します。
Workload API
Workload APIはSVIDとTrust Bundleを取得するためのAPIです。Workload APIからX.509 SVIDを取得する際には、SVIDとTrust Bundleに加えてSVIDと対になる秘密鍵もレスポンスに含まれますが、わかりやすさを考慮してここからの説明では割愛します。
Workload APIはSVIDが漏洩した際の被害を最小限に抑えるために短命なSVIDを発行する仕様(期限が切れたら自動ローテーション)になっており、ワークロードに新しいSVIDやTrust Bundleなどを迅速に伝播する目的でgRPCのサーバーサイドストリーミングRPCとして実装する必要があります。
また、Workload APIはどのような環境(オンプレミス、AWS、Azure、GCP、Kubernetesなど)でも機能することが求められています。これによりワークロードがどこで稼働していてもWorkload APIという統一されたインターフェースで自身のSVIDとTrust Bundleを取得できるようになります。
Workload APIはWorkload Endpointから提供されます。Workload EndpointはgRPCで実装しUnixドメインソケットで公開することが推奨されています。Workload APIはWorkload Endpointに含まれるRPCサービスという位置づけです。
ここでポイントになってくるのが、Workload Endpointにクライアント(ワークロード)と直接的な認証を実装してはいけないという制約です。この制約はワークロードからWorkload APIに対する初回リクエストにおいて、ワークロードが自分自身を証明するためのクレデンシャルを保持していないことに起因しています。
この制約に準拠するため、Workload Endpointではカーネルやコンテナオーケストレーターなど(呼び出し元ワークロードが稼働するプラットフォームに依存する)に問い合わせて、呼び出し元ワークロードを識別することが推奨されています。Workload Endpointで呼び出し元ワークロードを識別した結果を元に、Workload APIが割り当てるSPIFFE IDを任意のロジックで決定し、ワークロードにSVIDを配布するイメージです。これによりワークロードの属性情報に応じてSPIFFE IDを割り当てることが可能になります。また、実装によっては特定の属性情報を持ったワークロードにのみSVIDを配布することもできます。
ワークロード同士が相互認証するフロー
以降では、X.509 SVIDを利用したワークロード同士における、L4のmTLSによる相互認証の例を紹介します。
同一 Trust Domain 配下のワークロード同士の相互認証
ここではexample.comというTrust Domain配下でワークロードが稼働していると仮定します。各ワークロードはWorkload APIを介して自身の身元を示すSPIFFE IDが含まれたX.509 SVIDとTrust Bundleを取得でき、取得したTrust Bundleを利用して同一Trust Domain配下の別のワークロードが持つX.509 SVIDの信頼性を検証することが可能(署名機関が同一であるため)になっています。X.509 SVIDの信頼性が担保できると、そこに含まれるSPIFFE IDを元に任意の仕組みでアクセス制御を実現できます。
ワークロード同士でmTLSによる相互認証を行う際は、TLS証明書としてX.509 SVIDとTrust Bundleが利用されます。具体的には、ワークロードAからワークロードBへリクエストされる際にTrust BundleをCA証明書として、ワークロードAのX.509 SVIDをTLSクライアント証明書として、ワークロードBのX.509 SVIDをTLSサーバー証明書としてTLSハンドシェイクが実行されるイメージです。相互認証が完了した後で通信の暗号化にも使えることがX.509 SVIDの利点となっています。
異なるTrust Domain配下のワークロード同士の相互認証
ここではfoo.example.comとbar.example.comの異なるTrust Domain配下でワークロードが稼働していると仮定します。通常であれば、異なるTrust Domain配下のワークロード同士は相互認証ができません。この制約は署名機関が異なることに起因しており、bar.example.comで発行されたX.509 SVIDをfoo.example.comのTrust Bundleでは検証できないことを意味します。
しかし、Bundle Endpointを利用して各Trust Domainの署名機関が、連携するTrust Domainの署名機関に自身のTrust Bundleを配布(Federation)することで、異なるTrust Domain配下のワークロード同士の相互認証を実現できます。連携されたTrust BundleはWorkload APIを介してワークロードに配布されるため、連携されたTrust Domain配下のすべてのワークロードで複数のTrust Bundleが保持され、別Trust Domainのワークロードからのリクエストに載ってくるX.509 SVIDを対応するTrust Bundleで検証できるようになるという仕組みです。なお、mTLSは「同一Trust Domain配下のワークロード同士の相互認証」で紹介したものと同じように実行されます。
Kubernetesへの導入方法
最後に、SPIFFEをKubernetesに導入する方法を紹介します。SPIFFEはあくまで仕様なので、KubernetesにはSPIFFEに準拠したソフトウェアを導入する必要があります。
SPIREを利用する
KubernetesへのSPIFFE導入として1番シンプルな方法は、SPIFFEの参照実装であるSPIREの利用です。SPIREを利用するとPodに任意のSPIFFE IDを含むSVIDを配布できるようになりますが、それを実現するためにはSPIREから提供されるWorkload APIと通信し、SVIDを取得するためのWorkload APIクライアントの機能をPodに備える必要があります。
Workload APIクライアントには、SPIFFEプロジェクトが公式に提供するSPIFFE Helperをコンテナに同梱したり、同じく公式に提供されているSPIFFEライブラリでアプリケーションに機能を組み込むといったアプローチなどが考えれます。公式から提供されているものということでSPIFFE Helperを例に挙げましたが、Podで利用するにはサードパーティ製のpod-svid-helperの方が使いやすいため、pod-svid-helperの利用を検討してみるのも良いかと思います。
また、SPIREではEnvoyのSDS Serverとして振る舞い、SVIDを自動配布する仕組みもサポートされているので、PodのSidecar ProxyとしてEnvoyを導入している環境では、この仕組みを利用するのが手っ取り早いでしょう。
SPIFFEをサポートするService Meshを利用する
SPIREを利用する以外に、SPIFFEをサポートするService MeshプロダクトのIstio、Consul、Kumaなどを利用する方法もあります。これらのプロダクトでService Meshを構築すると、PodのSidecar ProxyとしてインジェクションされるEnvoyに、それぞれのプロダクト仕様のSPIFFE IDを含むSVID が自動でセットされるようになります。
おわりに
今回はSPIFFEが求められた背景やSPIFFEの概要、Kubernetesへの導入方法などを紹介しました。SPIFFEはSPIREと共に2020年6月にCloud Native Computing Foundation(CNCF)のSandboxプロジェクトからIncubatingプロジェクトに昇格したばかりで、様々な企業でSPIREを含むSPIFFEエコシステムの開発が活発に行われています。
また、Pinterest、Square、Uber、Yahoo! Japanなどでは既にSPIFFEが導入されていたり、他の有名企業での利用も進められていたりとコミュニティも拡大してきていることから、非常に注目度が高まっていると感じています。自社インフラのセキュリティ向上を目指していたり、サービス間の認証において課題を抱えていたりする方は、SPIFFEの導入を検討してみるのも良いでしょう。
【参考資料】
最後に参考資料を少しだけ紹介します。
SPIFFEの理解を深めたり、利用を検討する際に他社での事例が気になる方は、公式サイトCommunity Presentationsで公開されているKubeConやSPIFFE Community Dayで過去に発表されたセッションなどを参照するのが良いでしょう。
英語ではなく日本語での参考資料を求めている方は、SPIFFE Meetup Tokyoの過去セッション動画を参照すると良いでしょう。また、SPIFFEの学習中で疑問点などがあればSPIFFE Slackで気軽に質問してみるのも良いかもしれません。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Oracle Cloud Hangout Cafe Season6 #1「Service Mesh がっつり入門!」(2022年9月7日開催)
- FAPI 1.0に準拠したクライアントアプリケーションと リソースサーバの作り方
- KubernetesのDiscovery&LBリソース(その2)
- KubeCon Europe 2024からサービスメッシュのLinkerdの最新情報を紹介
- クライアントポリシーを利用したKeycloakの設定方法と、FAPIリファレンス実装の紹介
- Oracle Cloud Hangout Cafe Season5 #1「Kubernetes Operator 超入門」(2022年1月19日開催)
- Project Calicoのアーキテクチャを見てみよう
- KubeCon Europeでサービスメッシュの標準化を目指すSMIを発表。Istioの動向にも注目
- Oracle Cloud Hangout Cafe Season 4 #5「Kubernetesのオートスケーリング」(2021年8月4日開催)
- セキュリティを手掛けるベンチャーOctarineのCTOに訊いたKubernetesのセキュリティソリューション