Kubernetes: Policy Report API について

## Policy Report API

[Policy Report API](https://github.com/kubernetes-sigs/wg-policy-prototypes/tree/0fc2ddc5d3e396e9356e1769a1c0935cce1ba963/policy-report) は Kubernetes クラスタの管理者にポリシーの評価結果を提供するための CRD で、[Kubernetes Policy Working Group](https://github.com/kubernetes/community/tree/master/wg-policy) によって設計・開発が進められています。Policy Report CRD と記載されているケースも多いですが、この記事では Policy Report API と記載しています。

2024年4月時点で最新の API バージョン [reports.x-k8s.io/v1beta2](https://htmlpreview.github.io/?https://github.com/kubernetes-sigs/wg-policy-prototypes/blob/master/policy-report/docs/index.html) では、クラスタ全体の評価結果を格納する `ClusterPolicyReport` リソースと、Namespace 単位での評価結果を格納する `PolicyReport` リソースがサポートされています。

以下は Kyverno によって作成された `PolicyReport` リソースの例です。

```bash
$ kubectl get policyreports                                              
NAME                PASS   FAIL   WARN   ERROR   SKIP   AGE
sample-v1beta2-cr   1      0      0      0       0      24s

$ kubectl get policyreports sample-v1beta2-cr -o yaml
...
```

ポリシーの評価結果のサマリーや直近の評価結果が格納されていることが確認できます。

```yaml
apiVersion: reports.x-k8s.io/v1beta1
kind: PolicyReport
metadata:
  name: sample-v1beta2-cr
  annotations:
    name: Sample CR
configuration:
  limits:
    maxResults: 100
    statusFilter:
      - pass
      - fail
      - skip
source: kyverno
summary:
  pass: 1
  fail: 0
  warn: 0
  error: 0
  skip: 0
results:
  - category: Pod Security Standards (Baseline)
    message: validation rule 'adding-capabilities' passed.
    policy: disallow-capabilities
    resources:
    - apiVersion: v1
      kind: Pod
      name: kyverno-6d88f6dcdd-k6bc5
      namespace: nirmata
      uid: 3407b31a-b0bb-4716-a443-f4aa15662ef2
    result: pass
    rule: adding-capabilities
    scored: true
    severity: medium
    source: kyverno
    timestamp:
      nanos: 0
      seconds: 1679565894
```

## Policy Report API が提案された背景

2020年に作成された [Proposal](https://docs.google.com/document/d/1nICYLkYS1RE3gJzuHOfHeAC25QIkFZfgymFjgOzMDVw/edit#heading=h.wn242twwl364) をベースに Policy Report API が設計・開発された背景を紹介します。

Kubernetes クラスタを安全に運用していくためには不適切な設定や操作を防ぐことが重要で、それを実現するために [Falco](https://github.com/falcosecurity/falco) や [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) や [Kyverno](https://github.com/kyverno/kyverno/) など様々なサードパーティ製のソフトウェアが存在しています。

これらのソフトウェアは事前に定義されたポリシーを元にクラスタに対する操作を評価して、不適切なものを検知した際にはエラーとして報告してくれますが、各ソフトウェアでフォーマットが異なるため、複数のポリシーエンジンを運用している際に統合的にポリシーの評価結果を見られない課題がありました。

このフォーマットを Kubernetes リソースとして標準化できると、ポリシーの評価結果を管理しやすくなったり、統合的に監査・分析したりすることが可能になるため、Policy Report API が提案されました。

ちなみに現時点では Kubernetes の標準機能には組み込まれていません。

## Policy Report API の Adapter

Kubernetes Policy Working Group では、既存のポリシーエンジンの評価結果を Policy Report リソースに変換する Adapter が提供されていて、現時点では以下のソフトウェアがサポートされています。

### Kube-bench

[Kube-bench](https://github.com/aquasecurity/kube-bench) は Kubernetes クラスタが [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes) で定義されているセキュリティのベストプラクティスに従ってデプロイされているかをチェックするツールです。

Kube-bench の評価結果を Policy Report リソースで出力するためには [kube-bench-adapter](https://github.com/kubernetes-sigs/wg-policy-prototypes/tree/master/policy-report/kube-bench-adapter) を利用します。kube-bench-adapter は Kube-bench のラッパーで評価結果を `ClusterPolicyReport` リソースに変換してクラスタに作成する仕組みになっています。

![kube-bench-adapter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/f59c79fd-a365-8748-0c0e-177b0bbf4820.png)

### KubeArmor

[KubeArmor](https://github.com/kubearmor/KubeArmor) は eBPF と Linux Security Modules (LSM) などの機能を利用してコンテナなどの動作を制限するランタイムセキュリティツールです。

KubeArmor の評価結果を Policy Report リソースで出力するためには [kubearmor-adapter](https://github.com/kubernetes-sigs/wg-policy-prototypes/tree/master/policy-report/kubearmor-adapter) を利用します。kubearmor-adapter は KubeArmor のアラートを監視して、その評価結果を `PolicyReport` リソースに変換してクラスタに作成する仕組みになっています。

### Trivy

[Trivy](https://github.com/aquasecurity/trivy) はコンテナイメージやファイルシステムなどをスキャンして、脆弱性や設定ミスなどを検知する多機能なセキュリティスキャナーです。

Trivy の評価結果を Policy Report リソースで出力するためには [trivy-adapter](https://github.com/kubernetes-sigs/wg-policy-prototypes/tree/master/policy-report/trivy-adapter) を利用します。trivy-adapter は Trivy のラッパーで評価結果を `PolicyReport` リソースに変換してクラスタに作成する仕組みになっています。

![trivy-adapter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/41f430a9-47d2-d346-a867-3f70a0110595.png)

## Policy Report リソースの出力をサポートしているソフトウェア

以下のソフトウェアでは評価結果を Policy Report リソースとして出力する機能がサポートされています。ここで挙げているのは一部なので、一覧を見たい方は後述の KEP 内のリストをご参照ください。

### Kyverno

[Kyverno](https://github.com/kyverno/kyverno) は Kubernetes 向けのポリシーエンジンで、Validating/Mutating Admission Webhook としてリクエストされたオブジェクトを制御したり、コンテナイメージの検証をしたりすることができます。

記事の冒頭でも `PolicyReport` リソースの例として紹介しましたが、Kyverno は評価結果を `ClusterPolicyReport` リソースと `PolicyReport` リソースとして出力する仕様になっています。詳細は Kyverno の[公式ドキュメント](https://kyverno.io/docs/policy-reports/)をご参照ください。

### Falco

[Falco](https://github.com/falcosecurity/falco) は OS 内での異常な動作や潜在的なセキュリティの脅威を検知するランタイムセキュリティツールです。

Falco コミュニティでは、Falco で検知したイベントを外部ツールと連携させる [Falcosidekick](https://github.com/falcosecurity/falcosidekick) を提供していて、その連携先の1つとして Policy Report リソースが[サポート](https://github.com/falcosecurity/falcosidekick/blob/master/docs/outputs/policy_report.md)されています。連携を有効にすると Flaco での評価結果を `ClusterPolicyReport` リソースと `PolicyReport` リソースに変換してクラスタに作成するようになります。

![falco-adapter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/889510c4-41c4-93fc-fd45-7595e4b97b9f.png)

### Gatekeeper (未サポート)

[Gatekeeper](https://github.com/open-policy-agent/gatekeeper) は OPA をベースにした Kubernetes 向けのポリシーエンジンで Validating/Mutating Admission Webhook としてリクエストされたオブジェクトを制御する機能を持っています。

Gatekeeper でも [#2394](https://github.com/open-policy-agent/gatekeeper/issues/2394) や [#710](https://github.com/open-policy-agent/gatekeeper/issues/710) で Policy Report API をサポートする議論がされていましたが、リソースにする評価結果のスコープやリソースが増大した際の API Server と etcd への負荷を懸念して議論が長引いてクローズされてしまいました。

当時は Policy Report API に評価結果の最大数を記録するフィールドが定義されておらず方針がまとまらなかったですが、現在は最大数を示すフィールドも追加されたので Gatekeeper でサポートされる日もそう遠くないかもしれません。

## Policy Report リソースの利用をサポートするソフトウェア

ここで挙げているのは一部なので、一覧を見たい方は後述の KEP 内のリストをご参照ください。

### Policy Reporter

[Policy Reporter](https://github.com/kyverno/policy-reporter) は Policy Report リソースの情報を Loki や Elasticsearch や Slack などに連携するツールで Kyverno コミュニティでメンテナンスされています。オプショナル機能としてメトリクスも出力できるので評価結果を Prometheus で監視することも可能になります。更に Web UI が必要な場合は [Policy Reporter UI](https://github.com/kyverno/policy-reporter-ui) を利用しましょう。

## 今後について

[KEP-4447: Promote PolicyReport API to a Kubernetes SIG API](https://github.com/kubernetes/enhancements/pull/4448) という KEP がレビュー中で、Policy Report API を Kubernetes SIG の公式プロジェクトにする動きがあります。

KEP 内では Policy Report API の活用を促進させることを目的としていて、https://github.com/kubernetes-sigs/policy-report-api プロジェクトの作成と利用方法の提供をゴールとしています。

## さいごに

今回はポリシーの評価結果を Kubernetes リソースとして扱える Policy Report API を紹介しました。今後、Pod Security Admission を含む Admission Controls や Validating Admission Policy など、Kubernetes に標準で組み込まれている機能の評価結果も Policy Report API として出力されるようになるかは不明ですが、Policy Report API の活用事例などは出てきそうなので今後も動向をウォッチしていきたいと思います。

## 備考

この記事に添付している画像は KubeCon + CloudNativeCon North America 2022 のセッションの [PolicyReport CRD: Manage Admission Control, Runtime, and Scan Reports!](https://youtu.be/tG-YLGF9_Aw) から引用しています。