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

Python SDK

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

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

The Control Zero Python SDK provides deterministic policy enforcement for AI agents running in Python 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 도구에는 코딩 훅을 사용하세요. Python 애플리케이션 코드를 직접 제어할 수 있는 경우에 이 SDK를 사용합니다.

설치​

pip install controlzero

요구 사항:

  • Python 3.9 이상
  • 추가 시스템 종속성 없음

빠른 시작​

배포 모드를 선택하세요.

Hosted 정책을 대시보드에서 가져옵니다.

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

Audit in cloud.

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

from controlzero import Client

# SDK fetches your signed policy bundle on first call.
# Manages audit automatically. No local config needed.
client = Client(api_key="cz_live_your_api_key_here")
# Or use env var: export CONTROLZERO_API_KEY="cz_live_..."

설치: pip install controlzero (1.4.3부터 클라우드 모드 종속성이 기본 설치에 포함됩니다).

구성​

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

Pass only your project API key. 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 entries ship to the remote trail automatically.

from controlzero import Client

client = Client(api_key="cz_live_your_api_key_here")

Local 로컬 정책 파일 사용​

from controlzero import Client

client = Client(policy_file="controlzero.yaml")

Hybrid Hybrid 모드(API 키 + 로컬 정책)​

from controlzero import Client

# Explicit policy_file + api_key: the local file governs enforcement,
# the hosted bundle is IGNORED, audit still ships remotely.
client = Client(api_key="cz_live_your_api_key_here", policy_file="controlzero.yaml")

인라인 정책​

from controlzero import Client

client = 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과 동일한 호출에 일치합니다. 새 정책에서는 표준 이름을 사용하는 것이 좋으며, 레거시 이름을 사용하는 기존 규칙은 변경 없이 계속 동작합니다. SQL 시맨틱 클래스 매핑은 읽기 전용 데이터베이스 레시피를 참조하세요.

와일드카드 리소스 매칭​

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를 전달해야 합니다. 이렇게 하면 범위가 좁은 규칙이 좁게 유지됩니다.

환경 변수​

API 키를 명시적으로 전달하거나 CONTROLZERO_API_KEY 환경 변수로 설정할 수 있습니다. 에이전트 이름은 CZ_AGENT_NAME으로 설정할 수 있습니다.

export CONTROLZERO_API_KEY="cz_live_your_api_key_here"
export CZ_AGENT_NAME="my-analyst-agent"
from controlzero import Client

client = Client() # reads CONTROLZERO_API_KEY from environment

구성 옵션​

매개변수유형기본값설명
api_keystrCONTROLZERO_API_KEY envProject API key. Enables hosted mode: SDK auto-pulls the signed policy bundle from the dashboard and ships audit to the remote trail.
policydictNone규칙이 포함된 인라인 정책 dict.
policy_filestrNoneYAML 또는 JSON 정책 파일 경로.
strict_hostedboolFalseapi_key가 명시적인 policy/policy_file과 함께 전달되면, 한 번 경고하고 로컬 정책을 사용하는 대신 HybridModeError를 발생시킵니다. CI에서 의도하지 않은 로컬 재정의를 찾아내는 데 유용합니다.
refresh_interval_secondsint60Hosted 모드: 대시보드에 새 정책 번들이 있는지 확인하는 주기. 자동 새로 고침을 끄려면 None을 전달하세요. 모든 guard() 호출마다 새로 고치려면 0을 전달하세요(테스트 전용).
log_pathstr"./controlzero.log"로컬 감사 로그 파일 경로.
log_rotationstr"daily"감사 로그 순환 주기.
log_retentionstr"30 days"How long to keep rotated logs.
log_compressionstrNone순환된 로그 압축(예: "gz").
log_formatstr"json"감사 로그 형식.

정책 새로 고침(Hosted 모드)​

대시보드에서 정책을 업데이트하면, 장시간 실행 중인 SDK 프로세스는 새로 고침 주기(기본값: 60초) 안에 변경 사항을 자동으로 반영합니다. SDK는 조건부 요청을 보내므로, 번들이 바뀌지 않았다면 작은 왕복 비용만 듭니다.

세 가지 설정이 있습니다.

  • refresh_interval_seconds=60(기본값): 1분마다 확인합니다.
  • refresh_interval_seconds=None: 백그라운드 확인을 끕니다. 완전한 수동 제어를 위해 client.refresh()와 함께 사용하세요.
  • client.refresh(): 즉시 다시 불러옵니다. 번들이 실제로 변경되었으면 True를, 대시보드에 업데이트가 없으면 False를 반환합니다.
from controlzero import Client

# Long-lived agent, picks up dashboard changes within 60s automatically.
client = Client(api_key="cz_live_your_api_key_here")

# Or: force an immediate reload after a known dashboard change.
changed = client.refresh()
if changed:
print(f"Policy updated at {client.last_refreshed_at.isoformat()}")

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

Network errors during a background refresh are logged at WARNING level and do not raise; the last-known-good bundle keeps working until the next successful pull.

기본 사용법​

도구 호출 평가​

기본 메서드는 guard()이며, 활성 정책을 평가합니다.

from controlzero import Client, PolicyDeniedError

client = Client(policy_file="controlzero.yaml")

