Start Building for Free
CircleCI.comアカデミーブログコミュニティサポート

設定ファイルのポリシー管理機能の概要

2 weeks ago1 min read
クラウド
このページの内容

設定ファイルのポリシー管理機能を使って組織レベルのポリシーを作成し、設定要素が必須なのか、許可する、許可しないなどのルールとスコープを指定することができます。

はじめに

設定ファイルのポリシー管理機能により、CircleCI プロジェクトの設定ファイルを管理するポリシーを作成できます。 プロジェクトの設定ファイルが関連付けられたポリシーに定められたルールを遵守していない場合、最も厳しいケースでは、遵守するまでそのプロジェクトのパイプラインはトリガーできません。

CircleCI では、config.yml ファイルを使ってCI/CD パイプラインをプロジェクトレベルで定義します。 この方法ではプロジェクトの拡大に伴い変化するニーズに合うように各パイプラインを作成できるため、開発や反復を迅速に行う際に便利です。 しかし、組織全体の規則やセキュリティポリシーを管理および制定することが困難な場合があります。 そんな場合に、設定ファイルのポリシー管理機能が役立ちます。

設定ファイルのポリシーについての判定は保存され、監査できます。 これにより、組織内で実行されているパイプラインの定義に関する有益なデータが得られます。

クイックスタート

VCS に接続した CircleCI アカウント を既にお持ちで、いますぐ設定ファイルのポリシー管理機能を使用したい場合は、 設定ポリシーの管理における CLI と VCS の使用 ガイドをお読みください。

設定ファイルのポリシー管理機能の仕組み

設定ファイルのポリシー管理機能では、 Open Policy Agent (OPA) に基づき意思決定エンジンを使用します。 ポリシーは、OPA の定義に従い Rego クエリ言語で記述されます。 ルール違反があった場合は、パイプラインがトリガーされる際に表面化します。

ポリシーはローカルで作成し、CircleCI CLI を使って CircleCI にプッシュすることができます。 ポリシーは ご自身の VCS 内のリポジトリに保存できます。 詳細については、 設定ポリシーの管理における CLI と VCS の使用 のページを参照してください。

CircleCI ドメイン固有の言語を使った Rego ポリシーの記述

ポリシーは、OPA をサポートする専用の宣言型ポリシー言語である Rego で記述されます。 Rego の詳細については、 rego 言語に関するドキュメント を参照してください。

CircleCI が設定ファイルを判定するためには、ポリシーの評価結果を CircleCI が解釈できる必要があります。 そのため、ポリシーはこのページで説明されている CircleCI の仕様に合うように記述する必要があります。

パッケージと名前

すべてのポリシーが org パッケージに属し、ポリシー名を最初のルールとして宣言する必要があります。 ポリシーのすべての Rego ファイルには以下が含まれている必要があります。

package org

policy_name["unique_policy_name"]

policy_name は最大 80 文字の英数字の文字列です。 これは CircleCI において、ポリシーを名前で一意に識別するために使用されます (Kubernetes のリソース名と同様)。 ポリシー名は一意である必要があります。 1つの組織内で 2 つのポリシーに同じ名前をつけることはできません。

