본문으로 건너뛰기
이 페이지는 기계 번역이며 충분한 검토를 거치지 않았습니다. 영어 원문이 기준입니다. 보안, 개인정보 보호, 데이터 처리, 규정 준수 및 라이선스에 관한 설명은 기술 검토가 끝날 때까지 영어로 유지됩니다. 영어 원문 보기

Node.js SDK

지원 모드: Hosted Hybrid Local 제공 플랜: Free Solo Teams

영어 원문 -- 번역은 기술 검토 대기 중입니다

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.

알맞은 적용 지점 선택

수정할 수 없는 애플리케이션에는 게이트웨이 프록시를, 개발자용 AI 도구에는 코딩 훅을 사용하세요. JavaScript 또는 TypeScript 애플리케이션 코드를 직접 제어할 수 있는 경우에 이 SDK를 사용합니다.

설치​

@controlzero 패키지는 npmjs.org가 아니라 Control Zero 레지스트리 (https://npm.controlzero.ai)에서 제공됩니다. .npmrc(프로젝트 또는 사용자 수준)에서 스코프가 이 레지스트리를 가리키도록 한 번만 설정하세요.

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

그런 다음 설치합니다.

npm install @controlzero/sdk

이 명령은 이 페이지에 문서화된 기능 집합과 일치하는 현재 1.13.x 버전 계열을 설치합니다. @controlzero 스코프 외부의 종속성은 계속 npmjs.org에서 가져옵니다.

요구 사항:

  • Node.js 18 이상
  • TypeScript 5.0+ (선택 사항, 타입 검사를 사용하는 경우)

빠른 시작​

배포 모드를 선택하세요.

Hosted 모드는 비동기 초기화가 필요합니다

Python SDK와 달리, Node.js의 new Client({apiKey}) 생성자는 로컬 정책 없이 apiKey만 제공하면 오류를 발생시킵니다. 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 정책을 대시보드에서 가져옵니다.

영어 원문 -- 번역은 기술 검토 대기 중입니다

Audit in cloud.

대부분의 팀에 권장합니다.

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_..."

영어 원문 -- 번역은 기술 검토 대기 중입니다

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.

구성​

영어 원문 -- 번역은 기술 검토 대기 중입니다

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 })(동기식)는 API 키만으로는 생성을 거부하고 Client.create()를 사용하도록 안내합니다. Hosted 부트스트랩은 I/O 호출이므로 await할 수 있어야 하기 때문입니다.

Local 로컬 정책 파일 사용​

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

const client = new Client({ policyFile: './controlzero.yaml' });

인라인 정책​

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, database:delete는 레거시 액션 이름으로, 표준 클래스인 database:read, database:write, database:admin과 동일한 호출에 일치합니다. 새 정책에서는 표준 이름을 사용하는 것이 좋으며, 레거시 이름을 사용하는 기존 규칙은 변경 없이 계속 동작합니다.

와일드카드 리소스 매칭​

resources: ['*']를 나열한 규칙은 호출자가 context.resource를 전달했는지와 관계없이 모든 호출에 일치합니다. 규칙을 모든 호출에 보편적으로 적용해야 하고 호출별 리소스가 없거나 전달하고 싶지 않을 때 사용하세요.

// 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' } });

와일드카드가 아닌 리소스 패턴(예: resources: ['table/orders'])은 규칙이 적용되려면 호출자가 일치하는 context.resource를 전달해야 합니다.

환경 변수​

인수를 직접 전달하는 대신 환경 변수로 SDK를 구성할 수 있습니다.

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();

구성 옵션​

옵션환경 변수유형기본값설명
apiKeyCONTROLZERO_API_KEYstring-Project API key. Use Client.create({ apiKey }) to enable hosted mode (auto-pulls the signed policy bundle from the dashboard; remote audit).
policy-object-규칙이 포함된 인라인 정책 객체.
policyFileCONTROLZERO_POLICY_FILEstring-YAML 또는 JSON 정책 파일 경로.
strictHosted-boolfalseHybrid(API 키 + 로컬 정책) 구성에서 경고하는 대신 오류를 발생시킵니다.
logPath-string./controlzero.log로컬 감사 로그 파일 경로.
logRotation-stringdaily감사 로그 순환 주기.
logRetention-string30 daysHow long to keep rotated logs.
logCompression-stringnull순환된 로그 압축(예: gz).
logFormat-stringjson감사 로그 형식(json 또는 pretty).
refreshIntervalSeconds-number300Hosted 모드: 대시보드에 새 정책 번들이 있는지 확인하는 주기.
agentNameCZ_AGENT_NAMEstring-귀속을 위해 감사 이벤트에 기록되는 레이블.
Node는 300초마다, Python은 60초마다 새로 고침

Node SDK의 기본 refreshIntervalSeconds는 300(5분)입니다. Python SDK의 기본 refresh_interval_seconds는 60입니다. 두 폴링 주기를 맞추려면 refreshIntervalSeconds: 60으로 설정하세요.

