VaultのKubernetes Auth Methodsを理解する為に、以下の公式Docを読んだ内容をまとめてみる。
Overview
kubernetesAuth Methodは、Kubernetes Service Account Tokenを用いてVaultに対して認証することができる。
この認証方法は、Kubernetes Podに対して、Vault Tokenを簡単に導入できる。
Authentication
Via the CLI
- デフォルトのpathは
/kubernetesになる。 - もしこのAuth Methodが異なるpathで有効化されていれば、
kubernetesの代わりにそのpathを用いる(例:auth/my-path/login)。
$ vault write auth/kubernetes/login role=demo jwt=...
Via the API
- デフォルトのendpointは、
auth/kubernetes/loginである。 - もしこのAuth Methodが異なるpathで有効化されていれば、その値を用いる。
- レスポンスはTokenを含み、
auth.client_tokenの値として返ってくる。
$ curl \
--request POST \
--data '{"jwt": "your_service_account_jwt", "role": "demo"}' \
http://127.0.0.1:8200/v1/auth/kubernetes/login
Configuration
- ユーザやマシンが認証出来るようになる前に、Auth Methodが構成されている必要がある。
- これらのステップは、一般的には運用者あるいは構成管理ツールにて行われている必要がある。
1. Kubernetes Auth Methodを有効化する
$ vault auth enable kubernetes
2. VaultがKubernetesと接続する為に、/configendpointを用いる。
- 利用可能なconfiguration optionsのリストは、APIドキュメントを参照すること。
$ vault write auth/kubernetes/config \
token_reviewer_jwt="reviewer_service_account_jwt" \
kubernetes_host=https://192.168.99.100:8443 \
kubernetes_ca_cert=@ca.crt
- Kubernetes 1.21以降、Podにマウントされるトークンは有効期限付きで、PodやService Accountの削除とともに失効する。さらに1.24以降は、Service Accountを作ってもトークン用のSecretが自動生成されなくなった。そのため、
token_reviewer_jwtに何を使うかを決める必要がある。- VaultをKubernetes上のPodで動かす場合は、
token_reviewer_jwtとkubernetes_ca_certを省略するのが推奨である。Vault(1.9.3以降)はPodのローカルのトークンとCA証明書(/var/run/secrets/kubernetes.io/serviceaccount/配下)を定期的に読み直して使う。 token_reviewer_jwtを省略すると、ログイン時にクライアントが送ったJWTがそのままTokenReview APIの呼び出しに使われる(VaultがPod上で動いている場合はdisable_local_ca_jwt=trueも必要)。この場合、認証させたい各Service Accountにsystem:auth-delegatorを付与する。- 従来どおり長期トークンを使う場合は、
type: kubernetes.io/service-account-tokenのSecretを手動で作成し、そのトークンをtoken_reviewer_jwtに指定する。ただし短命トークンによるセキュリティ上の利点は得られない。
- VaultをKubernetes上のPodで動かす場合は、
- Vault 1.9以降で作成したマウントでは
disable_iss_validationのデフォルトがtrueになり、disable_iss_validationとissuerは非推奨となった。1.9より前に作成したマウントでKubernetes 1.21以降を使う場合は、disable_iss_validation=trueを明示的に設定する。
3. 名前付きRoleを作成する
- このRoleは
defaultnamespaceのvault-authService Accountを認可し、それに対してdefault policyを付与する。
$ vault write auth/kubernetes/role/demo \
bound_service_account_names=vault-auth \
bound_service_account_namespaces=default \
policies=default \
ttl=1h
注意事項
- VaultがPodの認証に使用するpatternは、
JWT tokenを、ネットワーク越しに共有することに依存している。 - security model of Vaultに記載があるように、Vaultは
trusted compute base(セキュリティ関連のイベントを処理する部分)の一部であるため、これを許容される。 - 一般的に、Kubernetesアプリケーションは、
JWT tokenを、他のアプリケーションと共有するべきではない。 - Podに代わってAPIを呼び出す事が出来てしまい、サードパーティ製品に対して、意図しないアクセス許可を与える可能性があるため。
Configuring Kubernetes
- このAuth Methodは、「与えられたJWTがまだ有効かどうか」を検証する為に、Kubernetes TokenReview APIにアクセスする。
- Kubernetesは
--service-account-lookupオプションと共に起動するべきである。- Kubernetes1.7でデフォルトになっているが、それ以前のバージョンではKubernetes API server起動時に設定する必要がある。
- これ以外の場合、Kubernetesで削除されたTokenが適切にRevokeされない。
- このAuth Methodで用いられてるService Accountは、TokenReview APIに対してのアクセス権限をもつ必要がある。
- もしKubernetesがRBACロールを使用するように構成されている場合、Service Accountには、このAPIにアクセスする権限を付与する必要がある。
- 以下のClusterRoleBindingのサンプルは、これらのpermissionを与えたものである。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: role-tokenreview-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: vault-auth
namespace: default
API
Kubernetes Auth PluginはHTTP APIを持っている。API docsに詳細が書いてある。