メインコンテンツまでスキップ
このページは機械翻訳であり、十分なレビューを経ていません。英語の原文が正となります。セキュリティ、プライバシー、データの取り扱い、コンプライアンス、ライセンスに関する記述は、技術レビューが完了するまで英語のまま掲載しています。 英語の原文を読む

クイックスタート

対応モード: Hosted Hybrid Local 利用可能なプラン: Free Solo Teams

5 分足らずで、エージェントに AI ガバナンスを追加できます。デプロイ方法は 2 通りあります。状況に合うほうを選んでください。

方法適したケースコード変更
ゲートウェイ(オプション A)既存のエージェント、素早い導入なし。URL を 1 つ変更するだけ
SDK(オプション B)新規のエージェント、最も緊密な統合パッケージをインストールし、ツール呼び出しをラップ

どちらも、ダッシュボードで定義した同じポリシーを適用します。

ステップ 1: サインアップ​

  1. app.controlzero.ai にアクセスして、アカウントを作成します。
  2. まず試してみたい場合は、app.controlzero.ai/demo のインタラクティブなデモをお試しください。アカウントは不要です。

無料プランには、月 5,000 件のガバナンス対象アクションが含まれ、クレジットカードは不要です。

ステップ 2: プロジェクトを作成する​

  1. サインイン後、2 ステップのオンボーディングで最初のプロジェクトを作成します。
  2. プロジェクトに名前を付け(例: my-agent)、環境を選択します。
  3. プロジェクトの設定ページから API Key をコピーします(例: cz_live_abc123...)。

環境変数として設定します。

export CONTROLZERO_API_KEY="cz_live_your_key_here"

ステップ 3: ダッシュボードでポリシーを定義する​

ポリシーは組織レベルの Policy Library に置かれ、プロジェクトにアタッチします。これにより、1 つのポリシーで多数のプロジェクトを統制しつつ、プロジェクトごとに上書きすることもできます。

3a. ライブラリポリシーを作成する​

サイドバーの Library をクリックし、続けて New policy をクリックします。

  • Name: db-read-only
  • Description: エージェントはデータベースにクエリできますが、データを変更することはできません。
  • Rules (JSON array): 以下のスニペットを貼り付けるか、Insert sample をクリックします。
[
{ "effect": "allow", "actions": ["database:read"], "resources": ["*"] },
{ "effect": "deny", "actions": ["database:write"], "resources": ["*"] },
{ "effect": "deny", "actions": ["database:admin"], "resources": ["*"] }
]

Create & publish v1 をクリックします。ポリシーは保存され、バージョン 1 として自動的に公開されるため、すぐにアタッチできます。

正規のルール形式

actions、resources、principals は配列です。作成ダイアログは、古いドキュメントにある単数形のフラットな action / resource 形式も受け付け、自動的に正規化します。

SQL のセマンティッククラス

database:read は、SELECT、EXPLAIN、SHOW、DESCRIBE、CTE の各ステートメントを、方言ごとのキーワードの綴りに関係なくカバーする、移植性のある正規クラスです。database:write は INSERT/UPDATE/DELETE/MERGE など、データを変更するステートメントをカバーします。database:admin はスキーマや権限の変更をカバーします。SELECT 1; DROP TABLE x のような複数ステートメントの便乗は database:admin として解決されるため、deny: database:admin ルールが、公開済みのすべてのバージョンでそれを捕捉します。許可のみの形(明示的な deny ルールなし)では、method を渡したときに破壊的な SQL を正しくブロックするために controlzero 1.13.13+ が必要です。以前のバージョンでは、引数から導出されたクラスが参照される前に、メソッドから導出されたクラスが allow ルールを満たしてしまうことがあったため、許可されていました。より細かく制御したい場合は、特定のキーワード(例: database:DROP)を対象にすることもできます。対応表の全体はCanonical Tool Namesを参照してください。

3b. ポリシーをプロジェクトにアタッチする​

