Chapter 03

📕 Policy as Code

Masayoshi MIZUTANI
Masayoshi MIZUTANI
2021.12.31に更新

なぜOPA/Regoを使ってポリシーをコード化するのか?という疑問については Policy as Code の考え方が答えを知るヒントになるでしょう。

多くのプロダクトやサービスではポリシー(発生した事象や調査結果などに対して深刻度や対応方法を判断するルール)をリッチなGUIで設定したり、設定ファイル上で記述する、というのが一般的かと思います。またそもそも何かの判断はソフトウェア側でやるのではなく、人間が実施する、というケースも多くあるかと思います。これをわざわざRegoという言語で記述する理由については Policy as Code という考え方が参考になるかと思います。下記はOPAと直接関係ありませんが、terraformなどを開発するHashiCorpのプロダクトの一つ、Sentielのドキュメント内でPolicy as Codeについて述べられたものです。

https://docs.hashicorp.com/sentinel/concepts/policy-as-code

Policy as Code ではアクセスの制限やリソースの使い方の制限を実施するだけでなく、発生した事象の深刻度評価、あるいは事象に対してどのような対応を取るべきか、という判断をコードで表現するという考え方です。

近年普及しつつあるDevOpsは「ソフトウェアエンジニアリングのツールやアイディアなどのベストプラクティスをサービス運用の場面に導入して改善する」という考え方に基づいています。Policy as Codeもまさにこの発想で、ポリシーをテキスト形式のコードとして扱うことでソフトウェアエンジニアリングでおなじみのバージョン管理、自動テスト、自動デプロイ、レビュー手法などの恩恵をうけるよう、という考え方になります。

Policy as Codeの価値

これらを活用することによって担当者は「ポリシー変更にまつわる負担が軽減される」という効果を得られますが、最も重要なのは負担の軽減により 「頻繁にポリシーの変更をできるようになる」 という結果です。

アクセス制御などのポリシーは一度定めたらほとんど調整することはないと思われがちですが、実際にはセキュリティにまつわる環境の変化やビジネス要件や業務要件、さらには組織や人員なども流動することが多く、それに伴ってあるべきアクセス制御の形も変化します。また、攻撃や脆弱性への対応にまつわるポリシーの場合、適切な設定に至るまでが難しく、繰り返しチューニングをしなければなりません。その際に「今まで正常だったものがうまく動作しなくなるかもしれない」「チェックするために人手がかかる」「設定反映の作業に注意を要する」というような状況だと単純に時間がかかるだけでなく、心理的障壁も大きくなってしまいます。

そのような負担や心理的障壁を取り除き、必要に応じて素早く、そして自信を持ってポリシーを変更できるようにすることが Policy as Code の本質であると筆者は考えています。変更に必要な時間を短縮することで業務のブロッカーになるのを防ぎ、不適切な設定を素早くチューニングしていくことで、セキュアにビジネスなどの価値を最大化していけることが期待されます。

具体的な運用のメリット

実際に運用上どのようなメリットがありそうかという観点で、詳細を見ていきたいと思います。

再現性

再現性は、そもそもソフトウェアではなく人間が都度判断しているポリシーをコード化する際の利点です。セキュリティアラートやソフトウェアの脆弱性の深刻度がいい例ですが、これまではソフトウェアに頼らずに専門家が自らの知識や経験に基づいて判断するというケースが多かったと思います。これは判断に必要な情報がMachine Readableなフォーマットになっておらず読み取れなかったり、あるいはそもそもオンライン化されておらず機械的に収集できない、というような状況が要因だったと考えられます。しかし近年ではそれらも改善されつつあり、多くの情報の多くが遠隔から機械的に収集・利用できるようになりました。

専門家の判断の基準を適切に言語化することで、ポリシーに「再現性」が生まれます。もちろんセキュリティに限らず「例外的な状況」のパターンを網羅するのは難しく、全てを機械的なポリシーで処理するのは困難です。しかし一方で頻出するパターンや言語化できるものについてはコード化し、ソフトウェアで処理することで人間の負担を大きく軽減できます。また、専門家の「カン」のような再現困難なものではなく言語化された「ポリシー」は他のメンバーにも理解がしやすくなり、共通認識の確立やポリシー改善のための議論がやりやすくなります。

テストの自動化

もっとも重要なメリットの1つは、記述したポリシーのテストがやりやすい点だと考えます。ポリシーはえてして複雑になりがちであり、複雑なポリシーが正しく動作するかを検証しなければなりません。新たに追加したポリシーによって既存のポリシーが意図した通りに動かなくなるということも起こりえます。そのため長期的にポリシーを変更し続けるためには容易にテストを実施し、検証しなければなりません。

ポリシーがコードによって記述されていることで、自動化されたテストを少ない負担で実施できます。テストの機能が用意されていないと、動作検証のために本番と同様の環境や状況を作り出す必要があり、ポリシーが増えていくにつれて恐ろしい手間がかかってしまいます。これによりポリシーの更新が滞るようになり、実情にそぐわないポリシーが使われ続けるという不幸がおこってしまいがちです。ソフトウェア開発における回帰テストの発想で常にポリシーが正常に動作することを確認することで、少ない負担でポリシーをメンテナンスし続けることが可能です。

