controlzero 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. controlzero-1.0.0/.gitignore +220 -0
  2. controlzero-1.0.0/Dockerfile.test +24 -0
  3. controlzero-1.0.0/LICENSE +17 -0
  4. controlzero-1.0.0/PKG-INFO +232 -0
  5. controlzero-1.0.0/README.md +194 -0
  6. controlzero-1.0.0/controlzero/__init__.py +41 -0
  7. controlzero-1.0.0/controlzero/_internal/__init__.py +1 -0
  8. controlzero-1.0.0/controlzero/_internal/dlp_scanner.py +777 -0
  9. controlzero-1.0.0/controlzero/_internal/enforcer.py +210 -0
  10. controlzero-1.0.0/controlzero/_internal/types.py +19 -0
  11. controlzero-1.0.0/controlzero/audit_local.py +128 -0
  12. controlzero-1.0.0/controlzero/audit_remote.py +221 -0
  13. controlzero-1.0.0/controlzero/cli/__init__.py +1 -0
  14. controlzero-1.0.0/controlzero/cli/main.py +1177 -0
  15. controlzero-1.0.0/controlzero/cli/templates/autogen.yaml +79 -0
  16. controlzero-1.0.0/controlzero/cli/templates/claude-code.yaml +85 -0
  17. controlzero-1.0.0/controlzero/cli/templates/codex-cli.yaml +80 -0
  18. controlzero-1.0.0/controlzero/cli/templates/cost-cap.yaml +64 -0
  19. controlzero-1.0.0/controlzero/cli/templates/crewai.yaml +83 -0
  20. controlzero-1.0.0/controlzero/cli/templates/cursor.yaml +86 -0
  21. controlzero-1.0.0/controlzero/cli/templates/gemini-cli.yaml +85 -0
  22. controlzero-1.0.0/controlzero/cli/templates/generic.yaml +57 -0
  23. controlzero-1.0.0/controlzero/cli/templates/langchain.yaml +89 -0
  24. controlzero-1.0.0/controlzero/cli/templates/mcp.yaml +79 -0
  25. controlzero-1.0.0/controlzero/cli/templates/rag.yaml +63 -0
  26. controlzero-1.0.0/controlzero/client.py +398 -0
  27. controlzero-1.0.0/controlzero/enrollment.py +493 -0
  28. controlzero-1.0.0/controlzero/errors.py +60 -0
  29. controlzero-1.0.0/controlzero/policy_loader.py +245 -0
  30. controlzero-1.0.0/controlzero/tamper.py +337 -0
  31. controlzero-1.0.0/examples/hello_world.py +20 -0
  32. controlzero-1.0.0/pyproject.toml +65 -0
  33. controlzero-1.0.0/tests/conftest.py +30 -0
  34. controlzero-1.0.0/tests/test_audit_remote.py +532 -0
  35. controlzero-1.0.0/tests/test_audit_sink_isolation.py +67 -0
  36. controlzero-1.0.0/tests/test_cli_hook.py +296 -0
  37. controlzero-1.0.0/tests/test_cli_init.py +43 -0
  38. controlzero-1.0.0/tests/test_cli_init_templates.py +24 -0
  39. controlzero-1.0.0/tests/test_cli_tail.py +33 -0
  40. controlzero-1.0.0/tests/test_cli_test.py +59 -0
  41. controlzero-1.0.0/tests/test_cli_validate.py +37 -0
  42. controlzero-1.0.0/tests/test_dlp_scanner.py +1063 -0
  43. controlzero-1.0.0/tests/test_enrollment.py +392 -0
  44. controlzero-1.0.0/tests/test_fail_closed_eval.py +19 -0
  45. controlzero-1.0.0/tests/test_glob_matching.py +118 -0
  46. controlzero-1.0.0/tests/test_hybrid_mode_strict.py +53 -0
  47. controlzero-1.0.0/tests/test_hybrid_mode_warn.py +30 -0
  48. controlzero-1.0.0/tests/test_install_hooks.py +1175 -0
  49. controlzero-1.0.0/tests/test_local_mode_dict.py +98 -0
  50. controlzero-1.0.0/tests/test_local_mode_file_json.py +33 -0
  51. controlzero-1.0.0/tests/test_local_mode_file_yaml.py +62 -0
  52. controlzero-1.0.0/tests/test_log_fallback_stderr.py +34 -0
  53. controlzero-1.0.0/tests/test_log_options_ignored_hosted.py +35 -0
  54. controlzero-1.0.0/tests/test_log_rotation.py +66 -0
  55. controlzero-1.0.0/tests/test_no_policy_no_key.py +28 -0
  56. controlzero-1.0.0/tests/test_package_rename_shim.py +46 -0
  57. controlzero-1.0.0/tests/test_policy_freshness.py +278 -0
  58. controlzero-1.0.0/tests/test_tamper.py +204 -0
  59. controlzero-1.0.0/tests/test_tamper_hook.py +309 -0
