ServiceAccount の Secret アクセス権限の確認

ServiceAccount に付与する Secret の読み取り権限を、ワークロードに必要な範囲へ限定してください。

説明

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 の読み取り権限をバインドします。

参考資料