Skip to main content

RBACを使ってKubernetesに最小権限の原則を適用する

著者
Headshot of Jekayin-Oluwa Olabemiwo

Jekayin-Oluwa Olabemiwo

feature kubernetes polp

2022年8月29日

0 分で読めます

最小権限の原則とは?

最小権限の原則(PoLP)は、ソフトウェア開発における防御戦略です。最小特権の原則、または最小権限の原則とも呼ばれ、ユーザーが割り当てられたタスクの遂行に必要なシステム、プロセス、ネットワーク、ファイルにのみアクセスできるようにします。

適切に設定すれば、権限のないユーザーが制限されたアプリケーション機能にアクセスしたり、ロールを切り替えたりすることはできません。また、割り当てられた機能を完了するために必要な場合を除き、ファイルやAPIシークレットなどの特定のデータにもアクセスできません。これにより、権限のない操作による意図的または意図しない影響から保護できます。

施設内では、サーバールームなどの特定のエリアに立ち入れるのは、その施設での業務を許可された従業員に限られます。こうした施設の重要な場所の中には、関連部門の経験豊富なメンバーや上級メンバーしか立ち入れない場所もあります。

最小権限の原則も同じ考え方に基づいています。たとえば、従業員管理ソフトウェアでは、人事担当者だけが従業員記録にアクセスできるようにするのが一般的です。同様に、アプリケーションのバージョンを本番環境にデプロイするなどの操作は、上級エンジニアだけが実行できるように設定できます。

最小権限の原則は、SaaS(Software as a Service)アプリケーションにも取り入れられています。ユーザーには、担当業務に応じてアプリケーション内で異なるロールが割り当てられます。

ソフトウェアシステムを保護するには、ステークホルダーにとって制約が厳しすぎないようにしながら、脅威アクターに対して脆弱にならないようにするバランスが必要です。最小権限の原則により、アクセスに伴う摩擦を最小限に抑えつつシステムの安全性を保ち、このバランスを実現できます。

さらに、最小権限の原則は、効率的で信頼性の高い運用パフォーマンスの維持にも役立ちます。マルウェア攻撃や、安全でないコードの本番環境へのプッシュ、管理者パスワードの変更といったリスクの高いユーザー操作によるシステム停止の可能性を低減できます。

この記事では、Kubernetes(K8s)がロールベースのアクセス制御を実装して、最小権限の原則をどのようにサポートしているかを解説します。

Kubernetesへのアクセスに最小権限の原則を適用する

Kubernetesはコンテナオーケストレーションのワークロードを処理します。組織や開発者が、コンテナ化されたアプリケーションのデプロイ、管理、スケーリングを自動化するためのプラットフォームです。そのため、デプロイ済みアプリケーションの作成や保守にあたり、開発、運用、ITチームのさまざまなメンバーがKubernetes環境にアクセスする必要があります。

最適なセキュリティとリソース保護を実現するには、本番環境のどの段階でも、Kubernetesの利用に際して最小権限の原則に従う必要があります。幸い、Kubernetesにはアクセス制御を可能にする認証と認可の仕組みが備わっています。チームは、Kubernetes APIを操作する際に、誰がどの運用リソースや権限にアクセスできるかを明確に定義する必要があります。また、人間のユーザーアカウントであるかサービスアカウントであるかを問わず、未認証アクセスを無効にする必要があります。

KubernetesがRBACでアクセスを管理する方法

ロールベースのアクセス制御(RBAC)は、多くのシステムで使われている手法です。環境内の各ユーザーのロールに基づいて、リソースへの権限を定義します。Kubernetesには、包括的なネイティブRBACメカニズムがあり、クラスター内のKubernetesオブジェクトに対して、ユーザーやユーザーグループがどのように操作できるかを指定する権限を設定できます。このRBACフレームワークの利用は、クラスターとそのコンテナ化されたアプリケーションを保護するための第一歩です。

Kubernetesオブジェクトは、実行中のコンテナ化されたアプリケーション、そのリソース、およびアプリケーションの動作を定めるポリシーを指定する永続的なエンティティです。つまり、クラスターの望ましい状態を定義します。Kubernetes APIを使ってオブジェクトを作成、変更、削除できます。

Kubernetesには、ユーザーアカウントとサービスアカウントの2種類があります。ユーザーアカウントは実際の人間のユーザー用で、サービスアカウントはKubernetes APIにアクセスするプロセス用です。Kubernetes RBACは、Pod、シークレット、コントローラー、カスタムリソース定義(CRD)などのリソースへの、これらのアカウントのアクセスを制御します。

Kubernetesでは、RoleオブジェクトまたはClusterRoleオブジェクトで権限を定義します。次に、RoleBindingオブジェクトとClusterRoleBindingオブジェクトを使って、定義した権限をルールとして割り当てます。RBAC APIでは、次の4種類のKubernetesオブジェクトを宣言します。

  • Role — 個々の名前空間内のリソースに適用される権限を管理します

  • ClusterRole — クラスター全体のリソースに適用される権限を管理します

  • RoleBinding — 特定の名前空間内でRoleをアカウントまたはグループに割り当てます

  • ClusterRoleBinding — クラスター内のすべての名前空間を対象に、ClusterRoleをアカウントまたはグループに割り当てます

次の2つのセクションでは、クラスター内のリソースへのアクセスを制限するうえで、RBACポリシーが最小権限の原則にどう沿うかを見ていきます。

権限の定義

権限を適切に設定するには、最小権限の原則を考慮しながら、各チームメンバーのロールを反映するようにKubernetesを設定する必要があります。RoleとClusterRoleを使うと、非常に効率よく設定できます。Roleは1つの名前空間内のリソースに適用され、ClusterRoleはクラスター全体のリソースに適用されます。

