説明
Role または ClusterRole に secrets の get、list、watch や広い権限があり、それを ServiceAccount にバインドすると、そのアカウントを使う Pod は許可範囲の Secret 値を読み取れます。Secret にはトークン、パスワード、証明書などの機密情報が含まれることがあります。
すべてのワークロードに Secret の読み取り権限が必要なわけではありません。必要なアプリケーションだけに狭い範囲で付与し、他の ServiceAccount からは削除してください。
想定される影響
- 許可範囲のパスワード、トークン、キーが漏えいする場合があります。
- 盗まれた認証情報を通じて、他のシステムへ侵害が広がる場合があります。
- Secret にアクセスする主体が増えるほど、権限管理や事故調査が難しくなります。
対処方法
- Role と ClusterRole から、不要な
secretsの読み取り権限を削除してください。 - Secret へのアクセスが必要なら、ServiceAccount に許可する名前空間、リソース、操作を必要な範囲に限定してください。
- 既定のアカウントではなく用途が明確な ServiceAccount を使い、実際のバインドと権限を定期的に確認してください。
例
RoleBinding は default 名前空間の Role を、kube-system の default ServiceAccount に付与します。このアカウントは別途存在している必要があります。変更後の Pod 読み取り権限も、業務上必要な場合だけ残してください。
変更前
hcl
resource "kubernetes_role" "role_name" {
metadata {
name = "terraform-example"
}
rule {
api_groups = [""]
resources = ["secrets"]
verbs = ["*"]
}
}
resource "kubernetes_role_binding" "example" {
metadata {
name = "terraform-example"
namespace = "default"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "Role"
name = kubernetes_role.role_name.metadata[0].name
}
subject {
kind = "ServiceAccount"
name = "default"
namespace = "kube-system"
}
}
変更後
hcl
resource "kubernetes_role" "role_name" {
metadata {
name = "terraform-example"
}
rule {
api_groups = [""]
resources = ["pods"]
verbs = ["get", "list", "watch"]
}
}
resource "kubernetes_role_binding" "example" {
metadata {
name = "terraform-example"
namespace = "default"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "Role"
name = kubernetes_role.role_name.metadata[0].name
}
subject {
kind = "ServiceAccount"
name = "default"
namespace = "kube-system"
}
}
補足:
- 変更前: Secret の全操作を許可する Role をバインドします。
- 変更後: Secret の権限を削除し、代わりに Pod の読み取り権限をバインドします。