プロジェクトを開き、Attach policy をクリックして db-read-only を選び、状態は Active のままにして確定します。これでプロジェクトのポリシーバンドルがルールを適用します。クライアントは次回のリフレッシュ時にそれらを取り込みます。Python SDK はデフォルトで 60 秒ごと、Node SDK は 300 秒ごとにポーリングします。

ステップ 4: エージェントを統合する​

オプション A: ゲートウェイ(コード変更なし)​

ゲートウェイは透過的なプロキシです。LLM のベース URL をゲートウェイに向け、ヘッダーを 2 つ追加します。既存のエージェントのコードはそのまま動作します。

英語の原文 -- 翻訳は技術レビュー待ちです

The gateway enforces policies on every request and response automatically.

1. ベース URL を変更する​

Anthropic(Claude):

# Before
ANTHROPIC_BASE_URL=https://api.anthropic.com

# After
ANTHROPIC_BASE_URL=https://gateway.controlzero.ai

OpenAI:

# Before
OPENAI_BASE_URL=https://api.openai.com

# After
OPENAI_BASE_URL=https://gateway.controlzero.ai/v1

2. Control Zero のヘッダーを追加する​

すべての LLM リクエストに、次のヘッダーを追加します。

X-ControlZero-API-Key: cz_live_your_key_here
X-ControlZero-Agent-ID: my-first-agent
  • X-ControlZero-API-Key(必須)は、ダッシュボードのプロジェクトキーです。
  • X-ControlZero-Agent-ID(任意)は、監査上の帰属のために呼び出し元にラベルを付けます。省略した場合は <provider>-direct になります。

3. 試してみる(Anthropic)​

curl -X POST https://gateway.controlzero.ai/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "X-ControlZero-API-Key: $CONTROLZERO_API_KEY" \
-H "X-ControlZero-Agent-ID: my-first-agent" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 100,
"messages": [{"role": "user", "content": "What is 2+2?"}]
}'

Anthropic の API キー(x-api-key)は Anthropic での認証に使われます。Control Zero の API キー(X-ControlZero-API-Key)は、ガバナンス、監査ログ、ポリシーの適用を有効にします。どちらも必須です。

以上です。ゲートウェイはすべての LLM レスポンスをインターセプトし、ツール呼び出しをポリシーに照らして評価し、許可されていないアクションをブロックします。事前チェック(モデルのブロック、コスト上限、PII 検出)は、リクエストがプロバイダーに届く前に、すべてのリクエストで実行されます。

セルフホストでのデプロイ、対応プロバイダー、設定の詳細は、ゲートウェイガイドを参照してください。

オプション B: SDK 統合​

SDK をインストールして、アプリケーションレベルでツール呼び出しを統制します。

英語の原文 -- 翻訳は技術レビュー待ちです

With an API key the SDK pulls your signed policy bundle from the dashboard automatically -- no local policy file required.

ツールを実行する前に guard() を呼び出してください。

1. SDK をインストールする​

Python:

pip install controlzero

要件: Python 3.9 以降。

Node.js:

@controlzero パッケージは Control Zero のレジストリから提供されます。.npmrc(プロジェクトレベルまたはユーザーレベル)で、スコープをそのレジストリに 1 回だけ向けてください。

@controlzero:registry=https://npm.controlzero.ai

そのうえでインストールします。

npm install @controlzero/sdk

@controlzero スコープ外の依存関係は、引き続き npmjs.org から解決されます。

2. AI アプリにガバナンスを追加する(Hosted モード)​

Python:

from controlzero import Client

# SDK pulls your dashboard policy on first call. Signed bundle, verified
# locally. Audit streams to the dashboard trail.
cz = Client(api_key="cz_live_your_key_here")

# Policies are managed in app.controlzero.ai, not in code. The SDK
# derives the SQL semantic class (read|write|admin|exec) from the
# `sql` argument, so a `database:read` rule fires for SELECT,
# EXPLAIN, SHOW, and CTE statements regardless of dialect.
result = cz.guard("database", method="SELECT", args={"sql": "SELECT id FROM orders"})
print(result.decision) # "allow" or "deny" per dashboard rules