@@ -0,0 +1,220 @@
1
+ # Worktrees
2
+ .worktrees/
3
+
4
+ # Dependencies
5
+ node_modules/
6
+ vendor/
7
+
8
+ # Build outputs
9
+ dist/
10
+ build/
11
+ .next/
12
+ out/
13
+ *.egg-info/
14
+ # Go binaries
15
+ apps/control-zero-platform/backend/server
16
+
17
+ # Test & Coverage
18
+ coverage/
19
+ htmlcov/
20
+ .coverage
21
+ *.lcov
22
+ .pytest_cache/
23
+ .vitest/
24
+ test-results/
25
+ playwright-report/
26
+ .playwright/
27
+ __pycache__/
28
+ *.pyc
29
+ *.pyo
30
+
31
+ # Environment and secrets (deny-all, allow explicitly)
32
+ .env*
33
+ production-secrets*
34
+ vault-backup.key
35
+ *.pem
36
+ *.key
37
+ *.p12
38
+ *.pfx
39
+ id_rsa
40
+ id_ed25519
41
+ *.keystore
42
+ # Firebase credentials and config (contains API keys / service account)
43
+ firebase.js
44
+ firebase.json
45
+ firebase-service-account*.json
46
+ *-firebase-adminsdk-*.json
47
+ firebase-adminsdk-*.json
48
+ serviceAccountKey.json
49
+ cz-service-account.json
50
+ firebase-credentials.json/
51
+ google-services.json
52
+ GoogleService-Info.plist
53
+ !*.pub
54
+ !.env.example
55
+ !.env.local.example
56
+ !.env.production.template
57
+ !.env.production.example
58
+ !.env.test
59
+
60
+ # Explicitly block files that contain or may contain real credentials (override allowlist above)
61
+ .env.dev
62
+ .env.production
63
+ .env.production.complete
64
+ .env.production.local
65
+ .env.local
66
+ .env.*.local
67
+ *.env.real
68
+ *.env.secret
69
+ .env.vercel
70
+
71
+ # IDE & Editors
72
+ .idea/
73
+ .vscode/
74
+ *.swp
75
+ *.swo
76
+ *.sublime-workspace
77
+ *.sublime-project
78
+
79
+ # OS files
80
+ .DS_Store
81
+ Thumbs.db
82
+ *.log
83
+
84
+ # Go
85
+ *.exe
86
+ *.exe~
87
+ *.dll
88
+ *.so
89
+ *.dylib
90
+
91
+ # Docker
92
+ docker-compose.override.yml
93
+ .docker/
94
+
95
+ # Production logs and certificates
96
+ logs/
97
+ letsencrypt/
98
+ *.log
99
+
100
+ # DLP test reports (generated, not committed)
101
+ reports/
102
+
103
+ # MkDocs
104
+ site/
105
+
106
+ # Turbo (if adopted)
107
+ .turbo/
108
+
109
+ # Changeset
110
+ .changeset/*.md
111
+ !.changeset/config.json
112
+ !.changeset/README.md
113
+
114
+ # Vercel
115
+ .vercel/
116
+
117
+ # Rust
118
+ target/
119
+ Cargo.lock
120
+ *.rlib
121
+
122
+ # Python virtual environments
123
+ venv/
124
+ .venv/
125
+ *.egg-info/
126
+
127
+ # Gateway
128
+ apps/control-zero-gateway/.venv/
129
+ apps/control-zero-gateway/__pycache__/
130
+
131
+ # Selenium test outputs
132
+ tests/selenium/screenshots/
133
+ tests/selenium/report.html
134
+
135
+ # Miscellaneous
136
+ *.bak
137
+ *.tmp
138
+ *.temp
139
+ .cache/
140
+ .vercel
141
+ # Internal documentation (sensitive -- do not track)
142
+ docs/internal/
143
+
144
+ # Playwright MCP
145
+ .playwright-mcp/
146
+
147
+ # Session artifacts (prevent future accumulation)
148
+ *_SUMMARY.md
149
+ *_STATUS.md
150
+ *_COMPLETE.md
151
+
152
+ # E2E test screenshots
153
+ e2e-*.png
154
+ cz-*.png
155
+ .superpowers/
156
+
157
+ # AI tooling directories
158
+ .gemini/
159
+ .claude/launch.json
160
+
161
+ # Docusaurus build cache (should not be tracked)
162
+ docs-site/.docusaurus/
163
+
164
+ # Test/governance tester scripts (generated during testing sessions)
165
+ *_tester.py
166
+ verify_and_screenshot.js
167
+
168
+ # HTML reports generated during testing sessions
169
+ *_AUDIT.html
170
+ *_REPORT.html
171
+ *_ANALYSIS.html
172
+ e2e-report.html
173
+ sit-uat-report.html
174
+ UAT_COMPREHENSIVE_REPORT.html
175
+ uat-screenshots/
176
+
177
+ # Offensive summary reports
178
+ SUMMARY_OFFENSIVE_*.md
179
+ .gstack/
180
+
181
+ # Deployment docs (contain server-specific credentials)
182
+ docs/deployment/
183
+ docs/SSH_RECOVERY_GUIDE.md
184
+ docs/HETZNER_OS_INSTALLATION.md
185
+ docs/BACKUP_RECOVERY.md
186
+ docs/VERCEL_SETUP_WEBAPPS.md
187
+ scripts/fix-ssh-config.sh
188
+ scripts/hetzner-post-install.sh
189
+ docs/knowledge-base/
190
+ docs/superpowers/
191
+ scripts/doppler/doppler-env.values.sh
192
+
193
+ # Air-gap build artifacts (generated tarballs and package directories)
194
+ cz-air-gap-*/
195
+ cz-air-gap-*.tar.gz
196
+ cz-support-*.tar.gz
197
+
198
+ # SSL Proxy -- customer CA certs and generated certs (never track secrets)
199
+ services/ssl-proxy/certs/
200
+
201
+ # UAT screenshot artifacts
202
+ uat-*.png
203
+
204
+ # Stray HTML reports in docs/. These are large exported artifacts
205
+ # (SIT/UAT reports, factsheet, launch readiness) that accumulate
206
+ # untracked and risk being swept up by `git add .`. The
207
+ # sit-uat-report-2026-03-22.html in particular is 128MB and would
208
+ # explode the repo. Real docs go under docs/knowledge-base/ or
209
+ # docs/designs/ instead.
210
+ docs/sit-uat-report-*.html
211
+ docs/launch-readiness-report-*.html
212
+ docs/control-zero-factsheet.html
213
+ docs/control-zero-review.html
214
+
215
+ # Reference screenshots (keep local, not in repo)
216
+ agentdefenders-full.png
217
+ cz-revamp-live.png
218
+
219
+ # Agent worktrees (created by Claude Code during parallel work)
220
+ .claude/worktrees/
@@ -0,0 +1,24 @@
1
+ # Test image for the controlzero Python SDK.
2
+ # Builds the package, installs it, runs the test suite.
3
+ FROM python:3.12-slim
4
+
5
+ WORKDIR /app
6
+
7
+ # Install build deps
8
+ RUN pip install --no-cache-dir hatchling pytest pytest-asyncio pytest-cov
9
+
10
+ # Copy the package
11
+ COPY pyproject.toml README.md LICENSE /app/
12
+ COPY controlzero /app/controlzero
13
+ COPY tests /app/tests
14
+ COPY examples /app/examples
15
+
16
+ # Install the package + dev extras
17
+ RUN pip install --no-cache-dir -e ".[dev]"
18
+
19
+ # Smoke test: import and run the example
20
+ RUN python -c "from controlzero import Client, __version__; print(f'controlzero {__version__} installed')"
21
+ RUN python examples/hello_world.py
22
+
23
+ # Run the full test suite by default
24
+ CMD ["pytest", "-v", "--tb=short", "tests/"]
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 Control Zero, Inc.
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -0,0 +1,232 @@
1
+ Metadata-Version: 2.4
2
+ Name: controlzero
3
+ Version: 1.0.0
4
+ Summary: AI agent governance: policies, audit, and observability for tool calls. Works locally with no signup.
5
+ Project-URL: Homepage, https://controlzero.ai
6
+ Project-URL: Documentation, https://docs.controlzero.ai
7
+ Project-URL: Repository, https://github.com/controlzero/controlzero
8
+ Project-URL: Examples, https://docs.controlzero.ai/sdk/integrations
9
+ Author-email: Control Zero <hello@controlzero.ai>
10
+ License: Apache-2.0
11
+ License-File: LICENSE
12
+ Keywords: agents,ai,audit,governance,guardrails,llm,mcp,policy
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Security
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: click>=8.1.0
26
+ Requires-Dist: loguru>=0.7.0
27
+ Requires-Dist: pydantic>=2.0.0
28
+ Requires-Dist: pyyaml>=6.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
32
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
33
+ Requires-Dist: pyyaml>=6.0; extra == 'dev'
34
+ Provides-Extra: hosted
35
+ Requires-Dist: cryptography>=41.0.0; extra == 'hosted'
36
+ Requires-Dist: httpx>=0.25.0; extra == 'hosted'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # control-zero
40
+
41
+ AI agent governance for Python. Policies, audit, and observability for tool calls.
42
+ Works locally with no signup.
43
+
44
+ > **v1.0.0 is a complete rewrite.** If you depend on `control-zero<1.0.0`
45
+ > (the hosted-mode SDK), pin your requirement: `control-zero<1.0.0` to stay on
46
+ > the legacy v0.3.x. The new v1.0.0+ is a local-first SDK with a different
47
+ > API surface; see the [migration guide](https://docs.controlzero.ai/sdk/migrate-v1)
48
+ > for details.
49
+
50
+ ## Hello World
51
+
52
+ ```python
53
+ from controlzero import Client
54
+
55
+ cz = Client(policy={
56
+ "rules": [
57
+ {"deny": "delete_*", "reason": "Hello World: deletes are blocked"},
58
+ {"allow": "*", "reason": "Hello World: everything else is fine"},
59
+ ]
60
+ })
61
+
62
+ print(cz.guard("delete_file", {"path": "/tmp/foo"}).decision) # "deny"
63
+ print(cz.guard("read_file", {"path": "/tmp/foo"}).decision) # "allow"
64
+ ```
65
+
66
+ 11 lines. No API key. No signup. Run it.
67
+
68
+ ## Install
69
+
70
+ ```bash
71
+ pip install control-zero
72
+ ```
73
+
74
+ ## Why
75
+
76
+ Your AI agents call tools. Some of those tools should never be called by an
77
+ agent without a human in the loop. `controlzero` is the policy layer between
78
+ the model's output and the tool execution. Decisions are fail-closed by default.
79
+
80
+ You can use it offline with a local YAML file or Python dict. When you want to
81
+ share policies across a team or get a hosted audit dashboard, sign up at
82
+ [controlzero.ai](https://controlzero.ai) and set `CONTROLZERO_API_KEY`.
83
+
84
+ ## Quickstart with the CLI
85
+
86
+ ```bash
87
+ # 1. Generate a starter policy file with examples and comments
88
+ controlzero init
89
+
90
+ # 2. Edit controlzero.yaml in your editor
91
+
92
+ # 3. Validate it
93
+ controlzero validate
94
+
95
+ # 4. Test a tool call against the policy
96
+ controlzero test delete_file
97
+ ```
98
+
99
+ The generated `controlzero.yaml` is the tutorial. It ships with annotated
100
+ rules covering the common patterns: allow lists, deny lists, wildcards, and
101
+ the catch-all.
102
+
103
+ Templates available:
104
+
105
+ - `controlzero init` — Hello World template (default)
106
+ - `controlzero init -t rag` — RAG agent template (block exfiltration)
107
+ - `controlzero init -t mcp` — MCP server template
108
+ - `controlzero init -t cost-cap` — model allow-listing and cost guards
109
+
110
+ ## Loading a policy
111
+
112
+ Three ways:
113
+
114
+ ```python
115
+ from controlzero import Client
116
+
117
+ # From a Python dict
118
+ cz = Client(policy={
119
+ "rules": [
120
+ {"deny": "delete_*"},
121
+ {"allow": "read_*"},
122
+ ]
123
+ })
124
+
125
+ # From a YAML file
126
+ cz = Client(policy_file="./controlzero.yaml")
127
+
128
+ # From an environment variable
129
+ # (set CONTROLZERO_POLICY_FILE=./controlzero.yaml)
130
+ cz = Client()
131
+ ```
132
+
133
+ If `./controlzero.yaml` exists in the current directory, it is picked up
134
+ automatically. No environment variable needed.
135
+
136
+ ## Policy schema
137
+
138
+ ```yaml
139
+ version: '1'
140
+ rules:
141
+ # Block any tool whose name starts with "delete_"
142
+ - deny: 'delete_*'
143
+ reason: 'Deletes need human approval'
144
+
145
+ # Allow specific known-good tools
146
+ - allow: 'search'
147
+ - allow: 'read_*'
148
+
149
+ # tool:method syntax
150
+ - allow: 'github:list_*'
151
+ - deny: 'github:delete_repo'
152
+
153
+ # Catch-all
154
+ - deny: '*'
155
+ reason: 'Default deny'
156
+ ```
157
+
158
+ Rules are evaluated top to bottom. The first match wins. If no rule matches,
159
+ the call is denied (fail-closed).
160
+
161
+ ## Local audit log
162
+
163
+ When running without an API key, every decision is written to `./controlzero.log`
164
+ with daily rotation and 30-day retention. Tail it:
165
+
166
+ ```bash
167
+ controlzero tail
168
+ ```
169
+
170
+ Configure rotation via the client:
171
+
172
+ ```python
173
+ cz = Client(
174
+ policy_file="./controlzero.yaml",
175
+ log_path="./logs/controlzero.log",
176
+ log_rotation="10 MB", # rotate at 10 MB, or "daily", or "1 hour"
177
+ log_retention="30 days",
178
+ log_compression="gz", # gzip rotated files
179
+ log_format="json", # or "pretty"
180
+ )
181
+ ```
182
+
183
+ When `CONTROLZERO_API_KEY` is set, audit ships to the remote dashboard and
184
+ these `log_*` options are ignored with a warning.
185
+
186
+ ## Hybrid mode
187
+
188
+ If you set both an API key AND pass a local policy, the local policy
189
+ **overrides** the dashboard policy and you get a loud WARN log on init:
190
+
191
+ ```
192
+ WARNING: controlzero: manual policy override detected. ...
193
+ ```
194
+
195
+ This is intentional: it makes accidental prod bypass impossible to miss.
196
+ For prod environments, opt into strict mode to raise instead:
197
+
198
+ ```python
199
+ cz = Client(api_key="cz_live_...", policy=local_policy, strict_hosted=True)
200
+ # RuntimeError: manual policy override detected ...
201
+ ```
202
+
203
+ ## Framework examples
204
+
205
+ Full integration guides at [docs.controlzero.ai/sdk/integrations](https://docs.controlzero.ai/sdk/integrations):
206
+
207
+ - LangChain
208
+ - LangGraph
209
+ - CrewAI
210
+ - OpenAI Agents SDK
211
+ - Anthropic tool use
212
+ - Pydantic AI
213
+ - AutoGen
214
+ - MCP servers
215
+ - Raw HTTP / no framework
216
+
217
+ ## Hosted mode
218
+
219
+ When you want a dashboard, audit search, team policies, and approval workflows,
220
+ sign up at [controlzero.ai](https://controlzero.ai) and set the API key:
221
+
222
+ ```python
223
+ import os
224
+ os.environ["CONTROLZERO_API_KEY"] = "cz_live_..."
225
+
226
+ from controlzero import Client
227
+ cz = Client() # picks up the API key from env, audit ships remote
228
+ ```
229
+
230
+ ## License
231
+
232
+ Apache 2.0
@@ -0,0 +1,194 @@
1
+ # control-zero
2
+
3
+ AI agent governance for Python. Policies, audit, and observability for tool calls.
4
+ Works locally with no signup.
5
+
6
+ > **v1.0.0 is a complete rewrite.** If you depend on `control-zero<1.0.0`
7
+ > (the hosted-mode SDK), pin your requirement: `control-zero<1.0.0` to stay on
8
+ > the legacy v0.3.x. The new v1.0.0+ is a local-first SDK with a different
9
+ > API surface; see the [migration guide](https://docs.controlzero.ai/sdk/migrate-v1)
10
+ > for details.
11
+
12
+ ## Hello World
13
+
14
+ ```python
15
+ from controlzero import Client
16
+
17
+ cz = Client(policy={
18
+ "rules": [
19
+ {"deny": "delete_*", "reason": "Hello World: deletes are blocked"},
20
+ {"allow": "*", "reason": "Hello World: everything else is fine"},
21
+ ]
22
+ })
23
+
24
+ print(cz.guard("delete_file", {"path": "/tmp/foo"}).decision) # "deny"
25
+ print(cz.guard("read_file", {"path": "/tmp/foo"}).decision) # "allow"
26
+ ```
27
+
28
+ 11 lines. No API key. No signup. Run it.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install control-zero
34
+ ```
35
+
36
+ ## Why
37
+
38
+ Your AI agents call tools. Some of those tools should never be called by an
39
+ agent without a human in the loop. `controlzero` is the policy layer between
40
+ the model's output and the tool execution. Decisions are fail-closed by default.
41
+
42
+ You can use it offline with a local YAML file or Python dict. When you want to
43
+ share policies across a team or get a hosted audit dashboard, sign up at
44
+ [controlzero.ai](https://controlzero.ai) and set `CONTROLZERO_API_KEY`.
45
+
46
+ ## Quickstart with the CLI
47
+
48
+ ```bash
49
+ # 1. Generate a starter policy file with examples and comments
50
+ controlzero init
51
+
52
+ # 2. Edit controlzero.yaml in your editor
53
+
54
+ # 3. Validate it
55
+ controlzero validate
56
+
57
+ # 4. Test a tool call against the policy
58
+ controlzero test delete_file
59
+ ```
60
+
61
+ The generated `controlzero.yaml` is the tutorial. It ships with annotated
62
+ rules covering the common patterns: allow lists, deny lists, wildcards, and
63
+ the catch-all.
64
+
65
+ Templates available:
66
+
67
+ - `controlzero init` — Hello World template (default)
68
+ - `controlzero init -t rag` — RAG agent template (block exfiltration)
69
+ - `controlzero init -t mcp` — MCP server template
70
+ - `controlzero init -t cost-cap` — model allow-listing and cost guards
71
+
72
+ ## Loading a policy
73
+
74
+ Three ways:
75
+
76
+ ```python
77
+ from controlzero import Client
78
+
79
+ # From a Python dict
80
+ cz = Client(policy={
81
+ "rules": [
82
+ {"deny": "delete_*"},
83
+ {"allow": "read_*"},
84
+ ]
85
+ })
86
+
87
+ # From a YAML file
88
+ cz = Client(policy_file="./controlzero.yaml")
89
+
90
+ # From an environment variable
91
+ # (set CONTROLZERO_POLICY_FILE=./controlzero.yaml)
92
+ cz = Client()
93
+ ```
94
+
95
+ If `./controlzero.yaml` exists in the current directory, it is picked up
96
+ automatically. No environment variable needed.
97
+
98
+ ## Policy schema
99
+
100
+ ```yaml
101
+ version: '1'
102
+ rules:
103
+ # Block any tool whose name starts with "delete_"
104
+ - deny: 'delete_*'
105
+ reason: 'Deletes need human approval'
106
+
107
+ # Allow specific known-good tools
108
+ - allow: 'search'
109
+ - allow: 'read_*'
110
+
111
+ # tool:method syntax
112
+ - allow: 'github:list_*'
113
+ - deny: 'github:delete_repo'
114
+
115
+ # Catch-all
116
+ - deny: '*'
117
+ reason: 'Default deny'
118
+ ```
119
+
120
+ Rules are evaluated top to bottom. The first match wins. If no rule matches,
121
+ the call is denied (fail-closed).
122
+
123
+ ## Local audit log
124
+
125
+ When running without an API key, every decision is written to `./controlzero.log`
126
+ with daily rotation and 30-day retention. Tail it:
127
+
128
+ ```bash
129
+ controlzero tail
130
+ ```
131
+
132
+ Configure rotation via the client:
133
+
134
+ ```python
135
+ cz = Client(
136
+ policy_file="./controlzero.yaml",
137
+ log_path="./logs/controlzero.log",
138
+ log_rotation="10 MB", # rotate at 10 MB, or "daily", or "1 hour"
139
+ log_retention="30 days",
140
+ log_compression="gz", # gzip rotated files
141
+ log_format="json", # or "pretty"
142
+ )
143
+ ```
144
+
145
+ When `CONTROLZERO_API_KEY` is set, audit ships to the remote dashboard and
146
+ these `log_*` options are ignored with a warning.
147
+
148
+ ## Hybrid mode
149
+
150
+ If you set both an API key AND pass a local policy, the local policy
151
+ **overrides** the dashboard policy and you get a loud WARN log on init:
152
+
153
+ ```
154
+ WARNING: controlzero: manual policy override detected. ...
155
+ ```
156
+
157
+ This is intentional: it makes accidental prod bypass impossible to miss.
158
+ For prod environments, opt into strict mode to raise instead:
159
+
160
+ ```python
161
+ cz = Client(api_key="cz_live_...", policy=local_policy, strict_hosted=True)
162
+ # RuntimeError: manual policy override detected ...
163
+ ```
164
+
165
+ ## Framework examples
166
+
167
+ Full integration guides at [docs.controlzero.ai/sdk/integrations](https://docs.controlzero.ai/sdk/integrations):
168
+
169
+ - LangChain
170
+ - LangGraph
171
+ - CrewAI
172
+ - OpenAI Agents SDK
173
+ - Anthropic tool use
174
+ - Pydantic AI
175
+ - AutoGen
176
+ - MCP servers
177
+ - Raw HTTP / no framework
178
+
179
+ ## Hosted mode
180
+
181
+ When you want a dashboard, audit search, team policies, and approval workflows,
182
+ sign up at [controlzero.ai](https://controlzero.ai) and set the API key:
183
+
184
+ ```python
185
+ import os
186
+ os.environ["CONTROLZERO_API_KEY"] = "cz_live_..."
187
+
188
+ from controlzero import Client
189
+ cz = Client() # picks up the API key from env, audit ships remote
190
+ ```
191
+
192
+ ## License
193
+
194
+ Apache 2.0