OPA(Open Policy Agent)は Rego 言語で記述されたポリシーを用いて、入力(input)や外部データ(data)に基づいて評価を行い、許可/拒否などの判定を行うエンジンである。
実装例については、AWS Prescriptive Guidance のマルチテナント API 認可制御ガイドが参考になる。OPA を活用した SaaS におけるマルチテナント認可の実装戦略が紹介されており、本稿の背景理解にも役立つ。
以下はOPAを使ったアクセス制御の基本的なシーケンスである。
sequenceDiagram
participant Client as クライアント
participant API as アプリケーション
participant OPA as OPA
participant Policy as Regoポリシー
participant Data as 外部データ
Client->>API: リクエスト送信
API->>OPA: input を含む評価要求
OPA->>Data: ポリシー評価用データ取得
Data-->>OPA: リソースデータ
OPA->>Policy: Rego ポリシーで評価
Policy-->>OPA: 結果(allow/deny)
OPA-->>API: 判定結果
API-->>Client: 応答
以下はページネーションにおいて OPA をナイーブに適用した場合のシーケンスである。
sequenceDiagram
participant Client
participant API
participant DB
participant OPA
Client->>API: GET /resources?page=P&size=N
Note over API: OFFSET/LIMIT で DB に問い合わせ【OPA前】
API->>DB: SELECT ... OFFSET (P-1)*N LIMIT N
DB-->>API: N件取得(未フィルタ)
Note over API: 各リソースを OPA で評価
API->>OPA: ポリシー評価(リソース単位)
OPA-->>API: 許可 or 拒否
alt 許可リソース数 >= N
API-->>Client: N件返却
else 許可数が不足
loop 許可リソースがN件に達すまで繰り返し
API->>DB: 次のOFFSETで追加取得
DB-->>API: 追加データ
API->>OPA: ポリシー評価
OPA-->>API: 許可 or 拒否
end
API-->>Client: 許可された最大N件を返却
end
sequenceDiagram
participant Client as クライアント
participant App as アプリケーション
participant DB as データベース
Client->>App: GET /items?page=P&size=N
Note over App: page, size から OFFSET, LIMIT 計算
App->>DB: SELECT * FROM items WHERE <条件> ORDER BY ... LIMIT N OFFSET (P-1)*N
DB-->>App: N件(または残り分だけ)
App-->>Client: 結果返却
sequenceDiagram
participant Client as クライアント
participant App as アプリケーション
participant DB as データベース
Client->>App: GET /items?after=<cursor>&size=N
Note over App: カーソル以降を WHERE で指定
App->>DB: SELECT * FROM items WHERE id > <cursor> ORDER BY id ASC LIMIT N
DB-->>App: N件の結果
App-->>Client: 返却 (next_cursor 付)
観点 | SQLフィルタリングで可能だったこと | OPAナイーブ評価での制約 |
---|---|---|
件数の把握 | WHERE句で事前に総件数を取得可能 | 評価後でなければ許可件数が確定せず、事前の予測ができない |
順序の一貫性 | ORDER BY+OFFSET/LIMITで安定した順序とスライスを実現 | 拒否リソースが混在すると、表示順序やページ境界が不安定になる |
ページ番号の整合性 | 「21件目~40件目」といった明示的なページ表示が可能 | 許可結果ベースでのみページを組み立てる必要があり、整合性が崩れる |
クエリ効率 | インデックス活用などにより最小限の取得・処理が可能 | 許可件数が足りないたびに再取得・再評価が必要で負荷が高まる |
事前に対象リソースを全件取得し、それらを OPA に渡して評価を行う方式。OPA は各リソースに対する許可/拒否の判定に加え、許可リストや拒否件数といった集計情報を返すことで、アプリ側でのページネーションや総ヒット件数の表示が可能となる。
OPAポリシーを「許可条件を表すSQL WHERE句相当の条件」として部分評価し、アプリ側でSQLクエリに適用する方式。
バックエンドは全許可リソースを返し、クライアント側でページングする方式。
OPA をナイーブに適用したリスト取得においては、ページネーションとポリシー評価の非整合によって、返却件数の不定・処理負荷の増大・ページ境界の曖昧化・ユーザー体験の低下といった複合的な問題が発生する。
ページネーションにおける OPA 適用にはトレードオフが存在する。「何を重視するか(実装容易性・性能・表現力・整合性)」を明確にした上で、実装を検討する必要がある。