result = cz.guard("database", method="DROP", args={"sql": "DROP TABLE orders"})
print(result.decision) # typically "deny" (matches database:admin)
print(result.reason)

# Or raise on deny:
from controlzero import PolicyDeniedError
try:
cz.guard("database", method="DROP", args={"sql": "DROP TABLE orders"}, raise_on_deny=True)
except PolicyDeniedError as e:
print(f"Blocked: {e.decision.reason}")

cz.close()

Node.js:

import { Client } from '@controlzero/sdk';

// Hosted mode uses the async factory. The SDK pulls your dashboard
// policy on first call, verifies signature, decrypts, and enforces.
const cz = await Client.create({ apiKey: 'cz_live_your_key_here' });

const result = cz.guard('database', {
method: 'SELECT',
args: { sql: 'SELECT id FROM orders' },
});
console.log(result.decision); // "allow" or "deny"

await cz.close();

2 つのモード、1 つのクライアント:

  • 英語の原文 -- 翻訳は技術レビュー待ちです

    Hosted mode (api_key=...): the SDK pulls the signed policy bundle from the dashboard, verifies and decrypts it locally, and ships audit to the remote trail. Keys and bundles are cached under ~/.controlzero/cache/ so restarts work offline. This is the recommended flow -- policies live where your team can manage them.

  • 英語の原文 -- 翻訳は技術レビュー待ちです

    Local mode (policy=... or policy_file=...): zero network for policy eval. Audit stays in a rotating local file.

    エアギャップ環境でのデプロイや、リポジトリにチェックインした controlzero.yaml に適しています。

guard() メソッドは、decision("allow" または "deny")と reason のフィールドを持つ PolicyDecision を返します。deny の判定を返す代わりに PolicyDeniedError を発生させるには、raise_on_deny=True を渡します。

呼び出しがブロックされたときの動作​

guard() の呼び出しが deny の判定を返した場合は、結果を確認するか、例外を発生させることができます。

from controlzero import Client, PolicyDeniedError

cz = Client(api_key="cz_live_your_key")

# Check the decision object. Note: `database:execute` is a legacy action
# name. The canonical name is `database:write`; both forms match the
# same calls.
result = cz.guard("database", method="execute", args={"sql": "DROP TABLE orders"})
if result.effect == "deny":
print(f"Blocked: {result.reason}")
# result.effect = "deny"
# result.reason = human-readable explanation
# result.policy_id = which policy matched

# Or raise on deny
try:
cz.guard("database", method="execute", args={"sql": "DROP TABLE orders"}, raise_on_deny=True)
except PolicyDeniedError as e:
print(f"Blocked by policy {e.decision.policy_id}: {e.decision.reason}")

ステップ 5: コンテキストマネージャーを使う(任意)​

Client はコンテキストマネージャープロトコルをサポートしており、終了時に close() を呼び出して監査ログをフラッシュします。

from controlzero import Client, PolicyDeniedError

with Client(policy_file="./controlzero.yaml") as cz:
result = cz.guard(
"filesystem",
{"path": "/data/report.csv"},
method="read_file",
context={"resource": "/data/report.csv"},
)
if result.denied:
print(f"Access denied: {result.reason}")
else:
print(f"Allowed: {result.reason}")

ガバナンスの総合シナリオ​

次のエンドツーエンドの例は、データベースから読み取り、許可されていない書き込みを試みる現実的なエージェントを示します。書き込みは、ツールが呼び出される前にポリシーによってブロックされます。

from controlzero import Client

policy = {
"rules": [
{"allow": "database:read", "reason": "Reads are permitted"},
{"deny": "database:*", "reason": "All other database operations are blocked"},
]
}

def run_analyst_agent(cz: Client) -> None:
# Step 1: check if read is allowed. The SDK derives the SQL
# semantic class (read) from the `sql` argument, so the
# `database:read` rule fires.
read_decision = cz.guard(
"database",
{"sql": "SELECT * FROM orders WHERE region = 'APAC'"},
method="SELECT",
)
print(f"Read decision: {read_decision.decision} - {read_decision.reason}")