バージョン管理やレビューの導入

まれにサポートされていることはありますが、大部分のプロダクトにバージョン管理やレビュー機能は実装されていないのが現状かと思います。ソフトウェア開発を経験したことがある人にとっては言わずもがなですが、長期的にメンテナンスをしていくにあたり

  • いつ変更されたか
  • どのような意図をもって変更されたか
  • 他にどのような変更があったか
  • 誰が変更したか

などは後からコードを読み解くために重要な手がかりになります。また変更に対してレビューを実施し、他のメンバーが適切な変更であるかを把握・確認することも大切です。

このようなバージョン管理やレビューの機能を持たないプロダクトに対しては変更管理票などを用いて上記のような手続きをしているケースが多いのではと思います。しかし手法が標準化されていなかったり、成果物の管理が難しかったりなどで、作業する人物の負担が大きくなってしまいがちです。また、手作業が多い場合は作業者のミスが発生しがちという問題もあります。

このような問題に対してGitを始めとする様々なツール、ベストプラクティス、サービスを活用することで、負担を軽くしつつ作業ミスを減らすことは重要であると考えられます。変更やレビューの記録はあとから参加したメンバーが参照することで、同じような変更をしたいときの手がかりにもなりえるといった、副次的な効果も期待できます。

デプロイの自動化

DevOpsで実践されるCI/CD(Continuous Integration, Continuous Delivery)もポリシーのコード化により実現しやすくなる場合があります。これはプロダクトなどの対応状況に大きく依存するため一概に自動化できるとは言えませんが、自動化できた場合の恩恵はとても大きいです。

GUIベースでの設定変更はアドホックに設定を試すといったような状況ではとても便利です。しかし決まった手順を決まったようにやる、しかも設定のミスが許されないという状況では逆に作業するメンバーの負荷を上げることになります[1]。また、デプロイ方法を手順書としてまとめたとしても、自然言語で書かれた指示は書き手と読み手の両方でゆらぎが発生しがちで、正確に手順を再現できない場合も多々あります[2]。

先述したとおり、ポリシーを頻繁に変更するためにはデプロイの負荷を下げることも重要であり、コード化によって自動化できるのであればぜひ取り組むべきと考えます。

運用の課題

Policy as Code は様々なメリットをもたらしますが、すべての環境に無条件で導入できるというわけではないと考えられます。導入に際して障壁となりそうなポイントをいくつか紹介したいと思います。

ポリシーの読み書き、テストのための知識・経験が必要

ポリシーをコードとして表現する過程では動作や判断の言語化・構造化が必要になりますが、もともとその業務をしていたメンバーがいわゆるプログラミングに関する素養や前提知識があるとは限りません[3]。そのような場合、従来のメンバーがポリシーの読み書きについて学習するか、あるいは他にポリシーの読み書きが得意なメンバーが参入してメンテナンスしていくか、などの筋道を考える必要があります。

利用したいプロダクトの対応が必要

この記事を執筆している時点で Policy as Code の考え方はまだ主流であるとは言い難く、対応しているプロダクトはある程度限られています。OPA/Regoを使うことでプロダクトとポリシーエンジンの分離はできますが、それでもプロダクト側にそもそも「ポリシーを外部参照する」という機能がなければ利用するのは困難です。

コード化した仕組みのメンテナンスが必要

ポリシーをコード化する過程でなんらかのサービスやプロダクトを追加した場合、それをメンテナンスするコストは発生します。例えばOPAをサーバとして設置して使う場合はそのインスタンスなりコンテナサービスなりの面倒をみる必要があります。自動デプロイの仕組みを作った場合、周辺サービスのアップデートなどによって仕組みが動かなくなったら修正する必要があります。

これらの作業は専属の詳しいメンバーがいれば片手間でできる場合もありますが、新たなコストが発生すること自体は認識しておく必要があります。

まとめ

運用上の課題をクリアする必要はあるものの、ポリシーをコード化して得られるメリットは決して小さくないと考えられます。ここでいうポリシーは機械的に処理できれば良いのでコード化については他のプログラミング言語で記述することももちろん可能ですが、このアドベントカレンダーではOPAやRegoを実際にどのように使っていくのかについて、引き続き紹介していきたいと思います。

脚注
  1. 一度ミスが発生すると一緒に作業するメンバーを増やしてダブルチェックするというような対策になりがちで、負担も大きくなります ↩︎

  2. 筆者も過去に手順書によるデプロイをやらざるを得ない業務に携わったことがあり、辛酸をなめさせられた経験があります ↩︎

  3. 例えばSOC (Security Operation Center) のアナリストはサイバー攻撃に関する知識、攻撃に関連した低レイヤのOSやネットワークの知識、アプリケーションの脆弱性に関する知識については卓越していますが、筆者の観測する範囲ではプログラミングの知識量や経験値には相関がなく、得意な人もいればそうでない人もいます ↩︎