K8s StructuredAuthorizationConfiguration

## StructuredAuthorizationConfigurationとは

:::note warn
この記事は v1.29でのalphaリリース時点の情報を参考にしています。
将来のリリースではAPIや挙動が変更になる可能性があります。
:::


KEP: https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/3221-structured-authorization-configuration

Doc: https://kubernetes.io/docs/reference/access-authn-authz/authorization/#configuring-the-api-server-using-an-authorization-config-file

K8sにおける認可チェーンの設定をフラグベースから設定ファイルで指定できるようにする機能(フィーチャーゲート)です。

他にも、複数のWebhookをチェーンに指定できるようなったことでクラスタ起動時にある条件が整うまで管理者やシステムユーザ以外のユーザをブロックしたり(※)、CEL式でフィルタリングルールを記述できるようになったことで、不要なリクエストがWebhookサーバに送られなくなるというような利点があります。

※ https://groups.google.com/g/kubernetes-sig-api-machinery/c/MBa19WTETMQ のような起動時に特定のCRDの準備が整うまでブロックしたいようなユースケースに対応できます。

## AuthorizationConfiguration 

設定ファイルは`AuthorizationConfiguration`の仕様に従って記述します。

see: https://github.com/kubernetes/kubernetes/blob/v1.29.0/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go#L230-L238

e.g. [Protecting installed CRDs](https://github.com/kubernetes/enhancements/tree/e09ddc24172ee3b7766cf427ee242bc64bab1901/keps/sig-auth/3221-structured-authorization-configuration#story-1-protecting-installed-crds)
``` yaml
apiVersion: apiserver.config.k8s.io/v1alpha1
kind: AuthorizationConfiguration
authorizers:
  - type: Webhook
    name: system-crd-protector
    webhook:
      unauthorizedTTL: 30s
      timeout: 3s
      subjectAccessReviewVersion: v1
      matchConditionSubjectAccessReviewVersion: v1
      failurePolicy: Deny
      connectionInfo:
        type: KubeConfig
        kubeConfigFile: /kube-system-authz-webhook.yaml
      matchConditions:
      # only send resource requests to the webhook
      - expression: has(request.resourceAttributes)
      # only intercept requests to kube-system (assumption i)
      - expression: request.resourceAttributes.namespace == 'kube-system'
      # don't intercept requests from kube-system service accounts
      - expression: !('system:serviceaccounts:kube-system' in request.user.groups)
      # only intercept update, delete or deletecollection requests
      - expression: request.resourceAttributes.verb in ['update', 'delete','deletecollection']
  - type: Node
  - type: RBAC
```

e.g. [Preventing unnecessarily nested webhooks](https://github.com/kubernetes/enhancements/tree/e09ddc24172ee3b7766cf427ee242bc64bab1901/keps/sig-auth/3221-structured-authorization-configuration#story-2-preventing-unnecessarily-nested-webhooks)
``` yaml
apiVersion: apiserver.config.k8s.io/v1alpha1
kind: AuthorizationConfiguration
authorizers:
  - type: Webhook
    name: system-crd-protector
    webhook:
      unauthorizedTTL: 30s
      timeout: 3s
      subjectAccessReviewVersion: v1
      matchConditionSubjectAccessReviewVersion: v1
      failurePolicy: Deny
      connectionInfo:
        type: KubeConfig
        kubeConfigFile: /kube-system-authz-webhook.yaml
      matchConditions:
      # only send resource requests to the webhook
      - expression: has(request.resourceAttributes)
      # only intercept requests to kube-system (assumption i)
      - expression: request.resourceAttributes.namespace == 'kube-system'
      # don't intercept requests from kube-system service accounts
      - expression: !('system:serviceaccounts:kube-system' in request.user.groups)
      # only intercept update, delete or deletecollection requests
      - expression: request.resourceAttributes.verb in ['update', 'delete','deletecollection']
  - type: Node
  - type: RBAC
  - name: opa
    type: Webhook
    webhook:
      unauthorizedTTL: 30s
      timeout: 3s
      subjectAccessReviewVersion: v1
      matchConditionSubjectAccessReviewVersion: v1
      failurePolicy: Deny
      connectionInfo:
        type: KubeConfig
        kubeConfigFile: /opa-kube-system-authz-webhook.yaml
      matchConditions:
      # only send resource requests to the webhook
      - expression: has(request.resourceAttributes)
      # only intercept requests to kube-system
      - expression: request.resourceAttributes.namespace == 'kube-system'
      # don't intercept requests from kube-system service accounts
      - expression: !('system:serviceaccounts:kube-system' in request.user.groups)
```

上記の設定はkube-apiserverの`--authorization-config`フラグにファイルを指定することで反映できます。`v1.29` 時点ではあわせて`StructuredAuthorizationConfiguration`フィーチャーゲートを有効にする必要があります。

設定ファイルは自動リロードに対応(または対応予定)しているようです。

設定ファイルの内容について、いくつか気になるパラメータの詳細ついてもまとめてみました。
### authorizers

`--authorization-modes` フラグと似た順序付けられたリスト。
webhook authorizerは複数指定できるが、その他は1回だけ指定できる。
###  authorizers.failurePolicy

`failurePolicy`により、Webhookリクエストがエラーになったり`matchConditions`の評価でエラーが発生した場合の制御を指定できるようになっています。

`NoOpinion`: リクエストを許可するAuthorizerが存在するかどうか後続のAuthorizerに続ける
`Deny`: 後続のAuthorizerに引き継ぐことなく処理を終了します。
### authorizers.matchConditions

リクエストが対象のWebhookサーバに送られるために満たす必要のある条件のリスト。
空のリストはすべての条件にマッチします。最大64個。

すべての条件がTRUEの場合にリクエストがWebhookサーバに送られます。1つでもFALSEがあるとそのWebhookはスキップされます。

条件はCEL式で記述できます。評価がエラー(FLASEではない)の場合、`failurePolicy`に従って処理される。