SDK Node.js
Mode yang didukung: Hosted Hybrid Local Tersedia di: Free Solo Teams
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
The Control Zero Node.js SDK provides deterministic policy enforcement for AI agents running in JavaScript and TypeScript environments. A deny stops the guarded call before it executes. Hosted policies arrive as signed bundles that are verified before use, and the SDK fails closed by default when it cannot establish coverage.
Gunakan gateway proxy untuk aplikasi yang tidak dapat Anda ubah dan hook pengodean untuk alat AI developer. Gunakan SDK ini jika Anda mengendalikan kode aplikasi JavaScript atau TypeScript.
Instalasi
Paket @controlzero disajikan dari registry Control Zero
(https://npm.controlzero.ai), bukan npmjs.org. Arahkan scope ke registry
tersebut satu kali di .npmrc Anda (tingkat proyek atau pengguna):
@controlzero:registry=https://npm.controlzero.ai
Kemudian instal:
npm install @controlzero/sdk
Perintah ini menginstal lini 1.13.x saat ini, yang sesuai dengan kumpulan
fitur yang didokumentasikan di halaman ini. Dependensi di luar scope
@controlzero tetap diambil dari npmjs.org.
Persyaratan:
- Node.js 18 atau yang lebih baru
- TypeScript 5.0+ (opsional, untuk penggunaan dengan pemeriksaan tipe)
Mulai Cepat
Pilih mode deployment Anda:
Berbeda dengan SDK Python, konstruktor new Client({apiKey}) di Node.js melempar error
ketika apiKey diberikan tanpa kebijakan lokal. Gunakan factory async untuk mode hosted:
// Hosted mode -- MUST use async factory
const cz = await Client.create({ apiKey: 'cz_live_your_api_key_here' });
// Local mode only -- synchronous constructor works
const cz = new Client({ policyFile: 'controlzero.yaml' });
- Hosted
- Hybrid
- Local
Hosted Kebijakan diambil dari dasbor.
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
Audit in cloud.
Direkomendasikan untuk sebagian besar tim.
import { Client } from '@controlzero/sdk';
// MUST use async factory for hosted mode
const client = await Client.create({ apiKey: 'cz_live_your_api_key_here' });
// Or use env var: export CONTROLZERO_API_KEY="cz_live_..."
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
The SDK pulls the signed policy bundle from the dashboard at first call, verifies its signature, decrypts locally, and enforces every call against the dashboard policy. Audit ships to the remote trail automatically.
Hybrid Anda memiliki file kebijakan.
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
API key enables remote audit only.
import { Client } from '@controlzero/sdk';
const client = await Client.create({
apiKey: 'cz_live_your_api_key_here',
policyFile: './controlzero.yaml',
});
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
Your controlzero.yaml governs enforcement. The API key sends audit to your dashboard.
Local Tanpa kunci API.
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
No network calls.
Sepenuhnya offline. Kompatibel dengan air-gap.
import { Client } from '@controlzero/sdk';
// From a file -- synchronous constructor works for local mode
const client = new Client({ policyFile: './controlzero.yaml' });
// Or inline policy
const client = new Client({
policy: {
rules: [
{ allow: 'database:query', reason: 'Reads are permitted' },
{ deny: 'database:execute', reason: 'Writes are blocked' },
],
},
});
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
Every decision and its event-level coverage is written to ./controlzero.log, so “did not run” remains distinguishable from “ran and found nothing.”
Konfigurasi
Hosted Mode Hosted (Direkomendasikan)
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
Pass only your project API key via the async Client.create factory.
The SDK pulls the signed policy bundle from the dashboard at first
call, verifies its signature, decrypts locally, and enforces every
call against the dashboard policy. Audit ships to the remote trail
automatically.
import { Client } from '@controlzero/sdk';
const client = await Client.create({ apiKey: 'cz_live_your_api_key_here' });
new Client({ apiKey }) (sinkron) menolak untuk dibuat hanya dengan kunci
API dan mengarahkan Anda ke Client.create() -- bootstrap hosted adalah
panggilan I/O dan harus dapat di-await.
Local Dengan File Kebijakan Lokal
import { Client } from '@controlzero/sdk';
const client = new Client({ policyFile: './controlzero.yaml' });
Kebijakan Inline
import { Client } from '@controlzero/sdk';
const client = new Client({
policy: {
rules: [
{ allow: 'database:query', reason: 'Reads are permitted' },
{ deny: 'database:*', reason: 'All other database operations are blocked' },
],
},
});
database:query, database:execute, dan database:delete adalah nama aksi lama yang cocok dengan panggilan yang sama seperti kelas kanonis database:read, database:write, dan database:admin. Kebijakan baru sebaiknya memakai nama kanonis; aturan yang sudah ada dengan nama lama tetap berfungsi tanpa perubahan.
Pencocokan resource dengan wildcard
Aturan yang mencantumkan resources: ['*'] cocok dengan setiap panggilan, terlepas dari apakah pemanggil memberikan context.resource. Gunakan ini ketika sebuah aturan harus berlaku secara universal dan Anda tidak memiliki (atau tidak ingin memberikan) resource per panggilan:
// Policy rule with universal resource matching
// { effect: 'allow', actions: ['database:read'], resources: ['*'] }
// This call matches even though context.resource is not set:
cz.guard('database', { method: 'query', args: { sql: 'SELECT 1' } });
Pola resource non-wildcard (misalnya resources: ['table/orders']) tetap mengharuskan pemanggil memberikan context.resource yang cocok agar aturan berlaku.
Variabel Lingkungan
Anda dapat mengonfigurasi SDK menggunakan variabel lingkungan alih-alih memberikan argumen secara langsung:
export CONTROLZERO_POLICY_FILE="./controlzero.yaml"
import { Client } from '@controlzero/sdk';
// Reads CONTROLZERO_POLICY_FILE from environment, or auto-discovers
// controlzero.yaml, controlzero.yml, or controlzero.json in cwd
const client = new Client();
Opsi Konfigurasi
| Opsi | Variabel Lingkungan | Tipe | Default | Deskripsi |
|---|---|---|---|---|
apiKey | CONTROLZERO_API_KEY | string | - | Project API key. Use Client.create({ apiKey }) to enable hosted mode (auto-pulls the signed policy bundle from the dashboard; remote audit). |
policy | - | object | - | Objek kebijakan inline berisi aturan. |
policyFile | CONTROLZERO_POLICY_FILE | string | - | Path ke file kebijakan YAML atau JSON. |
strictHosted | - | bool | false | Memunculkan error pada hybrid (kunci API + kebijakan lokal) alih-alih memberi peringatan. |
logPath | - | string | ./controlzero.log | Path file log audit lokal. |
logRotation | - | string | daily | Interval rotasi log audit. |
logRetention | - | string | 30 days | How long to keep rotated logs. |
logCompression | - | string | null | Kompres log hasil rotasi (mis. gz). |
logFormat | - | string | json | Format log audit (json atau pretty). |
refreshIntervalSeconds | - | number | 300 | Mode hosted: seberapa sering memeriksa dasbor untuk bundel kebijakan terbaru. |
agentName | CZ_AGENT_NAME | string | - | Label yang dicatat pada peristiwa audit untuk atribusi. |
Nilai default refreshIntervalSeconds pada SDK Node adalah 300 (5 menit).
Nilai default refresh_interval_seconds pada SDK Python adalah 60. Atur
refreshIntervalSeconds: 60 untuk menyamakan kedua interval polling tersebut.
Urutan resolusi kebijakan: opsi policy, opsi policyFile, variabel lingkungan CONTROLZERO_POLICY_FILE, lalu file pertama yang ditemukan otomatis di cwd (controlzero.yaml, kemudian controlzero.yml, kemudian controlzero.json -- yang pertama ada yang dipakai), lalu pass-through no-op dengan satu kali peringatan. File kebijakan dapat berformat YAML atau JSON; keduanya memakai skema yang identik.
Penggunaan Dasar
Mengevaluasi Pemanggilan Alat
Metode utamanya adalah guard(), yang mengevaluasi pemanggilan alat terhadap kebijakan yang dimuat:
import { Client } from '@controlzero/sdk';
const client = new Client({ policyFile: './controlzero.yaml' });
const decision = client.guard('database', {
method: 'query',
args: { sql: 'SELECT * FROM orders' },
});
console.log(decision.effect); // "allow" or "deny"
console.log(decision.reason); // human-readable reason
console.log(decision.policyId); // matching policy ID
Menangani Aksi yang Ditolak
Ketika kebijakan menolak aksi, periksa efek keputusan atau tangkap PolicyDeniedError:
import { Client, PolicyDeniedError } from '@controlzero/sdk';
const client = new Client({ policyFile: './controlzero.yaml' });
const decision = client.guard('filesystem', {
method: 'write_file',
args: { path: '/data/output.csv', content: '...' },
});
if (decision.effect === 'deny') {
console.log(`Blocked: ${decision.reason}`);
console.log(`Policy: ${decision.policyId}`);
}
Atau gunakan raiseOnDeny untuk melempar error saat ditolak:
try {
client.guard('filesystem', {
method: 'write_file',
args: { path: '/data/output.csv' },
raiseOnDeny: true,
});
} catch (error) {
if (error instanceof PolicyDeniedError) {
console.log(`Blocked: ${error.message}`);
}
}
Referensi API
Client
Kelas klien utama. guard() bersifat sinkron. Konstruksi bersifat sinkron untuk
klien dengan kebijakan lokal, hybrid, dan pass-through tanpa kebijakan. Hanya
bootstrap hosted dengan kunci API saja yang memerlukan factory async.
new Client(options?)
Membuat klien Control Zero baru. Lihat Opsi Konfigurasi
untuk parameter yang tersedia. Pemanggilan initialize() tidak diperlukan; konstruktor
langsung memuat kebijakan lokal. Jika tidak ada kebijakan yang dikonfigurasi sama sekali,
klien memberi peringatan satu kali dan meneruskan panggilan.
Memberikan apiKey tanpa kebijakan lokal akan melempar HostedModeNotImplemented.
Gunakan Client.create() untuk mode hosted.
static Client.create(options?): Promise<Client>
Teks asli berbahasa Inggris -- terjemahan menunggu tinjauan teknis
Async factory. Required for hosted mode: it fetches the signed policy bundle, verifies its signature and decrypts it before returning the client.
guard(tool, opts?): PolicyDecision
Mengevaluasi pemanggilan alat terhadap kebijakan yang dimuat.
Parameter:
| Nama | Tipe | Wajib | Deskripsi |
|---|---|---|---|
tool | string | Ya | Nama alat (mis., "database"). |
opts | GuardOptions | Tidak | Objek opsi dengan method, args, raiseOnDeny, context. |
GuardOptions:
| Field | Tipe | Default | Deskripsi |
|---|---|---|---|
method | string | "*" | Nama metode. Digabungkan dengan tool untuk membentuk aksi "tool:method". |
args | object | {} | Argumen untuk pemindaian DLP dan evaluasi bersyarat. |
raiseOnDeny | boolean | false | Jika true, melempar PolicyDeniedError saat ditolak. |
context | object | - | Konteks opsional dengan resource dan tags untuk pencocokan. |
Mengembalikan: PolicyDecision dengan effect, reason, policyId, dan dlpFindings.
close(): Promise<void>
Mengosongkan (flush) log audit yang di-buffer dan melepaskan resource.
PolicyDecision
Dikembalikan oleh guard().
| Atribut | Tipe | Deskripsi |
|---|---|---|
effect | string | "allow" atau "deny". |
policyId | string or null | Kebijakan yang cocok, jika ada. |
reason | string | Penjelasan yang dapat dibaca manusia. |
denied | boolean | Kemudahan: true ketika efeknya "deny". |
dlpFindings | array | Daftar kecocokan DLP yang ditemukan pada argumen. |
PolicyDeniedError
Dilempar oleh guard() ketika raiseOnDeny bernilai true dan kebijakan menolak aksi.
class PolicyDeniedError extends Error {
readonly decision: PolicyDecision;
}
Penggunaan dengan MCP
Control Zero terintegrasi secara alami dengan Model Context Protocol. Berikut contoh membungkus pemanggilan alat MCP dengan penerapan kebijakan:
import { Client, PolicyDeniedError } from '@controlzero/sdk';
const cz = new Client({ policyFile: './controlzero.yaml' });
function callMCPToolGoverned(server: string, tool: string, args: Record<string, unknown>): unknown {
// Evaluate the policy before calling the tool
cz.guard(server, {
method: tool,
args,
raiseOnDeny: true,
});
// Policy check passed. Call the tool
return mcpClient.callTool(server, tool, args);
}
Wrapper Penyedia LLM
SDK Node.js menyertakan wrapper ringan yang menambahkan tata kelola ke klien penyedia LLM yang populer. Setiap wrapper mencegat panggilan, mengevaluasi kebijakan, dan mencatat keputusan tanpa mengubah permukaan API asli penyedia.
Google AI (Gemini)
Menggunakan paket @google/genai terbaru. wrapGoogle membungkus namespace
.models milik klien (bukan satu instance model) sehingga setiap panggilan
generateContent / generateContentStream dikendalikan.
import { Client } from '@controlzero/sdk';
import { wrapGoogle } from '@controlzero/sdk/integrations';
import { GoogleGenAI } from '@google/genai';
const cz = new Client({ policyFile: './controlzero.yaml' });
const googleClient = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const models = wrapGoogle(googleClient.models, cz, { agentId: 'my-agent' });
const result = await models.generateContent({
model: 'gemini-2.0-flash',
contents: 'Summarize the quarterly report',
});
console.log(result.text);
Anthropic
import { Client } from '@controlzero/sdk';
import Anthropic from '@anthropic-ai/sdk';
const cz = new Client({ policyFile: './controlzero.yaml' });
const anthropic = new Anthropic({ apiKey: 'your-anthropic-key' });
import { wrapAnthropic } from '@controlzero/sdk/integrations';
const wrappedClient = wrapAnthropic(anthropic, cz);
const message = await wrappedClient.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Summarize the quarterly report' }],
});
console.log(message.content[0].text);
Wrapper yang Tersedia
| Fungsi | Penyedia | Path Impor |
|---|---|---|
wrapGoogle() | Google AI (Gemini) | @controlzero/sdk/integrations |
wrapAnthropic() | Anthropic (Claude) | @controlzero/sdk/integrations |
wrapOpenAI() | OpenAI | @controlzero/sdk/integrations |
Semua wrapper menerapkan pemeriksaan pra-eksekusi (pemblokiran model, estimasi biaya, deteksi PII) dan mencatat permintaan ke jejak audit. Jika kebijakan menolak permintaan, PolicyDeniedError dilempar sebelum panggilan mencapai penyedia.
Penanganan Kesalahan
import { Client, PolicyDeniedError } from '@controlzero/sdk';
const client = new Client({ policyFile: './controlzero.yaml' });
try {
client.guard('database', {
method: 'query',
args: { sql: 'SELECT 1' },
raiseOnDeny: true,
});
} catch (error) {
if (error instanceof PolicyDeniedError) {
console.log(`Denied: ${error.decision.reason}`);
}
}
await client.close();
Dukungan CommonJS
SDK mendukung ESM maupun CommonJS:
// ESM
import { Client } from '@controlzero/sdk';
// CommonJS
const { Client } = require('@controlzero/sdk');
Nama lama ControlZeroClient diekspor sebagai alias kompatibilitas mundur untuk Client.
TypeScript
SDK ditulis dalam TypeScript dan menyertakan deklarasi tipe lengkap. Semua tipe diekspor dari entry point utama:
import type { PolicyDecision } from '@controlzero/sdk';
import type { ClientOptions, GuardOptions } from '@controlzero/sdk';