# Step 2: check if write is allowed (it will be denied; class is `write`)
write_decision = cz.guard(
"database",
{"sql": "UPDATE orders SET status = 'processed' WHERE region = 'APAC'"},
method="UPDATE",
)
print(f"Write decision: {write_decision.decision} - {write_decision.reason}")

with Client(policy=policy) as cz:
run_analyst_agent(cz)

期待される出力:

Read decision: allow - Reads are permitted
Write decision: deny - All other database operations are blocked

監査ログを見る​

英語の原文 -- 翻訳は技術レビュー待ちです

Every guard() decision, allowed or denied, is automatically logged.

ダッシュボードでプロジェクトに移動し、Audit Log をクリックすると、次の内容が表示されます。

英語の原文 -- 翻訳は技術レビュー待ちです

This is a complete decision trail, not a sample. Each entry records coverage for that event, so “did not run” is distinguishable from “ran and found nothing.”

タイムスタンプツールメソッド判定エージェント
12:00:01databaseSELECTallowagent-analyst
12:00:02databaseUPDATEdenyagent-analyst

SDK リファレンス: 主なメソッド​

Client.__init__()​

def __init__(
self,
api_key: str = None, # optional, for hosted mode (cz_live_ or cz_test_)
policy: dict = None, # inline policy dict with "rules" key
policy_file: str = None, # path to controlzero.yaml policy file
strict_hosted: bool = False, # raise on hybrid (API key + local policy) instead of warn
log_path: str = "./controlzero.log", # local audit log path
log_rotation: str = "daily", # audit log rotation interval
log_retention: str = "30 days", # how long to keep rotated logs
log_compression: str = None, # compress rotated logs (e.g. "gz")
log_format: str = "json", # audit log format
): ...

ポリシーの解決順序: policy= 引数、policy_file= 引数、CONTROLZERO_POLICY_FILE 環境変数、次にカレントディレクトリで最初に自動検出されたファイル(controlzero.yaml、次に controlzero.yml、次に controlzero.json -- 最初に存在したものが優先)、次に CONTROLZERO_API_KEY 環境変数(Hosted モード)、最後に何もしないパススルーです。ポリシーファイルは YAML でも JSON でもよく、どちらも同一のスキーマを使います。

Client.guard(tool, args, method, raise_on_deny, context)​

ロードされたポリシーに照らして、ツール呼び出しを評価します。decision("allow" または "deny")、reason、policy_id のフィールドを持つ PolicyDecision を返します。評価されるアクション文字列は "{tool}:{method}" です。

raise_on_deny=True を渡すと、deny の判定を返す代わりに PolicyDeniedError を発生させます。

Client.close()​

バッファされた監査ログをフラッシュし、開いている接続をすべて閉じます。

PolicyDeniedError​

raise_on_deny=True でポリシーがアクションを拒否したときに、guard() によって発生します。

属性型説明
e.decision.effectstr常に "deny"。
e.decision.reasonstr人が読める説明。
e.decision.policy_idstr一致したポリシーの ID。なければ None。

デバッグ​

CZ_DEBUG=1 を設定すると、stderr に詳細なデバッグ出力が有効になります。すべてのポリシー評価、キャッシュのヒット/ミス、監査ログのフラッシュが出力され、ガバナンスの問題の診断に役立ちます。

CZ_DEBUG=1 python my_agent.py

デバッグ出力のサンプル:

[CZ DEBUG] initialized client agent=my-agent project=proj_abc123
[CZ DEBUG] policy_eval tool=database method=SELECT action=database:SELECT class=database:read effect=allow policy_id=db-read-only latency_ms=0.12
[CZ DEBUG] policy_eval tool=database method=UPDATE action=database:UPDATE class=database:write effect=deny policy_id=db-read-only latency_ms=0.08
[CZ DEBUG] audit_flush count=2 status=ok

latency_ms フィールドは、ポリシー評価にかかった時間を示します。

英語の原文 -- 翻訳は技術レビュー待ちです

Policy evaluation is local and does not make network requests.

次のステップ​