SPIFFEで何が解決できるのか

## はじめに

昨年にSPIFFEの記事を書いてからSPIFFE自体もアップデートされている部分もありますので、最新の情報にあわせて改めてSPIFFEで何が解決できるのか？について簡単に整理したいと思います。

## SPIFFEは何を解決するのか

SPIFFEはZero Trust Networkの考え方にもとづくサービス間認証の仕様です。
これらは新しいものではなく、2002年に発表されたPlan9 security design、2005年に発表されたGoogleのLOASの流れを汲んでいます。

近年のMicroservice化されたシステムのようなworkload間の通信において **送信元が信頼できるか** 、 **メッセージの正当性を信じられるか** というような課題を、どのような環境(cloud/on-prem, container/VM)であっても、各workloadは **同一インタフェースで確認できる** フレームワークの仕様です。またSPIFFEは異なるドメイン間で利用する場合においても**中央管理を必要しません**。

SPIFFEではこれをどのようにして実現するのか、重要となるSVID, Workload API, Federation という点から整理していきます。

### SVID

SPIFFEではSVID(SPIFFE Verifiable Identity Document)というworkloadのideneityを証明するデータ形式が定義されており、X.509形式のTLS証明書を使ったX.509-SVIDとJWT(Json Web Token)を使ったJWT-SVIDの２つがあります。
workloadはSVIDとそれを検証するための証明書バンドルをAPIを介してコントロールプレーンから取得します。

また、どちらのSVIDもworkloadのidentityとしてSPIFFE IDを含みます。

#### SPIFFE ID
https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md

URI形式で所属するトラストドメインと必要に応じて動作している環境などを含めてworkloadのideneityを表現します。

```
spiffe://staging.example.com/payments/web-fe
```
```
spiffe://k8s-west.example.com/ns/staging/sa/default
```
```
spiffe://example.com/9eebccd2-12bf-40a6-b262-65fe0487d453
```

#### X.509-SVID
https://github.com/spiffe/spiffe/blob/master/standards/X509-SVID.md

X.509証明書の`SAN`フィールドに自身のSPIFFE IDがセットされています。TLSを終端する側ではSANの値によって通信を受け入れるかどうかを判断します。

#### JWT-SVID

https://github.com/spiffe/spiffe/blob/master/standards/JWT-SVID.md

TLSがworkloadではなくもっと前段で終端されているようなケースの場合、X.509-SVIDではエンドツーエンドの相互認証ができません。そのようなケースをカバーするものとしてJWT-SVIDがあります。

`sub`に送信元である自分自身のSPIFFE IDを, `aud` には一つ以上の送信先のSPIFFE IDをセットします。
したがってデータを受け取った側ではsubの値によって送信元を確認し、audに自身が含まれているかによって意図した通信先なのかどうかを確認できます。
その他は基本的にJWTの仕様に従って検証すればよいと思います。

### Workload API

Workload APIはworkloadが自身を証明するための証明書やJWTを取得したりそれらを検証するためのデータを取得するために使われます。
Workload APIはベンダーニュートラルなAPIとなっており、どのような環境(GCP, AWS, VM, ...)でもworkloadは同じ方法で自身のIdenittyと証明書バンドルを取得することができます。

<img width="747" alt="Screen Shot 2018-12-15 at 13.18.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/15164/359b2e40-19c0-7658-0531-8dfaf8b36bf7.png">

### Federation

Federationは複数の異なるドメイン間(k8sなら例えば別々のクラスタなど)で証明書バンドルを共有します。将来的にはFederation APIというものが定義されるのですが、現時点ではまだ公開されておらず、今は別のAPIを拡張して実現しています。
Federationより、workloadは異なるドメインからの通信について、Federationされているドメイン間であれば送信元の正しさを確認することができます。

<img width="725" alt="Screen Shot 2018-12-15 at 13.28.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/15164/eb9b56fe-e87f-6eee-db2c-725e7dcd9329.png">

さらにWorkload APIのようなベンダーニュートラルなAPIのおかけで、それぞれのドメインが異なる環境で動作していても同じ方法でSVIDと証明書バンドルを取得できます。SPIFFEは中央管理の仕組みをもたないため、コントロールプレーンはそれぞれの環境毎のインスタンス管理の仕組みと連携してworkloadのSVIDを生成します。

<img width="816" alt="Screen Shot 2018-12-15 at 21.35.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/15164/a0ac9182-a5a0-0e7c-4f24-af590e26571f.png">

## SPIFFEを利用するには？

SPIFFEの実装としては以下のものがあります。

- SPIRE
- Istio 
- HashiCorp Consul Connect

現時点ではIstioやConsul Connectは異なるドメイン間での検証ができないため、Federationが必須な場合にはSPIREが選択肢となるでしょう。

## 終わりに

KubeCon + CloudNativeCon North America 2018 でもSPIFFEのセッションが増えてきており、k8sのSIG-AuthやContainer Identity WG関連のセッションなどでも言及されていました。セッションに参加していた人の多くははk8sで利用する際のIstioとの違いについて気にしていたのではないかと思います。より多くの機能を持っているIstioも今後はマルチドメインでの認証といったこともサポートされると思いますので、今後もサービス認証関連のプロダクトの動向に注目していきたいと思います。

来年は機会があればSPIFFE関連のMeetupを開催できたらいいなと思っています。