このセクションでは、RoleとClusterRoleを使ってシステムの特定の部分へのアクセスを制限する方法を説明します。

ある企業に新しくシニアDevOpsエンジニアが加わり、すべての環境変数やその他のシークレットを閲覧できる一方、チームメンバーは閲覧できないようにする必要があるとします。さらに、運用チームの一員として、このエンジニアは企業のアプリケーションワークロード用に作成されたPodを閲覧し、クライアント側アプリケーションを実行するコンテナの健全性を監視する必要があるかもしれません。

これを実現するには、YAMLファイルでRoleオブジェクトとClusterRoleオブジェクトを定義します。以下は、development名前空間のシークレットへの読み取りアクセスを許可するRoleの定義例です。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

上記のコードでは、APIバージョンを指定しています。RBACはrbac.authorization.k8s.io APIグループを使い、Kubernetes APIを通じて認可ポリシーを設定します。次に、定義の種類としてRoleを指定し、適用先の名前空間であるdevelopmentを記載しています。ここでは、developmentが開発チームのリソース用の名前空間であると想定しています。次に、Roleにsecretpod-readerという名前を付けます。

rulesセクションには、ルールの適用対象となるリソースと、Roleがそのリソースに対して実行できる操作を記載します。このセクションには、ルールの動詞も含まれます。Kubernetesでは、write、watch、read、deleteなどのルール動詞を使って、広範な区分で権限を管理します。

以下は、クラスター内のフロントエンドPodへの読み取りアクセスを許可するClusterRoleの定義例です。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"

上記のコードでは、メタデータに名前空間が指定されていません。これは、ClusterRoleが名前空間に属さないためです。そのため、メタデータセクションではClusterRoleの名前としてpod-readerだけを指定しています。

次に、Roleをdevelopment名前空間のリソースグループにバインドし、ClusterRoleをクラスターにバインドできます。これで、チームだけがdevelopmentリソース内の必要なシークレットを閲覧できるようになります。このように最小権限の原則を適用すれば、チームは開発業務に必要なリソースにアクセスできる一方、組織内の他のユーザーはこれらのPodやリソースにアクセスできません。

これで、DevOpsエンジニアがシークレットにアクセスするためのRoleと、DevOpsチーム全体がPodを読み取るためのClusterRoleを作成できました。次のセクションでは、RoleとClusterRoleに権限を割り当てます。

権限の割り当て

たとえば、特定の従業員がアプリケーション設定で使われているシークレットキーにアクセスする必要がある場合、RoleBindingが役立ちます。これには、APIキーのペアや環境変数が含まれることがあります。

また、クラスター全体に権限を付与するには、ClusterRoleBindingを使う必要があります。ClusterRoleBindingを使うと、指定されたClusterRoleを持つユーザーが、名前空間を問わずクラスター内の任意のPodを読み取れるようになります。

DevOpsエンジニアのユーザー名がSolaの場合、上で作成したRoleを、development名前空間内のユーザーsolaに割り当てることができます。これにより、solaはその名前空間のシークレットを読み取れるようになります。

solaという名前は大文字と小文字が区別される点に注意してください。RoleBindingの定義は以下のとおりです。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-reader
  namespace: development
subjects:
- kind: User
  name: sola
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: secret-reader 
  apiGroup: rbac.authorization.k8s.io

上記のコードでは、次のことを行っています。

  • RoleBindingの種類を指定しました。

  • Roleというsecret-readerと、そのRoleBindingの適用先であるdevelopment名前空間を指定しました。

  • solaセクションで、Userとしてsubjectsを指定しました。複数のsubjectを指定することもできます。

  • roleRefセクションで、対応するRoleをバインディングに関連付けました。バインディングを作成した後は、roleRefセクションで関連付けたRoleまたはClusterRoleを変更できない点に注意してください。

上記のRoleBindingの例は、APIキーのペアや環境変数など、アプリケーション設定で使われるシークレットキーへのアクセスを、特定の開発チームメンバーに許可するユースケースに適しています。

今後、クラスター全体に権限を付与するにはClusterRoleBindingを使います。次の例では、opsグループのユーザーが、クラスター内の任意の名前空間にあるPodを読み取れるようにする方法を示します。opsという名前は大文字と小文字が区別される点に注意してください。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-pods-global
subjects:
- kind: Group
  name: ops
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

上の例のように、チームメンバー全員にクラスター内のすべてのPodへのアクセス権を付与する場合、ClusterRoleBindingが役立ちます。個々の権限を適切に設定すれば、グループ内のユーザーはPodを閲覧して状態を確認し、必要なレポート作成や監視業務を行えます。同時に、ClusterRoleの定義により、ユーザーがPodやその中のアプリケーションを変更できないようにします。

Kubernetes設定を保護する

ロールベースのアクセス制御は、最小権限の原則に沿った運用に大きく貢献します。幸い、KubernetesのネイティブRBACフレームワークは、この分野で幅広い機能を提供しています。ロールの作成とバインド機能は非常に強力で、必要なリソースへのアクセスを必要最小限のユーザーに限定できます。チームメンバーの業務を妨げることなく、潜在的な攻撃者に対するリスクを抑えられます。SnykでのKubernetes RBACの活用例はこちらをご覧ください。

Kubernetes環境に最小権限の原則を適切かつ安全に実装する方法について詳しく知りたい方は、Snykにアクセスし、Snykブログの関連記事をご覧ください。

Kubernetes関連リソース:

開発者ファーストのコンテナセキュリティ

Snykは、コンテナイメージとKubernetesワークロードの脆弱性を検出し、自動的に修正します。