【GKE】kubernetesのsecretリソースにアクセスできるユーザーを制限したい

公開:2021/01/30
更新:2021/02/07
3 min読了の目安(約2900字TECH技術記事

TL;DR

  • 全てのクラスタのsecretへアクセスする必要がない場合
    • IAMで container.secrets.* の権限を与えない
  • クラスタ、Namespaceごとにアクセス権限を設定した場合
    • IAMで container.secrets.* の権限を与えずに、RBACで与えたい権限を付与する

ソース

https://cloud.google.com/kubernetes-engine/docs/how-to/hardening-your-cluster

kubernetesのsecretリソースについて

secretのリソースにアクセスできるユーザーは、データの中身をみることができます。
なぜなら、secretのデータはBase64でエンコードされてるだけだからです。
たとえば、次のようなsecretリソースが定義されている場合、

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: sample-secret
  namespace: default
data:
  foo: YmFyCg==

この場合 foo というキーに対して YmFyCg== という値が格納されているわけですが、以下のようにデコードしてあげると値の中身を閲覧することができます。

echo 'YmFyCg==' | base64 -D

今回の場合は、 bar という値が格納されていました。
kubernetesのsecretは、データベースのパスワードや外部サービスのシークレットキーなどを格納するので、その内容を閲覧できる開発者を制限すべきです。

方法1: GCPのIAMで権限を付与しない

Googleプロジェクト内の全てのGKEクラスタのsecretリソースにアクセスする必要がない場合は、IAMの設定でユーザーに対して、 container.secrets.* の権限を付与しないようにすればOKです。
たとえば roles/container.developercontainer.secrets.* の権限を持っていますが、 roles/container.viewer だと container.secrets.*の権限は持っていません。

詳しくはこちら

https://cloud.google.com/iam/docs/understanding-roles

方法2: GCPのIAMで権限を付与しない + RBACで部分的に許可する

  • クラスタごとにsecretにアクセスできるユーザーを制限したい
  • namespaceごとにsecretにアクセスできるユーザーを制限したい
  • IAMじゃなくて、kubernetesのリソースを使ってsecretにアクセスできるユーザーを制限したい

という場合は、このパターンを使います。
IAMではcontainer.secrets.*の権限を付与しないで、RBACでユーザーごとに許可するという形になります。

クラスタごとにsecretにアクセスできるユーザーを許可したい場合は、 ClusterRoleClusterRoleBinding を用います。たとえば、secretのgetとlistを許可する場合は、許可したいクラスタに以下のようなリソースを作成します。

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secret-reader-binding
subjects:
- kind: User
  name: xxxxx@gmail.comm
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

namespaceごとにsecretにアクセスできるユーザーを制限したい場合は、 RoleRoleBinding を用います。たとえば、hogeというnamespaceのsecretのgetとlistを許可する場合は、許可したいnamespaceに以下のようなリソースを作成します。

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: hoge
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: hoge
  name: secret-reader-binding
subjects:
- kind: User
  name: xxxxx@gmail.comm
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

詳しくはこちら

https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#role

最後に

これでkubernetes上のsecretリソースの値をみることができるユーザーを制限することができます。
しかし、secret.yamlの定義ファイルをGitリポジトリにコミットしてしまうわけにはいかないです。
それを回避する方法として、KubesecSealed Secrets
BerglasExternal Secretsなどのツールがありますので、活用してみてください。