decision = client.guard(
"database",
method="query",
args={"sql": "SELECT * FROM orders"},
)
print(decision.effect) # "allow" or "deny"
print(decision.reason) # human-readable reason
print(decision.policy_id) # matching policy ID

거부된 액션 처리​

정책이 액션을 거부하면 결정의 effect를 확인하거나 PolicyDeniedError를 잡으세요.

from controlzero import Client, PolicyDeniedError

client = Client(policy_file="controlzero.yaml")

decision = client.guard(
"filesystem",
method="write_file",
args={"path": "/data/output.csv", "content": "..."},
)
if decision.effect == "deny":
print(f"Blocked: {decision.reason}")
print(f"Policy: {decision.policy_id}")

컨텍스트 관리자​

Client는 컨텍스트 관리자 프로토콜을 구현합니다. with를 사용하면 종료 시 close()가 호출됩니다.

from controlzero import Client

with Client(policy_file="controlzero.yaml") as client:
decision = client.guard("github", method="list_issues", args={"repo": "acme/app"})

API 레퍼런스​

Client​

기본 동기식 클라이언트 클래스입니다.

__init__(api_key=None, policy=None, policy_file=None, strict_hosted=False, log_path="./controlzero.log", log_rotation="daily", log_retention="30 days", log_compression=None, log_format="json")​

새 Control Zero 클라이언트를 생성합니다.

policy와 policy_file을 모두 전달하면 ValueError가 발생합니다.

guard(tool, args=None, method="*", raise_on_deny=False, context=None) -> PolicyDecision​

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

매개변수:

이름유형필수기본값설명
toolstr예-도구 이름. method와 결합되어 액션을 이룹니다.
argsdict아니요NoneDLP 스캔과 조건부 평가에 사용되는 인수.
methodstr아니요"*"메서드 이름. 평가되는 액션은 "{tool}:{method}"입니다.
raise_on_denybool아니요FalseTrue이면 거부 결정 시 PolicyDeniedError를 발생시킵니다.
contextdict아니요None매칭에 사용하는 resource 및 tags 키를 가진 선택적 컨텍스트.

반환값: effect, reason, policy_id, dlp_findings를 가진 PolicyDecision.

close() -> None​

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

Flushes buffered audit logs, wipes secrets from memory, and closes the HTTP connection.

PolicyDecision​

guard()가 반환합니다.

속성유형설명
effectstr"allow" 또는 "deny".
policy_idstr or None일치한 정책(있는 경우).
reasonstr사람이 읽을 수 있는 설명.
dlp_findingslist인수에서 발견된 DLP 일치 항목 목록.

PolicyDeniedError​

정책이 액션을 거부할 때 발생할 수 있습니다.

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

The tool is never invoked.

속성유형설명
e.decisionPolicyDecision전체 결정 객체.
e.decision.effectstr항상 "deny".
e.decision.reasonstr결정에 대한 사람이 읽을 수 있는 설명.
e.decision.policy_idstr or None일치한 정책의 ID(있는 경우).

BundleSignatureError​

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

Raised when a policy bundle fails cryptographic signature verification. The SDK will not load a tampered bundle.

오류 처리​

from controlzero import Client, PolicyDeniedError

client = Client(policy_file="controlzero.yaml")

decision = client.guard("database", method="query", args={"sql": "SELECT 1"})
if decision.effect == "deny":
print(f"Policy denied: {decision.reason}")

client.close()

MCP와 함께 사용​

Control Zero는 MCP 도구 호출을 통제하도록 설계되었습니다. MCP 서버 이름과 도구 이름을 guard()에 그대로 전달하세요.

from controlzero import Client

with Client(api_key="cz_live_your_api_key_here") as client:
decision = client.guard(
"filesystem", # MCP server name
method="read_file", # MCP tool name
args={"path": "/data/report.pdf"},
)
if decision.effect == "deny":
print(f"MCP tool blocked: {decision.reason}")

MCP 통제 패턴에 대한 자세한 안내는 MCP 도구 호출 통제를 참조하세요.

LLM 제공자 래퍼​

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

OpenAI​

from controlzero import Client
from controlzero.integrations.openai import wrap_openai
import openai

client = Client(api_key="cz_live_your_api_key_here")
wrapped = wrap_openai(openai.OpenAI(), client)

response = wrapped.chat.completions.create(
model="gpt-5.4",
messages=[{"role": "user", "content": "Hello"}],
)

Google AI (Gemini)​

from controlzero import Client
from controlzero.integrations.google import wrap_google
from google import genai

client = Client(api_key="cz_live_your_api_key_here")
google_client = genai.Client(api_key="your-google-ai-key")
wrapped_model = wrap_google(google_client.models, client)

response = wrapped_model.generate_content(
model="gemini-2.0-flash",
contents="Summarize the quarterly report",
)
print(response.text)

Anthropic​

from controlzero import Client
from controlzero.integrations.anthropic import wrap_anthropic
import anthropic

client = Client(api_key="cz_live_your_api_key_here")
wrapped = wrap_anthropic(anthropic.Anthropic(), client)

message = wrapped.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)

사용 가능한 래퍼​

함수제공자임포트 경로
wrap_openai()OpenAIcontrolzero.integrations.openai
wrap_anthropic()Anthropic (Claude)controlzero.integrations.anthropic
wrap_google()Google AI (Gemini)controlzero.integrations.google

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