LoginSignup
4
0

More than 1 year has passed since last update.

Web ブラウザ上で Wasmを使ってOpen Policy Agent (OPA) を実行

Last updated at Posted at 2021-09-30

はじめに

汎用ポリシーエンジンである Open Policy Agent では、WebAssembly 形式でポリシーを配布可能です。本記事では、WebAssembly 形式で出力された Open Policy Agent のポリシーを Web ブラウザで評価することを試してみた内容を紹介します。

Open Policy Agent とは

Open Policy Agent (OPA) は OSS の軽量で汎用的なポリシーエンジンです。開発時や運用時におけるルール(ポリシー)を事前に定義することで、ポリシーに反する情報を検出できます。OPA はポリシーを定義するための宣言型言語 Rego と、ポリシー評価のためのシンプルな API を提供しています。

WebAssembly とは

WebAssembly とは、 Web ブラウザ上で実行可能なバイナリコードの仕様です。C/C++, Rust などの言語で記述されたプログラムをコンパイルし、Web ブラウザ上で実行します。実行時のパース等が不要で高速に動作させることができるため、ブラウザの機能では実現できなかった処理が可能になります。

また、WebAssembly はプラットフォームに依存せず、高いポータビリティを有していることから、Web ブラウザ以外での活用という点でも注目されています。

WebAssembly と OPA

OPA には、ポリシーを WebAssembly 形式で出力する機能があります。通常ポリシー評価のためには、OPA を Daemon として動作させて API を利用するか、ライブラリとして組み込む(Go 言語に限る)必要があります。ポリシーを Wasm 形式で出力することで、Web ブラウザをはじめ、さまざまなプラットフォーム上で OPA のポリシーを評価できるようになります。

Web ブラウザ上で OPA を動作させる手順

ここからは、OPA のポリシーを WebAssembly (Wasm) 形式で出力し、Web ブラウザ上で実行させる手順を説明していきます。

なお、Node.js 上での実行に関しては、opa-wasm のサンプル等を参考にしてください。

Wasm ファイルの作成

まずは Rego で記述したポリシーから、Wasm ファイルを作成します。 Wasm ファイルの作成には、バンドルファイルを作成するための opa build コマンドを利用します。

$ opa build -t wasm -e 'example/allow' policy/wasm/policy.rego

Wasm 形式でポリシーを出力するには最低 1 つ、エントリーポイントとなるルールを指定する必要があります(-e で指定)。上記の例では、example パッケージの allow というルールがエントリーポイントとなります。

opa build コマンドが成功すると、bundle.tar.gz というバンドルファイルが生成されます。Wasm ファイルはこのバンドルファイルの中に出力されます。

# bundle.tar.gz の中身を確認
$ tar tvf bundle.tar.gz
-rw------- 0/0             128 1970-01-01 09:00 /policy/wasm/policy.rego
-rw------- 0/0          116734 1970-01-01 09:00 /policy.wasm
-rw------- 0/0              87 1970-01-01 09:00 /.manifest
# policy.wasm ファイルのみを解凍
$ tar -xzf bundle.tar.gz /policy.wasm

Wasm 形式の注意点としては、JSON で記述される Data ドキュメントが含まれないという点が挙げられます。Daemon として OPA を実行する場合、ポリシーと一緒に Data ドキュメントが読み込まれ、ポリシーの評価時に Data ドキュメントの情報が参照されます。しかし、Wasm で利用する際には後述するように外部から Data の情報をセットする必要があります。

Wasm ファイルの読み込み (@open-policy-agent/opa-wasm の利用)

作成した Wasm 形式のポリシーを JavaScript で利用するには、@open-policy-agent/opa-wasm パッケージを利用します。

$ npm install @open-policy-agent/opa-wasm

@open-policy-agent/opa-wasm には loadPolicy という関数が用意されており、これを利用して OPA の wasm ファイルを読み込むことができます。

import { loadPolicy } from "@open-policy-agent/opa-wasm";

...
// wasm ファイルを ArrayBufferとして読み込む
const policyWasm = await fetch("/path/to/wasm").then(res => res.arrayBuffer());
// webpack の arraybuffer-loader を利用すればバンドル時に組み込むことも可能
// const policyWasm = require("./path/to/policy.wasm");

const policy = await loadPolicy(policyWasm);

ポリシー評価の実行

loadPolicy によって作成されたオブジェクトには、setData()evaluate() メソッドが提供されています。

setData() はポリシーに Data ドキュメントをセットします。前述の通り、Wasm 形式のポリシーには Data ドキュメントが含まれないため、(API などを利用して) 外部から取得してポリシーに Data ドキュメントをセットします。

const data = { hello: "world" };
policy.setData(data);

evaluate() は Data ドキュメントと入力を基にポリシーを評価し、評価結果が object として返却されます。

input には JSON serializable なオブジェクトを指定します。

const input = { world: "world" };
const result = policy.evaluate(input);
console.log(result);
// {result: true}

おわりに

OPA のポリシーを Wasm 形式で作成し、Web ブラウザ上でポリシー評価をしてみました。Wasm 形式でポリシーを配布できるため、1 つのコードベースから複数のプラットフォームで同じポリシーを適用できる点はかなり有用だと感じました。例えば Web アプリケーションとバックエンドサーバで、同一のポリシーを利用して Payload の Validation を行うといったユースケースも考えられます。

引き続き OPA, WebAsembly の動向に注目していきたいと思います。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0