policy_name にはルールの一部を使い、rego key`: policy_name["NAME"] として宣言する必要があります。

ルール

org パッケージと policy_name ルールを宣言すると、ポリシーをルールの一覧として定義できるようになります。 各ルールは 3 つのパートで構成されます。

  • 評価: 設定ファイルにポリシー違反がないかを評価

  • 措置: 違反している場合の措置

  • 有効化: 措置を有効にするかどうかを決定

このフォーマットを使用すると、ポリシー作成者 は、CircleCI のポリシー評価の出力を解析する能力に影響を与えることなく、カスタムヘルパー関数を作成できます。 ポリシーはすべて input 変数を使って設定データにアクセスできます。 input は評価されるプロジェクトの設定です。 この 'input' は CircleCI の設定ファイルの内容と一致するので、'jobs' や 'workflows' などの使用可能な任意の設定要素にご希望の評価結果を適用するルールを記述することができます。

input.workflows     # an array of nested structures mirroring workflows in the CircleCI config
input.jobs          # an array of nested structures mirroring jobs in the CircleCI config

ルールの定義

OPA では、ルールよってあらゆるタイプの出力を生成できます。 CircleCI では、違反の対象となるルールには、以下のタイプの出力が必要です。

  • 文字列

  • 文字列配列

  • 文字列から文字列のマップ

これは、ルール違反があった際に、開発者や SecOps がそれに基づき対応するためのエラーメッセージが生成される必要があるためです。 別のタイプの出力を生成するヘルパールールを定義することもできますが、CircleCI が判定時に考慮するルールは、上記の出力タイプでなければなりません。 詳細については、下記の 有効化 のセクションをご覧ください。

評価

設定ファイルが規定されたポリシーに違反した場合に、意思決定エンジンがどのように判定するかを説明します。 評価では、ルールの名前と ID を定義し、条件をチェックして、違反について記載するユーザーフレンドリーな文字列を返します。 ルールの評価には、ルール名オプションのルール ID が含まれます。 ルール名は、ルールの評価結果を有効化し、措置を設定するために使用されます。

RULE_NAME = reason {
  ... # some comparison
  reason := "..."
}
RULE_NAME[RULE_ID] = reason {
  ... # some comparison
  reason := "..."
}

下記は、設定に少なくとも 1 つのワークフローが含まれる設定をチェックするシンプルな評価の例です。

contains_workflows = reason {
    count(input.workflows) > 0
    reason := "config must contain at least one workflow"
}

ルール ID は 1 つのルールについて複数回の違反があった場合に識別するために使用されます。 たとえば、1 つの設定ファイルで非公式の Docker イメージを複数使用している場合、use_official_docker_image ルールに複数回違反することになります。 ルール ID は複数回の違反が予測される場合のみ使用してください。 場合によっては、ルールを遵守しているかどうかだけを知りたい場合もあります。 その場合、ルール ID は不要です。

use_official_docker_image[image] = reason {
  some image in docker_images   # docker_images are parsed below
  not startswith(image, "circleci")
  not startswith(image, "cimg")
  reason := sprintf("%s is not an approved Docker image", [image])
}

# helper to parse docker images from the config
docker_images := {image | walk(input, [path, value])  # walk the entire config tree
                          path[_] == "docker"         # find any settings that match 'docker'
                          image := value[_].image}    # grab the images from that section
措置

このポリシーの管理機能では、ルールの措置レベルを設定できます。

ENFORCEMENT_STATUS["RULE_NAME"]

設定可能なレベルは 以下の 2 つのレベルです。

  • hard_fail : policy-service が設定ファイルにおいて hard_fail と設定されたルールに対する違反を検出した場合、パイプラインはトリガーされません。

  • soft_fail : policy-service が設定ファイルにおいて soft_fail と設定されたルールに対する違反を検出した場合、パイプラインはトリガーされますが、そのルール違反は policy-service の判定ログに記録されます。

hard_fail に設定された use_official_docker_image ルールの設定例:

hard_fail["use_official_docker_image"]
有効化

ポリシー違反を審査するためにはルールを有効化する必要があります。 有効化されていないルールは、CircleCI 違反出力形式に合致する必要はなく、他のルールのヘルパーとして使用できます。

enable_rule["RULE_NAME"]

ルールを有効化するには、そのルールを enable_rule オブジェクトにキーとして追加します。 たとえば、use_official_docker_image ルールを有効化する場合、以下を使用します。

enable_rule["use_official_docker_image"]

パイプラインのメタデータの使用

CircleCI 設定ファイルのポリシーを記述する場合、多くの場合プロジェクトやブランチごとに動作が若干異なるポリシーにすることが推奨されます。 それには data.meta Rego プロパティーを使用します。

ポリシーがトリガーされたパイプラインのコンテキストで評価されると、data.meta において以下の 3 つのプロパティーが使用できるようになります。

project_id    (CircleCI Project UUID)
branch        (string)
build_number  (number)

このメタデータは、ルールのアクティブ化/非アクティブ化、評価結果の変更、およびルール定義自体の一部として使用できます。

以下は 1 つのプロジェクトに対してのみルールを制定し、ブランチメイン上でのみ hard_fail とするポリシーのサンプルです。

package org

policy_name["example"]

# specific project UUID
# use care to avoid naming collisions as assignments are global across the entire policy bundle
sample_project_id := "c2af7012-076a-11ed-84e6-f7fa45ad0fd1"

# this rule is enabled only if the body is evaluates to true
enable_rule["custom_rule"] { data.meta.project_id == sample_project_id }

# "custom_rule" evaluates to a hard_failure condition only if run in the context of branch main
hard_fail["custom_rule"] { data.meta.branch == "main" }

サンプルポリシー

以下は、use_official_docker_image という 1 つのルールが制定された全ポリシーのサンプルです。設定ファイル内の先頭に circlecicimg がついたすべての Docker イメージをチェックします。 設定ファイル内のすべての docker_images を見つけるヘルパーコードを使用しています。 use_official_docker_image の評価結果を hard_fail に設定し、このルールを有効化しています。

package org

import future.keywords

policy_name["example"]

use_official_docker_image[image] = reason {
  some image in docker_images   # docker_images are parsed below
  not startswith(image, "circleci")
  not startswith(image, "cimg")
  reason := sprintf("%s is not an approved Docker image", [image])
}

# helper to parse docker images from the config
docker_images := {image | walk(input, [path, value])  # walk the entire config tree
                          path[_] == "docker"         # find any settings that match 'docker'
                          image := value[_].image}    # grab the images from that section

hard_fail["use_official_docker_image"]

enable_rule["use_official_docker_image"]

ドキュメントの改善にご協力ください

このガイドは、CircleCI の他のドキュメントと同様にオープンソースであり、 GitHub でご利用いただけます。 ご協力いただき、ありがとうございます。

サポートが必要ですか

CircleCI のサポートエンジニアによる、サービスに関する問題、請求およびアカウントについての質問への対応、設定の構築に関する問題解決のサポートを行っています。 サポートチケットを送信して、CircleCI のサポートエンジニアにお問い合わせください。日本語でお問い合わせいただけます。

または、 サポートサイト から、サポート記事やコミュニティフォーラム、トレーニングリソースをご覧いただけます。