정책 확인 순서: policy 옵션, policyFile 옵션, CONTROLZERO_POLICY_FILE 환경 변수, 그다음 cwd에서 자동 탐색된 첫 번째 파일(controlzero.yaml, 그다음 controlzero.yml, 그다음 controlzero.json -- 먼저 존재하는 파일이 우선), 그 이후에는 한 번 경고를 출력하고 아무 동작 없이 통과시킵니다. 정책 파일은 YAML 또는 JSON일 수 있으며, 둘 다 동일한 스키마를 사용합니다.

기본 사용법​

도구 호출 평가​

기본 메서드는 guard()이며, 로드된 정책에 대해 도구 호출을 평가합니다.

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

거부된 액션 처리​

정책이 액션을 거부하면 결정의 effect를 확인하거나 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}`);
}

또는 raiseOnDeny를 사용해 거부 시 예외를 던지게 할 수 있습니다.

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}`);
}
}

API 레퍼런스​

Client​

기본 클라이언트 클래스입니다. guard()는 동기식입니다. 로컬 정책, Hybrid, 정책 없는 통과(pass-through) 클라이언트는 생성도 동기식입니다. API 키만 사용하는 Hosted 부트스트랩만 비동기 팩토리가 필요합니다.

new Client(options?)​

새 Control Zero 클라이언트를 생성합니다. 사용 가능한 매개변수는 구성 옵션을 참조하세요. initialize() 호출은 필요하지 않으며, 생성자가 로컬 정책을 즉시 불러옵니다. 정책이 전혀 구성되지 않은 경우 클라이언트는 한 번 경고하고 호출을 그대로 통과시킵니다.

로컬 정책 없이 apiKey를 전달하면 HostedModeNotImplemented가 발생합니다. Hosted 모드에는 Client.create()를 사용하세요.

static Client.create(options?): Promise<Client>​

영어 원문 -- 번역은 기술 검토 대기 중입니다

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​

로드된 정책에 대해 도구 호출을 평가합니다.

매개변수:

이름유형필수설명
toolstring예도구 이름(예: "database").
optsGuardOptions아니요method, args, raiseOnDeny, context를 가진 옵션 객체.

GuardOptions:

필드유형기본값설명
methodstring"*"메서드 이름. 도구와 결합되어 "tool:method" 액션을 이룹니다.
argsobject{}DLP 스캔과 조건부 평가에 사용되는 인수.
raiseOnDenybooleanfalsetrue이면 거부 시 PolicyDeniedError를 던집니다.
contextobject-매칭에 사용하는 resource 및 tags를 가진 선택적 컨텍스트.

반환값: effect, reason, policyId, dlpFindings를 가진 PolicyDecision.

close(): Promise<void>​

버퍼에 남은 감사 로그를 비우고 리소스를 해제합니다.

PolicyDecision​

guard()가 반환합니다.

속성유형설명
effectstring"allow" 또는 "deny".
policyIdstring or null일치한 정책(있는 경우).
reasonstring사람이 읽을 수 있는 설명.
deniedboolean편의 속성: effect가 "deny"이면 true.
dlpFindingsarray인수에서 발견된 DLP 일치 항목 목록.

PolicyDeniedError​

raiseOnDeny가 true이고 정책이 액션을 거부하면 guard()가 던집니다.

class PolicyDeniedError extends Error {
readonly decision: PolicyDecision;
}

MCP와 함께 사용​

Control Zero는 Model Context Protocol과 자연스럽게 통합됩니다. 다음은 MCP 도구 호출을 정책 적용으로 감싸는 예시입니다.

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);
}

LLM 제공자 래퍼​

Node.js SDK에는 널리 쓰이는 LLM 제공자 클라이언트에 거버넌스를 추가하는 경량 래퍼가 포함되어 있습니다. 각 래퍼는 제공자의 기본 API 표면을 변경하지 않으면서 호출을 가로채고, 정책을 평가하고, 결정을 기록합니다.

Google AI (Gemini)​

현재의 @google/genai 패키지를 사용합니다. wrapGoogle은 단일 모델 인스턴스가 아니라 클라이언트의 .models 네임스페이스를 감싸므로, 모든 generateContent / generateContentStream 호출이 통제됩니다.

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);

사용 가능한 래퍼​

함수제공자임포트 경로
wrapGoogle()Google AI (Gemini)@controlzero/sdk/integrations
wrapAnthropic()Anthropic (Claude)@controlzero/sdk/integrations
wrapOpenAI()OpenAI@controlzero/sdk/integrations

모든 래퍼는 사전 점검(모델 차단, 비용 추정, PII 탐지)을 적용하고 요청을 감사 기록에 남깁니다. 정책이 요청을 거부하면 호출이 제공자에 도달하기 전에 PolicyDeniedError가 던져집니다.

오류 처리​

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();

CommonJS 지원​

SDK는 ESM과 CommonJS를 모두 지원합니다.

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

// CommonJS
const { Client } = require('@controlzero/sdk');

레거시 이름 ControlZeroClient는 Client에 대한 하위 호환 별칭으로 내보내집니다.

TypeScript​

SDK는 TypeScript로 작성되었으며 전체 타입 선언을 함께 제공합니다. 모든 타입은 메인 진입점에서 내보내집니다.

import type { PolicyDecision } from '@controlzero/sdk';
import type { ClientOptions, GuardOptions } from '@controlzero/sdk';