SPIRE の Node/Workload Attestation を AWS 上で体感する

# はじめに

今回は、Amazon EC2 インスタンスに SPIRE Server を構築した後に、SPIRE Agent を起動した別インスタンスから Node Attestation を行い、最後にそのインスタンス上で Workload（UNIX系OSで動作するプロセスを例として使います）を起動して Workload Attesttion を行うまでの一連の流れを説明していきたいと思います。SPIRE は [2019年4月23日現在の最新バージョン](https://github.com/spiffe/spire/releases) である `0.7.3` を利用します。

注意事項ですが、当記事では SPIFFE/SPIRE に関する詳細な説明は割愛します。SPIFFE/SPIRE が初めての方は、当記事をご覧頂く前に以下の記事に目を通して頂くと理解が進むかと思います。

- [SPIFFEとその実装であるSPIREについて](https://qiita.com/hiyosi/items/8eec00f396af2050db61)
- [SPIFFEで何が解決できるのか](https://qiita.com/hiyosi/items/6e8d56b257c55a709b4d)

上記に加えて、[2019-05-14 (火) SPIFFFE Meetup Tokyo #1](https://spiffe-jp.connpass.com/event/126507/) で発表された内容も SPIFFE/SPIRE の理解を深めるのに非常に有用なので参考までにどうぞ。

- [Intro SPIFFE](https://speakerdeck.com/hiyosi/intro-spiffe)
- [SPIFFE in Action](https://speakerdeck.com/ainoya/spiffe-in-action)

# 環境構築

まず初めに環境構築を行います。

## EC2インスタンスの起動と IAM User の作成

### EC2インスタンスの起動

Ubuntu 16.04 のインスタンスを2台起動します。VPC、プライベートIP、リージョン、インスタンスタイプ、セキュリティグループなど、細かな設定は自由に設定して下さい。また、インスタンスを起動した後に `ping` などで、各インスタンス同士で通信が行えることを確認しておいてください。

|ホスト名|プライベートIP|タグ|起動させるもの|
|:-:|:-:|:-:|:-:|
|spire-server|172.31.17.242|name:spire-server|SPIRE Server|
|spire-agent|172.31.17.235|name:spire-agent|SPIRE Agent|

ここからの説明では、各インスタンスを指す際に「 `spire-server` ホストで ○○ を XX します」のようにホスト名を使います。説明しやすいようにホスト名をカスタムしておりますが、デフォルトの `ip-xxx-xxx-xxx-xxx` のままでも問題はありません。

### IAM User の作成

SPIRE Server の Node Attester Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_aws_iid.md) と Node Resolver Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_noderesolver_aws_iid.md) の設定を行う際に、各 Plugin が AWS に接続してインスタンス情報を取得するために Access Keys が必要となるので、各 Plugin のドキュメントに記載されている必要なポリシーを満たす IAM User の作成を行います。

#### Node Attester Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_aws_iid.md) に設定する IAM User のポリシー

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        }
    ]
}
```

#### Node Resolver Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_noderesolver_aws_iid.md) に設定する IAM User のポリシー

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "iam:GetInstanceProfile"
            ],
            "Resource": "*"
        }
    ]
}
```

上記のポリシーを持つ IAM User の作成時に表示される Access Keys は、設定時に使うのでメモしておいてください。

## SPIRE Server の構築

### `spire-server` コマンドのインストール

`spire-server` ホストに ubuntu ユーザーで接続してください。

```bash
ssh -i /path/to/key ubuntu@spire-server
```

SPIRE の Release をダウンロードして、中身を `/opt/spire` に展開します。
※ [2019年4月23日現在の最新バージョン](https://github.com/spiffe/spire/releases) である `0.7.3` を利用

```bash
wget https://github.com/spiffe/spire/releases/download/0.7.3/spire-0.7.3-linux-x86_64-glibc.tar.gz
tar xf spire-0.7.3-linux-x86_64-glibc.tar.gz
sudo cp -r spire-0.7.3/. /opt/spire
```

`spire-server` コマンドが使えるように /usr/local/bin 直下に symlink を作成します。

```bash
sudo ln -s /opt/spire/spire-server /usr/local/bin/spire-server
```

`spire-server` コマンドが使えることを確認できたら OK です。

```bash
ubuntu@spire-server:~$ spire-server --version
0.7.3
```

### `sqlite3` コマンドのインストール

SPIRE Server の起動には不要ですが、説明の中で SQLite の中身を参照するのでインストールを行います。

`apt-get` で `sqlite3` をインストールします。

```bash
sudo apt-get update
sudo apt-get install -y sqlite3
```

`sqlite3` コマンドが使えることを確認できたら OK です。

```bash
ubuntu@spire-server:~$ sqlite3 --version
3.11.0 2016-02-15 17:29:24 3d862f207e3adc00f78066799ac5a8c282430a5f
```

### SPIRE Server で利用する Plugins の選定

|Plugin Type|利用するもの|備考|
|:-:|:-:|:-:|
|DataStore|[sql](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_datastore_sql.md)|データベースには `sqllite3` を設定|
|NodeAttestor|[aws_iid](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_aws_iid.md)|AWS Instance Identity document を使って Node の正当性を証明する|
|NodeResolver|[aws_iid](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_noderesolver_aws_iid.md)|AWS Instance Identity document を使って Node の正当性を証明する|
|KeyManager|[disk](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_keymanager_disk.md)|`memory` だと確認が大変なので `disk` に書くように設定|
|UpstreamCA|[disk](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_upstreamca_disk.md)|SPIRE Server 自体を RootCA とする設定|

### 設定ファイルの準備

`/opt/spire/conf/server/server.conf` の内容を以下に変更します。

- trust domain はデフォルトの `example.org` を利用
- `access_key_id` と `secret_access_key` を IAM User 作成時にメモしたものに変更すること
- UpstreamCA Plugin で利用する CAキー と CA証明書 は SPIRE の Release に含まれているものを使用

※ SPIRE Server の設定の詳細は [こちら](https://github.com/spiffe/spire/blob/0.7.3/doc/spire_server.md) を参照下さい

```conf
server {
    bind_address = "0.0.0.0"
    bind_port = "8081"
    registration_uds_path = "/var/run/spire/spire-registration.sock"
    trust_domain = "example.org"
    data_dir = "/opt/spire/data"
    log_level = "DEBUG"
    upstream_bundle = true
    svid_ttl = "1h"
    ca_subject = {
        Country = ["US"],
        Organization = ["SPIFFE"],
        CommonName = "",
    }
}

plugins {
    DataStore "sql" {
        plugin_data {
            database_type = "sqlite3"
            connection_string = "/opt/spire/data/sqlite/datastore.sqlite3"
        }
    }

    NodeAttestor "aws_iid" {
        plugin_data {
            access_key_id = "xxx"
            secret_access_key = "xxx"
        }
    }

    NodeResolver "aws_iid" {
        plugin_data {
            access_key_id = "xxx"
            secret_access_key = "xxx"
        }
    }

    KeyManager "disk" {
        plugin_data = {
            keys_path = "/opt/spire/data/keys"
        }
    }

    UpstreamCA "disk" {
        plugin_data {
            ttl = "1h"
            key_file_path = "/opt/spire/conf/server/dummy_upstream_ca.key"
            cert_file_path = "/opt/spire/conf/server/dummy_upstream_ca.crt"
        }
    }
}
```

### SPIRE Server の起動

起動に必要なディレクトリを作成します。

```bash
sudo mkdir -p /opt/spire/data/sqlite
sudo mkdir -p /var/run/spire
```

ログは標準出力に吐くようにして、フォアグラウンドでプロセスを起動します。

```bash
sudo spire-server run -config /opt/spire/conf/server/server.conf
```

起動時のログから、各 Plugin の初期化が行われていることがわかります。

```bash
ubuntu@spire-server:~$ sudo spire-server run -config /opt/spire/conf/server/server.conf
WARN[0000] Current umask 0022 is too permissive; setting umask 0027.
INFO[0000] data directory: "/opt/spire/data"
INFO[0000] Starting plugin catalog                       subsystem_name=catalog
DEBU[0000] UpstreamCA(disk): configuring plugin          subsystem_name=catalog
DEBU[0000] DataStore(sql): configuring plugin            subsystem_name=catalog
INFO[0000] initializing database.
DEBU[0000] NodeAttestor(aws_iid): configuring plugin     subsystem_name=catalog
DEBU[0000] NodeResolver(aws_iid): configuring plugin     subsystem_name=catalog
DEBU[0000] KeyManager(disk): configuring plugin          subsystem_name=catalog
INFO[0000] plugins started
DEBU[0000] Keypair set "A" does not exist                subsystem_name=ca_manager
DEBU[0000] Keypair set "B" does not exist                subsystem_name=ca_manager
DEBU[0000] Loaded keypair sets                           subsystem_name=ca_manager
DEBU[0000] Preparing keypair set "A"                     subsystem_name=ca_manager
DEBU[0000] Keypair set "A" will expire 2019-04-22T15:06:07Z  subsystem_name=ca_manager
DEBU[0000] Activating keypair set "A"                    subsystem_name=ca_manager
DEBU[0000] Rotating server SVID                          subsystem_name=svid_rotator
DEBU[0000] Signed x509 SVID "spiffe://example.org/spire/server" (expires 2019-04-22T15:06:07Z)  subsystem_name=ca_manager
DEBU[0000] Initializing API endpoints                    subsystem_name=endpoints
INFO[0000] Starting TCP server on [::]:8081              subsystem_name=endpoints
INFO[0000] Starting UDS server /var/run/spire/spire-registration.sock  subsystem_name=endpoints
```

Registration API が UNIXドメインソケット で LISTEN を開始したことが確認できます。

```bash
ubuntu@spire-server:~$ ls -l /var/run/spire/spire-registration.sock
srwxrwx--- 1 root root 0 Apr 22 14:06 /var/run/spire/spire-registration.sock
```

データディレクトリには、以下のファイルが作成されます。

```bash
ubuntu@spire-server:~$ sudo ls -lR /opt/spire/data
/opt/spire/data:
total 12
-rw-r----- 1 root root 1557 Apr 22 14:06 certs.json
-rw-r----- 1 root root  489 Apr 22 14:06 keys
drwxr-xr-x 2 root root 4096 Apr 22 14:06 sqlite

/opt/spire/data/sqlite:
total 120
-rw-r----- 1 root root  4096 Apr 22 14:06 datastore.sqlite3
-rw-r----- 1 root root 32768 Apr 22 14:06 datastore.sqlite3-shm
-rw-r----- 1 root root 82432 Apr 22 14:06 datastore.sqlite3-wal
```

`certs.json` と `keys` の中身は以下のようになります。

```bash
ubuntu@spire-server:~$ sudo cat /opt/spire/data/certs.json
{
	"certs": null,
	"cas": {
		"x509-CA-A": "MIIB7jCCAXSgAwIBAgIBATAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMB4XDTE5MDQyMjE0MDU1N1oXDTE5MDQyMjE1MDYwN1owHjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTB2MBAGByqGSM49AgEGBSuBBAAiA2IABPrt35IAbZBcifsvJMBbBa+A6hh2zL8nw/J9xLHGwN1WU21S0Py40/IqCEgPo0KB6qYmpgT5aVvDUe094hb6qLn237siKt+xpJ0dClSQhEd2YbeEKmciBqmreN9Bl2JsxaOBhTCBgjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJhfWNfaOhZEa+QgvdrMfeaLkAcQwHwYDVR0jBBgwFoAUh6XzV6LwNazA+GTEVOdu07o5yOgwHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5vcmcwCgYIKoZIzj0EAwMDaAAwZQIxAMyei6J1bkDP4b0/QDu0jmUG/CCM48lwokpx/b0C6xaHJkRHLyx9x56pD+AP0hwIPAIwJVGLn8bwGiyT5oLpRYcQbPiXnFnJ5RdLXk22UBy8CbeMt/QbPGk6OpuJOYBd4dDMMIIBzDCCAVOgAwIBAgIJAJM4DhRH0vmuMAoGCCqGSM49BAMEMB4xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKDAZTUElGRkUwHhcNMTgwNTEzMTkzMzQ3WhcNMjMwNTEyMTkzMzQ3WjAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEWjB+nSGSxIYiznb84xu5WGDZj80nL7W1c3zf48Why0ma7Y7mCBKzfQkrgDguI4j0Z+0/tDH/r8gtOtLLrIpuMwWHoe4vbVBFte1vj6Xt6WeE8lXwcCvLs/mcmvPqVK9jo10wWzAdBgNVHQ4EFgQUh6XzV6LwNazA+GTEVOdu07o5yOgwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwGQYDVR0RBBIwEIYOc3BpZmZlOi8vbG9jYWwwCgYIKoZIzj0EAwQDZwAwZAIwE4Me13qMC9i6Fkx0h26y09QZIbuRqA9puLg9AeeAAyo5tBzRl1YL0KNEp02VKSYJAjBdeJvqjJ9wW55OGj1JQwDFD7kWeEB6oMlwPbI/5hEY3azJi16I0uN1JSYTSWGSqWc="
	},
	"public_keys": {
		"JWT-Signer-A": "ClswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARSUivCC3pPTrL2mRvosRyk625n7rosimxy96x/MRVtzjIN8OerLfl4cth3nE2ZzbH7KWpXTz4gaRdDePrySumOEiBiN3pwRU5wTXdKZHNVSmREZVI2c2tBckk2WUpvUDdMaBjfsPflBQ=="
	}
}

ubuntu@spire-server:~$ sudo cat /opt/spire/data/keys
{
	"keys": {
		"JWT-Signer-A": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgrZgf1H6EZs6WxlcJ35TDENBAzYo0mOgA9mflyDbdGZOhRANCAARSUivCC3pPTrL2mRvosRyk625n7rosimxy96x/MRVtzjIN8OerLfl4cth3nE2ZzbH7KWpXTz4gaRdDePrySumO",
		"x509-CA-A": "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBeZ59Jo0Z6a9J8akxi8RswjF2YdQr2dslmhb4ceYw7pf6tJ0d65JKaEabyZmiGpwehZANiAAT67d+SAG2QXIn7LyTAWwWvgOoYdsy/J8PyfcSxxsDdVlNtUtD8uNPyKghID6NCgeqmJqYE+Wlbw1HtPeIW+qi59t+7IirfsaSdHQpUkIRHdmG3hCpnIgapq3jfQZdibMU="
	}
}
```

SQLite の中身を覗いてみると、以下のテーブルが作成されていることがわかります。

- attested_node_entries
- migrations
- bundles
- node_resolver_map_entries
- federated_registration_entries
- registered_entries
- join_tokens
- selectors

```bash
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .tables
attested_node_entries           migrations
bundles                         node_resolver_map_entries
federated_registration_entries  registered_entries
join_tokens                     selectors
```

各テーブルのレコードを確認すると、この時点では `migrations` と `bundles` 以外はレコードなしの状態です。

```bash
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
# カラムを表示するためのおまじない
sqlite> .headers on

# attested_node_entries
sqlite> select * from attested_node_entries;

# migrations
sqlite> select * from migrations;
id|created_at|updated_at|version
1|2019-04-22 14:06:07.30985429+00:00|2019-04-22 14:06:07.30985429+00:00|5

# bundles
sqlite> select * from bundles;
id|created_at|updated_at|trust_domain|data
1|2019-04-22 14:06:07.363437704+00:00|2019-04-22 14:06:07.363437704+00:00|spiffe://example.org|
spiffe://example.org�
�0��0�t�0
*�H�=01
U      0	UUS10

190422150607Z01
U              0	UUS10
SPIFFE0v0*�H�=+�

# node_resolver_map_entries
sqlite> select * from node_resolver_map_entries;

# federated_registration_entries
sqlite> select * from federated_registration_entries;

# registered_entries
sqlite> select * from registered_entries;

# join_tokens
sqlite> select * from join_tokens;

# selectors
sqlite> select * from selectors;
```

各テーブルのカラムは、以下から確認できますので興味ある方はどうぞ。
https://github.com/spiffe/spire/blob/0.7.3/pkg/server/plugin/datastore/sql/models.go

`registered_entries` が空なので、もちろんエントリーも空の状態となります。

```bash
ubuntu@spire-server:~$ sudo spire-server entry show -registrationUDSPath /var/run/spire/spire-registration.sock
Found 0 entries
```

専用のコマンドから Bundle が作成されたことも確認できます。
処理を詳しくは追えてませんが、実体は `bundles` の文字化けしていたレコードなのかなと思っています。

```bash
ubuntu@spire-server:~$ sudo spire-server bundle show -registrationUDSPath /var/run/spire/spire-registration.sock
-----BEGIN CERTIFICATE-----
MIIB7jCCAXSgAwIBAgIBATAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0G
A1UECgwGU1BJRkZFMB4XDTE5MDQyMjE0MDU1N1oXDTE5MDQyMjE1MDYwN1owHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTB2MBAGByqGSM49AgEGBSuBBAAi
A2IABPrt35IAbZBcifsvJMBbBa+A6hh2zL8nw/J9xLHGwN1WU21S0Py40/IqCEgP
o0KB6qYmpgT5aVvDUe094hb6qLn237siKt+xpJ0dClSQhEd2YbeEKmciBqmreN9B
l2JsxaOBhTCBgjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUJhfWNfaOhZEa+QgvdrMfeaLkAcQwHwYDVR0jBBgwFoAUh6XzV6LwNazA
+GTEVOdu07o5yOgwHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5vcmcwCgYI
KoZIzj0EAwMDaAAwZQIxAMyei6J1bkDP4b0/QDu0jmUG/CCM48lwokpx/b0C6xaH
JkRHLyx9x56pD+AP0hwIPAIwJVGLn8bwGiyT5oLpRYcQbPiXnFnJ5RdLXk22UBy8
CbeMt/QbPGk6OpuJOYBd4dDM
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBzDCCAVOgAwIBAgIJAJM4DhRH0vmuMAoGCCqGSM49BAMEMB4xCzAJBgNVBAYT
AlVTMQ8wDQYDVQQKDAZTUElGRkUwHhcNMTgwNTEzMTkzMzQ3WhcNMjMwNTEyMTkz
MzQ3WjAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMHYwEAYHKoZIzj0C
AQYFK4EEACIDYgAEWjB+nSGSxIYiznb84xu5WGDZj80nL7W1c3zf48Why0ma7Y7m
CBKzfQkrgDguI4j0Z+0/tDH/r8gtOtLLrIpuMwWHoe4vbVBFte1vj6Xt6WeE8lXw
cCvLs/mcmvPqVK9jo10wWzAdBgNVHQ4EFgQUh6XzV6LwNazA+GTEVOdu07o5yOgw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwGQYDVR0RBBIwEIYOc3Bp
ZmZlOi8vbG9jYWwwCgYIKoZIzj0EAwQDZwAwZAIwE4Me13qMC9i6Fkx0h26y09QZ
IbuRqA9puLg9AeeAAyo5tBzRl1YL0KNEp02VKSYJAjBdeJvqjJ9wW55OGj1JQwDF
D7kWeEB6oMlwPbI/5hEY3azJi16I0uN1JSYTSWGSqWc=
-----END CERTIFICATE-----
```

証明書の中身はこのようになっております。

```
# 上記の結果を cert ファイルに書き込んだあとに実行
ubuntu@spire-server:~$ openssl x509 -text -noout -in cert
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
    Signature Algorithm: ecdsa-with-SHA384
        Issuer: C=US, O=SPIFFE
        Validity
            Not Before: Apr 22 14:05:57 2019 GMT
            Not After : Apr 22 15:06:07 2019 GMT
        Subject: C=US, O=SPIFFE
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:fa:ed:df:92:00:6d:90:5c:89:fb:2f:24:c0:5b:
                    05:af:80:ea:18:76:cc:bf:27:c3:f2:7d:c4:b1:c6:
                    c0:dd:56:53:6d:52:d0:fc:b8:d3:f2:2a:08:48:0f:
                    a3:42:81:ea:a6:26:a6:04:f9:69:5b:c3:51:ed:3d:
                    e2:16:fa:a8:b9:f6:df:bb:22:2a:df:b1:a4:9d:1d:
                    0a:54:90:84:47:76:61:b7:84:2a:67:22:06:a9:ab:
                    78:df:41:97:62:6c:c5
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                26:17:D6:35:F6:8E:85:91:1A:F9:08:2F:76:B3:1F:79:A2:E4:01:C4
            X509v3 Authority Key Identifier:
                keyid:87:A5:F3:57:A2:F0:35:AC:C0:F8:64:C4:54:E7:6E:D3:BA:39:C8:E8

            X509v3 Subject Alternative Name:
                URI:spiffe://example.org
    Signature Algorithm: ecdsa-with-SHA384
         30:65:02:31:00:cc:9e:8b:a2:75:6e:40:cf:e1:bd:3f:40:3b:
         b4:8e:65:06:fc:20:8c:e3:c9:70:a2:4a:71:fd:bd:02:eb:16:
         87:26:44:47:2f:2c:7d:c7:9e:a9:0f:e0:0f:d2:1c:08:3c:02:
         30:25:51:8b:9f:c6:f0:1a:2c:93:e6:82:e9:45:87:10:6c:f8:
         97:9c:59:c9:e5:17:4b:5e:4d:b6:50:1c:bc:09:b7:8c:b7:f4:
         1b:3c:69:3a:3a:9b:89:39:80:5d:e1:d0:cc
```

以上で、SPIRE Server の構築は完了です。

## SPIRE Agent を起動するための前準備

### `spire-agent` コマンドのインストール

`spire-agent` ホストに ubuntu ユーザーで接続してください。

```bash
ssh -i /path/to/key ubuntu@spire-agent
```

SPIRE の Release をダウンロードして、中身を `/opt/spire` に展開します。
※ [2019年4月23日現在の最新バージョン](https://github.com/spiffe/spire/releases) である `0.7.3` を利用

```bash
wget https://github.com/spiffe/spire/releases/download/0.7.3/spire-0.7.3-linux-x86_64-glibc.tar.gz
tar xf spire-0.7.3-linux-x86_64-glibc.tar.gz
sudo cp -r spire-0.7.3/. /opt/spire
```

`spire-agent` コマンドが使えるように /usr/local/bin 直下に symlink を作成します。

```bash
sudo ln -s /opt/spire/spire-agent /usr/local/bin/spire-agent
```

`spire-agent` コマンドが使えることを確認できたら OK です。

```bash
ubuntu@spire-agent:~$ spire-agent --version
0.7.3
```

### SPIRE Agent が使う設定ファイルの準備

#### SPIRE Agent で利用する Plugins の選定

|Plugin Type|利用するもの|備考|
|:-:|:-:|:-:|
|NodeAttestor|[aws_iid](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_aws_iid.md)|AWS Instance Identity document を使って Node の正当性を証明する|
|KeyManager|[disk](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_keymanager_disk.md)|`memory` だと確認が大変なので `disk` に書くように設定|
|Workload|[unix](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_workloadattestor_unix.md)|UNIXプロセスの情報から Selector を生成する|

#### 設定ファイルの準備

`/opt/spire/conf/agent/agent.conf` の内容を以下に変更します。

- trust domain はデフォルトの `example.org` を利用
- NodeAttestor Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_aws_iid.md) で使う設定値はデフォルト値を明示的に宣言
- trust_bundle_path で利用する CA証明書 は SPIRE の Release に含まれているものを使用

※ SPIRE Agent の設定の詳細は [こちら](https://github.com/spiffe/spire/blob/0.7.3/doc/spire_agent.md) を参照下さい。

```conf
agent {
    data_dir = "/opt/spire/data"
    log_level = "DEBUG"
    server_address = "172.31.17.242"
    server_port = "8081"
    socket_path ="/var/run/spire/agent.sock"
    trust_bundle_path = "/opt/spire/conf/agent/dummy_root_ca.crt"
    trust_domain = "example.org"
}

plugins {
    NodeAttestor "aws_iid" {
        plugin_data {
            identity_document_url = "http://169.254.169.254/latest/dynamic/instance-identity/document"
            identity_signature_url = "http://169.254.169.254/latest/dynamic/instance-identity/signature"
        }
    }
    KeyManager "disk" {
        plugin_data = {
            keys_path = "/opt/spire/data/keys"
        }
    }
    WorkloadAttestor "unix" {
        plugin_data {}
    }
}
```

### 起動に必要なディレクトリを作成

```bash
sudo mkdir -p /var/run/spire
```

以上で、SPIRE Agent を起動するための前準備は完了です。
※ Node Attestation を体感するときに SPIRE Agent を起動するのでここまでの対応で OK

## Workload Attestation の前準備

### Workload Attestation に使う unix ユーザーを作成

今回は、Workload としてUNIX系OSで動作するプロセスを使うので、そのために必要な uid 10000 の `valid-workload` ユーザーと uid 20000 の `invalid-workload` ユーザーを作成します。

```
sudo useradd -u 10000 valid-workload
sudo useradd -u 20000 invalid-workload
```

各ユーザーが作成されていることが確認できたら OK です。

```
ubuntu@spire-agent:~$ id -u valid-workload
10000
ubuntu@spire-agent:~$ id -u invalid-workload
20000
```

以上で、環境構築は完了です。

# Node Attestation を体感する

まずは SPIRE ドメインに参加するための Node 認証の仕組みである Node Attestation を体感していきます。

## SPIRE Agent を起動して Node Attestation を行う

`spire-agent` ホストに ubuntu ユーザーで接続してください。

```bash
ssh -i /path/to/key ubuntu@spire-agent
```

ログは標準出力に吐くようにして、フォアグラウンドでプロセスを起動します。

```bash
sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
```

ログの `DEBU[0000] No pre-existing agent SVID found. Will perform node attestation  subsystem_name=attestor` から Node Attestation が実行されたことがわかります。そして、Node Attestation に成功したことで SPIRE Agent が起動しています。

```bash
ubuntu@spire-agent:~$ sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
WARN[0000] Current umask 0022 is too permissive; setting umask 0027.
INFO[0000] data directory: "/opt/spire/data"
INFO[0000] Starting plugin catalog                       subsystem_name=catalog
DEBU[0000] NodeAttestor(aws_iid): configuring plugin     subsystem_name=catalog
DEBU[0000] KeyManager(disk): configuring plugin          subsystem_name=catalog
DEBU[0000] WorkloadAttestor(unix): configuring plugin    subsystem_name=catalog
DEBU[0000] No pre-existing agent SVID found. Will perform node attestation  subsystem_name=attestor
INFO[0000] Starting workload API                         subsystem_name=endpoints
```

突然 Node Attestation が成功したと言われても納得できないと思いますが、この後で SPIRE Server 側のログを確認しながら説明しますので、この時点ではなにげない理解で大丈夫です。

データディレクトリには、以下のファイルが作成されます。

```bash
ubuntu@spire-agent:~$ sudo ls -l /opt/spire/data
total 8
-rw------- 1 root root 1061 Apr 22 14:10 agent_svid.der
-rw------- 1 root root  962 Apr 22 14:10 bundle.der
```

`spire-agent` ホストに紐づく SPIFFE ID の値を確認するために、`spire-agent` ホストの Account ID、Region、Instance ID を確認します。

```bash
ubuntu@spire-agent:~$ curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | egrep 'accountId|instanceId|region'
  "accountId" : "XXXXXXXXXXXX",
  "instanceId" : "i-00fc2dca2309d04d7",
  "region" : "ap-northeast-1"
```

※ http://169.254.169.254/latest/dynamic/instance-identity/document は [インスタンスメタデータを取得するための URL](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
※ Account ID は意図的に伏せています

Account ID、Region、Instance ID は以下となりました。

|プロパティ|値|
|:-:|:-:|
|Account ID|XXXXXXXXXXXX|
|Region|ap-northeast-1|
|Instance ID|i-00fc2dca2309d04d7|

SPIRE Server の Node Attester Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_aws_iid.md) では、 `spiffe://example.org/spire/agent/aws_iid/ACCOUNT_ID/REGION/INSTANCE_ID` というルールで SPIFFE ID が登録される仕様のため、想定通りいけば `spire-agent` ホストに紐づく SPIFFE ID は `spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7` となります。

## SPIRE Server のログを確認してみる

SPIRE Server 側のログを確認してみます。

```bash
ubuntu@spire-server:~$ sudo spire-server run -config /opt/spire/conf/server/server.conf
...
DEBU[0252] Signing CSR for Agent SVID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7  subsystem_name=node_api
DEBU[0252] Signed x509 SVID "spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7" (expires 2019-04-22T15:06:07Z)  subsystem_name=ca_manager
INFO[0252] Node attestation request from 172.31.17.235:33086 completed using strategy aws_iid  subsystem_name=node_api
```

以下のログから、想定通り `spire-agent` ホストに紐づく SPIFFE ID `spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7` が登録されたことがわかります。

```bash
DEBU[0252] Signing CSR for Agent SVID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7  subsystem_name=node_api
DEBU[0252] Signed x509 SVID "spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7" (expires 2019-04-22T15:06:07Z)  subsystem_name=ca_manager
```

また、以下のログから `spire-agent` ホストからの Node Attestation が完了したことがわかります。

```bash
INFO[0252] Node attestation request from 172.31.17.235:33086 completed using strategy aws_iid  subsystem_name=node_api
```

## SQLite の中身を確認してみる

Node Attestation 前後で変化があったテーブルは `attested_node_entries` と `node_resolver_map_entries` となります。

```bash
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
# カラムを表示するためのおまじない
sqlite> .headers on

# attested_node_entries
sqlite> select * from attested_node_entries;
id|created_at|updated_at|spiffe_id|data_type|serial_number|expires_at
1|2019-04-22 14:10:19.469466093+00:00|2019-04-22 14:10:19.469466093+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|2|2019-04-22 15:06:07+00:00

# node_resolver_map_entries
sqlite> select * from node_resolver_map_entries;
id|created_at|updated_at|spiffe_id|type|value
1|2019-04-22 14:10:19.468130215+00:00|2019-04-22 14:10:19.468130215+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|sg:id:sg-012874274efb978c7
2|2019-04-22 14:10:19.46821413+00:00|2019-04-22 14:10:19.46821413+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|sg:name:Ubuntu 16-04 LTS - Xenial -HVM--Ubuntu 16-04 LTS 20190212-AutogenByAWSMP-1
3|2019-04-22 14:10:19.468289052+00:00|2019-04-22 14:10:19.468289052+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|tag:name:spire-agent
```

各テーブルのレコードを詳しく見ていきましょう。

### attested_node_entries

SPIRE Server のログにも出力されていたとおり Node Attestation に成功したホストの情報が書き込まれています。

|id|spiffe_id|data_type|serial_number|expires_at|
|:-:|:-:|:-:|:-:|:-:|
|1|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|2|2019-04-22 15:06:07+00:00|

※ 表が見づらくなるので timestamp 系のカラムは除いてます

### node_resolver_map_entries

SPIRE Server の Node Resolver Plugin ["aws_iid"](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_noderesolver_aws_iid.md) では、以下4つの Selector が生成される仕様となっております。

- Instance Tag
- Security Group ID
- Security Group Name
- IAM Role

自分の環境だと IAM Role を設定していなかったので、3つの Selector が生成されました。
上から Security Group ID、Security Group Name、Instance Tag となります。

|id|spiffe_id|type|value|
|:-:|:-:|:-:|:-:|
|1|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|`sg:id:sg-012874274efb978c7`|
|2|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|`sg:name:Ubuntu 16-04 LTS - Xenial -HVM--Ubuntu 16-04 LTS 20190212-AutogenByAWSMP-1`|
|3|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|`tag:name:spire-agent`|

※ 表が見づらくなるので timestamp 系のカラムは除いてます

以上が、Node Attestation となります。

# Workload Attestation を体感する

次に、任意の Workload から SVID を取得するための認証の仕組みである Workload Attestation を体感していきます。

## SPIRE Server に Entry を登録する

`spire-server` ホストに ubuntu ユーザーで接続してください。

```bash
ssh -i /path/to/key ubuntu@spire-server
```

`spire-agent` ホスト上で uid 10000 の `valid-workload` ユーザーから実行されるUNIXプロセスを認証を許可する Workload として Entry に登録します。ParentID には Node Attestation の際に登録された `spire-agent` ホストの SPIFFEE ID を設定し、SPIFFE ID には Workload に紐付ける任意の SPIFFE ID を設定し、Selector には uid 10000 から実行されるプロセスが対象となるように値（Workload Attester Plugin "unix" の詳細は [こちら](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_workloadattestor_unix.md)）を設定します。

```
sudo spire-server entry create \
    -registrationUDSPath /var/run/spire/spire-registration.sock \
    -parentID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 \
    -spiffeID spiffe://example.org/host/valid-workload \
    -selector unix:uid:10000
```

以下のような実行結果となります。

```bash
ubuntu@spire-server:~$ sudo spire-server entry create \
>     -registrationUDSPath /var/run/spire/spire-registration.sock \
>     -parentID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 \
>     -spiffeID spiffe://example.org/host/valid-workload \
>     -selector unix:uid:10000
Entry ID      : 9d0d2673-bf2b-42d3-9235-2090e9050fb4
SPIFFE ID     : spiffe://example.org/host/valid-workload
Parent ID     : spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7
TTL           : 3600
Selector      : unix:uid:10000
```

SPIRE Server のログにも Entry が登録され、SVID が発行されたログが出力されます。

```bash
ubuntu@spire-server:~$ sudo spire-server run -config /opt/spire/conf/server/server.conf
...
DEBU[3107] Signing SVID for spiffe://example.org/host/valid-workload on request by spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7  subsystem_name=node_api
DEBU[3107] Signed x509 SVID "spiffe://example.org/host/valid-workload" (expires 2019-04-22T15:36:07Z)  subsystem_name=ca_manager
```

専用のコマンドから Entry が追加されたことも確認できました。

```bash
ubuntu@spire-server:~$ sudo spire-server entry show -registrationUDSPath /var/run/spire/spire-registration.sock
Found 1 entry
Entry ID      : 9d0d2673-bf2b-42d3-9235-2090e9050fb4
SPIFFE ID     : spiffe://example.org/host/valid-workload
Parent ID     : spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7
TTL           : 3600
Selector      : unix:uid:10000
```

SQLite の中身を確認してみると `registered_entries` と `selectors` にレコードが追加されたことがわかります。

```bash
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
# カラムを表示するためのおまじない
sqlite> .headers on

# registered_entries
sqlite> select * from registered_entries;
id|created_at|updated_at|entry_id|spiffe_id|parent_id|ttl|admin
1|2019-04-22 14:57:52.177533369+00:00|2019-04-22 14:57:52.177533369+00:00|9d0d2673-bf2b-42d3-9235-2090e9050fb4|spiffe://example.org/host/valid-workload|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|3600|0

# selectors
sqlite> select * from selectors;
id|created_at|updated_at|registered_entry_id|type|value
1|2019-04-22 14:57:52.177715825+00:00|2019-04-22 14:57:52.177715825+00:00|1|unix|uid:10000
```

## valid-workload ユーザーでプロセスを実行して Workload Attestation を行う

`spire-agent` ホストに ubuntu ユーザーで接続してください。

```bash
ssh -i /path/to/key ubuntu@spire-agent
```

SVID を取得する際に Workload Attestation が必須となるので、SVID を取得するためのコマンドを uid 10000 の `valid-workload` ユーザーで実行してみます。

```bash
sudo -u valid-workload spire-agent api fetch x509 -socketPath /var/run/spire/agent.sock
```

認証が許可された Workload として Entry に追加してあるので、Workload Attestation が成功して SVID の情報を取得することができました。

```bash
ubuntu@spire-agent:~$ sudo -u valid-workload spire-agent api fetch x509 -socketPath /var/run/spire/agent.sock
Received 1 bundle after 2.006431ms

SPIFFE ID:		spiffe://example.org/host/valid-workload
SVID Valid After:	2019-04-22 14:57:44 +0000 UTC
SVID Valid Until:	2019-04-22 15:36:07 +0000 UTC
Intermediate #1 Valid After:	2019-04-22 14:35:57 +0000 UTC
Intermediate #1 Valid Until:	2019-04-22 15:36:07 +0000 UTC
CA #1 Valid After:	2019-04-22 14:05:57 +0000 UTC
CA #1 Valid Until:	2019-04-22 15:06:07 +0000 UTC
CA #2 Valid After:	2018-05-13 19:33:47 +0000 UTC
CA #2 Valid Until:	2023-05-12 19:33:47 +0000 UTC
CA #3 Valid After:	2019-04-22 14:35:57 +0000 UTC
CA #3 Valid Until:	2019-04-22 15:36:07 +0000 UTC
CA #4 Valid After:	2019-04-22 15:05:57 +0000 UTC
CA #4 Valid Until:	2019-04-22 16:06:07 +0000 UTC
```

以下のように `-write` オプションで、SVID と Bundle をディスクに書き込むことも可能です。

```bash
sudo -u valid-workload spire-agent api fetch x509 \
    -socketPath /var/run/spire/agent.sock -write /tmp
```

以下、例となります。

```bash
ubuntu@spire-agent:~$ sudo -u valid-workload spire-agent api fetch x509 \
>     -socketPath /var/run/spire/agent.sock -write /tmp
Received 1 bundle after 1.660049ms

SPIFFE ID:		spiffe://example.org/host/valid-workload
SVID Valid After:	2019-04-22 15:16:49 +0000 UTC
SVID Valid Until:	2019-04-22 15:36:07 +0000 UTC
Intermediate #1 Valid After:	2019-04-22 14:35:57 +0000 UTC
Intermediate #1 Valid Until:	2019-04-22 15:36:07 +0000 UTC
CA #1 Valid After:	2019-04-22 14:05:57 +0000 UTC
CA #1 Valid Until:	2019-04-22 15:06:07 +0000 UTC
CA #2 Valid After:	2018-05-13 19:33:47 +0000 UTC
CA #2 Valid Until:	2023-05-12 19:33:47 +0000 UTC
CA #3 Valid After:	2019-04-22 14:35:57 +0000 UTC
CA #3 Valid Until:	2019-04-22 15:36:07 +0000 UTC
CA #4 Valid After:	2019-04-22 15:05:57 +0000 UTC
CA #4 Valid Until:	2019-04-22 16:06:07 +0000 UTC

Writing SVID #0 to file /tmp/svid.0.pem.
Writing key #0 to file /tmp/svid.0.key.
Writing bundle #0 to file /tmp/bundle.0.pem.

# SVID と Bundle がディスクに書き込まれた
ubuntu@spire-agent:~$ ll /tmp/svid.0.pem
-rw-r--r-- 1 valid-workload valid-workload 1482 Apr 22 15:17 /tmp/svid.0.pem
ubuntu@spire-agent:~$ ll /tmp/svid.0.key
-rw-r--r-- 1 valid-workload valid-workload 241 Apr 22 15:17 /tmp/svid.0.key
ubuntu@spire-agent:~$ ll /tmp/bundle.0.pem
-rw-r--r-- 1 valid-workload valid-workload 2875 Apr 22 15:17 /tmp/bundle.0.pem
```

SPIRE Agent のログからは Workload Attestation を行おうとした Workload の Selector 情報が確認できます。この出力された Selector 情報が Entry で追加したものと一致するため、Workload Attestation が成功となったわけです。

```bash
ubuntu@spire-agent:~$ sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
...
DEBU[3606] PID 2082 attested to have selectors [type:"unix" value:"uid:10000"  type:"unix" value:"user:valid-workload"  type:"unix" value:"gid:10000"  type:"unix" value:"group:valid-workload" ]  subsystem_name=workload_api
```

## invalid-workload ユーザーでプロセスを実行して Workload Attestation が失敗するか確認する

Workload Attestation が成功するパターンは確認できたので、次は失敗するパターンを試してみます。

Entry に登録されていない uid 20000 の `invalid-workload` ユーザーで SVID の取得を行おうとすると、Permission Denied なエラー終了となります。

```bash
ubuntu@spire-agent:~$ sudo -u invalid-workload spire-agent api fetch x509 -socketPath /var/run/spire/agent.sock
rpc error: code = PermissionDenied desc = no identity issued
```

SPIRE Agent のログからは Workload Attestation を行おうとした Workload の Selector 情報が確認できます。この出力された Selector 情報が許可された Workload として Entry に存在しないため、Workload Attestation が失敗となりました。

```bash
ubuntu@spire-agent:~$ sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
...
DEBU[4228] PID 2137 attested to have selectors [type:"unix" value:"uid:20000"  type:"unix" value:"user:invalid-workload"  type:"unix" value:"gid:20000"  type:"unix" value:"group:invalid-workload" ]  subsystem_name=workload_api
```

以上が、Workload Attestation となります。

# 補足

## Node Attestation について

今回は AWS 上での Node Attestation となりましたが、インスタンスの正当性を証明するための Node Attester（Server/Agent 両方）があれば、任意のプラットフォームで Node Attestation を行うことが可能です。SPIRE に Built-in されているものだと以下があります。

|プラットフォーム|Server plugin|Agent plugin|備考|
|:-:|:-:|:-:|:-:|
|Azure|[azure_msi](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_azure_msi.md)|[azure_msi](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_azure_msi.md)|Azure MSI token を使う|
|GCP|[gcp_iit](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_gcp_iit.md)|[gcp_iid](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_gcp_iit.md)|GCP Instance Identity Token を使う|
|Kubernetes|[k8s_sat](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_k8s_sat.md)|[k8s_sat](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_k8s_sat.md)|Kubernetes Service Account token を使う|
|どこでも使える|[join_token](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_jointoken.md)|[join_token](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_jointoken.md)|SPIRE Server からワンタイムトークンを発行して SPIRE Agent 起動時に渡す|
|どこでも使える|[x509pop](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_server_nodeattestor_x509pop.md)|[x509_pop](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_nodeattestor_x509pop.md)|X.509 証明書を使う|

また、OSS としても公開されているものもあります。

|プラットフォーム|Server plugin|Agent plugin|備考|
|:-:|:-:|:-:|:-:|
|OpenStack|[openstack_iid](https://github.com/zlabjp/spire-openstack-plugin/blob/master/doc/openstack-iid-attestor.md#configuring-the-server-plugin)|[openstack_iid](https://github.com/zlabjp/spire-openstack-plugin/blob/master/doc/openstack-iid-attestor.md#configuring-agent-plugin)|OpenStack InstanceID を使う|

## Workload Attestation について

今回は UNIXプロセスを Workload として使いましたが、Workload から任意のルールで Selector を発行できる Workload Attester があれば、任意の Workload で Workload Attestation を行うことが可能です。SPIRE に Built-in されているものだと以下があります。

|Workload|Plugin|備考|
|:-:|:-:|:-:|
|Kubernetes Resource|[k8s](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_workloadattestor_k8s.md)|Namespace と Service Account を Selector として発行します|
|Docker Container|[docker](https://github.com/spiffe/spire/blob/0.7.3/doc/plugin_agent_workloadattestor_docker.md)|Label と Image ID を Selector として発行します|

# さいごに

今回は、AWS を使って SPIRE の Node Attestation と Workload Attestation を体感する流れを紹介しました。各処理を実行しながら、ログを確認したり、どのようなデータが保存されるかを追いかけたりと、冗長な流れとなってしまいましたが、参考程度に活用頂けたらと思います。

Node Attestation、Workload Attestation を経て、最終的に Workload が SVID と Bundle が取得できる（Workload が Node 上にファイルとして書き込むことも可能）ことを理解頂いたと思いますが、その SVID と Bundle を用いたユースケースとして SPIRE の公式ページでは以下が紹介されております。

- サービス間の安全な認証
- [Vault](https://www.hashicorp.com/products/vault/) と [Knox](https://github.com/pinterest/knox) からのシークレット取得
- [Envoy](https://blog.envoyproxy.io/securing-the-service-mesh-with-spire-0-3-abb45cd79810) などのサービスメッシュ内のサイドカープロキシを識別するための基盤としてのIDプロビジョニング
- 分散システムの認証に使用する PKI のプロビジョニングとローテーション

https://spiffe.io/spire/#use-cases

上記のユースケースも踏まえて、SPIFFE/SPIRE は今後より盛り上がってくる OSS だと思いますので、引き続き情報を追いかけていきたいと思います。

# 参考資料

- [SPIFFEとその実装であるSPIREについて](https://qiita.com/hiyosi/items/8eec00f396af2050db61)
- [SPIFFEで何が解決できるのか](https://qiita.com/hiyosi/items/6e8d56b257c55a709b4d)
- [spiffe.io](https://spiffe.io/)
- [KubeCon NA 2018 SPIFFE Intro（ PDF ）](https://kccna18.sched.com/event/HtJu/intro-spiffe-andrew-jessup-daniel-feldman-scytale)
- [Cloud Native Identity with SPIFFE](https://www.slideshare.net/prabathsiriwardena/cloud-native-identity-with-spiffe)