📑

Open Policy Containers(OPC)

に公開

Open Policy Containers(OPC)の前にOpen Policy Agent(OPA)

  • https://www.openpolicyagent.org/
  • クラウドネイティブ環境におけるポリシー適用のための汎用エンジン
  • Regoという宣言型言語を用いてポリシーを記述する
    • JSONやYAMLのような構造化されたデータを入力として受け取り、ポリシー評価の結果(許可/拒否など)を返す

例: 全てのNamespaceに管理者を特定するためのownerラベルを必須にする

package main

deny contains msg if {
    # 対象リソースをNamespaceに限定
    input.review.kind.kind == "Namespace"
    # Namespaceのメタデータに "labels" が存在しない場合
    not input.review.object.metadata.labels

    msg := "Namespace must include an 'owner' label."
}

deny contains msg if {
    # 対象リソースをNamespaceに限定
    input.review.kind.kind == "Namespace"

    # "owner" ラベルが設定されていない場合
    not input.review.object.metadata.labels.owner

    msg := "Namespace must include an 'owner' label."
}

例: 111111111111.dkr.ecr.ap-northeast-1.amazonaws.comというリポジトリ以外からのコンテナイメージの利用を禁止する

package main

deny contains msg if {
    container := input.review.object.spec.containers[_]

    # イメージ名が許可されたリポジトリで始まらない場合
    not startswith(container.image, "111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/")

    msg := sprintf("Image '%v' comes from an untrusted registry. Only images from 'your-company.com' are allowed.", [container.image])
}

deny contains msg if {
    # initContainersを対象
    container := input.review.object.spec.initContainers[_]

    # イメージ名が許可されたリポジトリで始まらない場合
    not startswith(container.image, "111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/")

    msg := sprintf("InitContainer image '%v' comes from an untrusted registry. Only images from 'your-company.com' are allowed.", [container.image])
}

Open Policy Containers(OPC)の背景と概要

  • https://openpolicycontainers.com/
  • OPAポリシーのバージョン管理、配布、セキュリティ確保といったライフサイクル管理の複雑性が課題になり登場した
  • OCI仕様とDockerライクなワークフローを採用している
  • OPAポリシーをOCIv2互換のコンテナイメージとしてビルド、タグ付け、署名、プッシュ、プルを行う

policy CLI

  • OPAポリシーをOCIイメージへと変換し、コンテナレジストリを介して配布・管理することができる
  • OPAポリシーをOCIイメージとして扱うための一連の機能を提供し、開発者がコンテナイメージを操作するのと同様の直感的な体験でポリシーを管理できるように設計されている
  • brew tap opcr-io/tap && brew install opcr-io/tap/policy

サブコマンド

名前 説明
build ポリシーをビルドしイメージを作成
images ローカルに保存されているイメージの一覧を表示
push イメージをコンテナレジストリにプッシュ
pull コンテナレジストリからイメージをプル
login コンテナレジストリにログイン
logout コンテナレジストリからログアウト
save イメージをローカルのバンドルtarballとして保存
tag 既存のポリシーイメージに新しいタグを付与
rm ローカルレジストリからポリシーイメージを削除
inspect ポリシーイメージに関する詳細情報を表示
repl ポリシーをロードしたOPAインスタンスを使用してクエリを実行するためのシェルを起動
templates テンプレートの一覧表示と適用
version バージョン情報を表示

使い方

  1. ポリシーの作成
ns.yaml
src
├── .manifest
└── policies
    └── istio.rego
.manifest
{
  "roots": ["opctest"]
}
ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: hoge
  labels:
    name: hoge
    istio.io/rev: stable
istio.rego
package opctest

deny contains msg if {
  input[i].contents.kind == "Namespace"
  labels := input[i].contents.metadata.labels
  not object.get(labels, "istio.io/rev", false)

  msg := "Isito not injected."
}

deny contains msg if {
  input[i].contents.kind == "Namespace"
  labels := input[i].contents.metadata.labels
  object.get(labels, "istio.io/rev", false) != "stable"

  msg := "Revision is not stable."
}
  1. レジストリへのログイン(login)

    • cat password | policy login -s ghcr.io -u atsuya0 --password-stdin
    • ビルドしたイメージをリモートのOCI準拠レジストリ(例: GitHub Container Registry (GHCR), Docker Hub, Amazon ECR, opcr.ioなど)にプッシュする前に認証を行う
  2. ポリシーのビルド(build)

    • policy build src -t ghcr.io/atsuya0/opctest:0.0.1
    • Regoで記述されたOPAポリシーファイル群を含むディレクトリを指定
    • ポリシーがコンパイルされイメージとしてパッケージングされる
  3. レジストリへのプッシュ(push)

    • policy push ghcr.io/atsuya0/opctest:0.0.1
    • タグ付けされたイメージをリモートレジストリにアップロード
  4. レジストリからのプル(pull)

    • policy pull ghcr.io/atsuya0/opctest:0.0.1
    • 必要なイメージをレジストリからダウンロード
  5. イメージをローカルのバンドルtarballとして保存(save)

  • policy save ghcr.io/atsuya0/opctest:0.0.1

cosign

ポリシーの電子署名と検証

  1. 署名
    • cosign sign ghcr.io/atsuya0/opctest:0.0.1
    • policy buildでイメージを作成した後にコマンドを実行
    • イメージダイジェストに対して秘密鍵で署名が生成される
  2. 検証
    • cosign verify ghcr.io/atsuya0/opctest:0.0.1
    • policy pullでイメージをプルする際にコマンドを実行
    • 対応する公開鍵で署名を検証する

メリット

標準化 ポリシーのパッケージングと配布方法の標準化
開発体験の向上 Dockerライクなpolicy CLIのワークフローにより馴染みのある方法でポリシーを扱える
セキュリティの向上 cosignによる署名と検証が行え既存のポリシーは変更不能
バージョン管理 OCIイメージタグによる明確なバージョニングが可能となり、変更管理とロールバックが容易になる
既存インフラの活用 任意のOCI準拠レジストリを利用できるため、既存のコンテナレジストリを流用できる

Conftest

  • ConftestはOPA/Regoを使用して構造化された設定データ(Kubernetes YAML、Terraform、JSONなど)をテストするためのツール
  1. イメージをローカルのバンドルtarballとして保存
  • policy save ghcr.io/atsuya0/opctest:0.0.1
  1. tarballを展開
  • bsdtar xzf bundle.tar.gz
  1. テスト
  • conftest test ns.yaml --policy src/policies/istio.rego --namespace opctest

Gatekeeper

  • GatekeeperはKubernetesアドミッションコントローラーのWebhookとして機能し、OPAを利用してKubernetes APIリクエスト(作成、更新、削除)に対してポリシーを評価する
  • ConstraintTemplateにRegoコードそのものをインラインで記述する必要があり、OPCを利用することはできない

Discussion