tenuo-claude-code 0.2.1__tar.gz → 0.2.2__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.
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/.gitignore +1 -1
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/PKG-INFO +114 -61
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/README.md +113 -60
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/README.md +42 -14
- tenuo_claude_code-0.2.2/demo/docs/README.md +21 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/DETAILS.md +44 -17
- tenuo_claude_code-0.2.2/docs/TROUBLESHOOTING.md +221 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/README.md +1 -1
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/pyproject.toml +1 -1
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/admin.py +29 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/authorizer_runtime.py +13 -1
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/cli.py +205 -23
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/README.md +2 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.advanced.example +2 -2
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_admin.py +87 -0
- tenuo_claude_code-0.2.2/tests/test_cloud_bindings.py +331 -0
- tenuo_claude_code-0.2.2/tests/test_scaffold.py +244 -0
- tenuo_claude_code-0.2.1/tests/test_scaffold.py +0 -133
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/CONTRIBUTING.md +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/LICENSE +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/.claude/agents/researcher.md +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/.mcp.json +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/fake-secrets.env +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/ops_server.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/sandbox/incident-report.md +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/sandbox/notes.txt +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/tenuo.yaml +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/tenuo_demo.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/cloud-audit-stream.png +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/cloud-receipt-approval-detail.png +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/tenuo_claude_code_architecture.png +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/tenuo_claude_code_architecture.svg +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/README.md +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/audit-rollout.yaml +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/enforce-with-mcp.yaml +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/read-only-research.yaml +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/__init__.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/data/harness_tools.yaml +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/paths.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/templates/tenuo.yaml.example +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/verify.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/admin.env.example +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/cloud.env.example +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.cloud.example +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.example +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/conftest.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_approvals.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_authorize_call.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_authorizer_runtime.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_check.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_constraints.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_permissions.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_routing.py +0 -0
- {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_subagents.py +0 -0
|
@@ -24,7 +24,7 @@ tenuo.advanced.yaml
|
|
|
24
24
|
demo/sandbox/out.txt
|
|
25
25
|
demo/sandbox/_probe.txt
|
|
26
26
|
|
|
27
|
-
# Local-only presentation notes (
|
|
27
|
+
# Local-only presentation notes (gitignored — keep your own copy; see demo/docs/README.md)
|
|
28
28
|
demo/docs/PRESENTATION.md
|
|
29
29
|
|
|
30
30
|
# OS / editor
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tenuo-claude-code
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Tenuo governance for Claude Code — warrants, hooks, MCP proxy, and Cloud lifecycle
|
|
5
5
|
Project-URL: Homepage, https://tenuo.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/tenuo-ai/claude-governance
|
|
@@ -51,9 +51,21 @@ mkdir my-project && cd my-project
|
|
|
51
51
|
tenuo-claude bootstrap
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
When `verify` passes, open Claude Code in this directory.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
**Native authorizer (no Docker):**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
tenuo-claude install-authorizer
|
|
60
|
+
tenuo-claude bootstrap
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If Docker is not installed, `bootstrap` uses the native authorizer automatically. If Docker is installed and you want native anyway:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
export TENUO_AUTHORIZER_BACKEND=native
|
|
67
|
+
tenuo-claude bootstrap
|
|
68
|
+
```
|
|
57
69
|
|
|
58
70
|
### Where to go next
|
|
59
71
|
|
|
@@ -61,10 +73,11 @@ No Docker, or prefer native? Run `tenuo-claude install-authorizer` once, then `b
|
|
|
61
73
|
|-----------------|------------|
|
|
62
74
|
| Day-to-day commands, ports, CLI reference | [Use the tool](#use-the-tool-pypi) |
|
|
63
75
|
| Edit or replace the example policy | [Policy](#policy-tenuoyaml) |
|
|
64
|
-
| Clone
|
|
76
|
+
| Clone the repo or run the sample project | [Build from source](#build-from-source) |
|
|
65
77
|
| Connect to Tenuo Cloud | [Cloud mode](#cloud-mode) |
|
|
66
78
|
| Review security posture | [Security](#security) |
|
|
67
79
|
| Plan org-wide rollout | [Talk to us](https://tenuo.ai/early-access.html) |
|
|
80
|
+
| Something failed during setup | [Troubleshooting (Q&A)](docs/TROUBLESHOOTING.md) |
|
|
68
81
|
| Implementation depth | [docs/DETAILS.md](docs/DETAILS.md) |
|
|
69
82
|
|
|
70
83
|
## How it works
|
|
@@ -85,41 +98,42 @@ tenuo.yaml → init/up → warrant + authorizer + hooks + MCP proxy
|
|
|
85
98
|
|
|
86
99
|
**Native tools** (Read, Bash, WebFetch, and the rest) go through a PreToolUse hook. **MCP tools** go through a proxy in place of the downstream server. At `init`, Tenuo mints a **session warrant**; each call must prove it holds that warrant before the authorizer allows the action.
|
|
87
100
|
|
|
88
|
-
Both paths use the same warrant and authorizer.
|
|
89
|
-
|
|
90
101
|
More: [docs/DETAILS.md](docs/DETAILS.md)
|
|
91
102
|
|
|
92
103
|
## Prerequisites
|
|
93
104
|
|
|
94
105
|
- Python ≥ 3.10
|
|
95
|
-
- **Authorizer runtime** (
|
|
96
|
-
- **Docker
|
|
97
|
-
- **Native (no Docker)
|
|
106
|
+
- **Authorizer runtime** (use one):
|
|
107
|
+
- **Docker** (default when the daemon is running): [Docker Desktop](https://www.docker.com/products/docker-desktop/) or your engine, then `tenuo-claude up`. Uses the pinned `tenuo/authorizer` image.
|
|
108
|
+
- **Native** (no Docker): run `tenuo-claude install-authorizer`, then `tenuo-claude up --native`. On first run, add `--install`. Override the binary with `TENUO_AUTHORIZER_BIN`. Set `TENUO_AUTHORIZER_SKIP_VERSION=1` only for local dev builds.
|
|
109
|
+
- To force native while Docker is installed, set `TENUO_AUTHORIZER_BACKEND=native` before `bootstrap` or `up`.
|
|
110
|
+
- [Claude Code](https://code.claude.com/docs) — Tenuo wires PreToolUse hooks and MCP proxy at `init`.
|
|
98
111
|
|
|
99
|
-
|
|
100
|
-
- [Claude Code](https://code.claude.com/docs) for live agent use. Optional: `verify` works without it.
|
|
112
|
+
**Local mode:** no Tenuo Cloud account. Suitable for single-project evaluation.
|
|
101
113
|
|
|
102
|
-
**
|
|
103
|
-
|
|
104
|
-
**Cloud mode:** [cloud.tenuo.ai](https://cloud.tenuo.ai) tenant for tenant-root warrants, central audit, fleet revocation, and org-wide rollout ([Cloud mode](#cloud-mode)).
|
|
114
|
+
**Cloud mode:** requires a [cloud.tenuo.ai](https://cloud.tenuo.ai) tenant for tenant-root warrants, central audit, fleet revocation, and org-wide rollout ([Cloud mode](#cloud-mode)).
|
|
105
115
|
|
|
106
116
|
---
|
|
107
117
|
|
|
108
118
|
## Use the tool (PyPI)
|
|
109
119
|
|
|
110
|
-
After [Try it](#try-it), you have an example `tenuo.yaml`, a running authorizer, and passing `verify`.
|
|
120
|
+
After [Try it](#try-it), you have an example `tenuo.yaml`, a running authorizer, and passing `verify`.
|
|
111
121
|
|
|
112
122
|
### Day to day
|
|
113
123
|
|
|
114
124
|
| When | Command |
|
|
115
125
|
|------|---------|
|
|
116
|
-
| Start work | `tenuo-claude
|
|
117
|
-
|
|
|
118
|
-
|
|
|
126
|
+
| Start work (Cloud) | `tenuo-claude check && tenuo-claude up` |
|
|
127
|
+
| Start work (local only) | `tenuo-claude up` or `tenuo-claude up --native` |
|
|
128
|
+
| `check` reports cloud bindings failure | `tenuo-admin setup`, then `check && up` again |
|
|
129
|
+
| You edited `tenuo.yaml` | `tenuo-claude refresh` (local); Cloud capability changes also need `tenuo-admin setup` |
|
|
130
|
+
| Diagnose setup | `tenuo-claude check` |
|
|
119
131
|
| See decisions | `tenuo-claude audit` |
|
|
120
132
|
| Stop authorizer | `tenuo-claude down` |
|
|
121
133
|
|
|
122
|
-
|
|
134
|
+
See [Troubleshooting (Q&A)](docs/TROUBLESHOOTING.md) for common errors.
|
|
135
|
+
|
|
136
|
+
If you always use the native authorizer without Docker, set `TENUO_AUTHORIZER_BACKEND=native` in your shell so plain `up` selects the host binary.
|
|
123
137
|
|
|
124
138
|
### Port conflicts
|
|
125
139
|
|
|
@@ -146,13 +160,15 @@ tenuo-claude up
|
|
|
146
160
|
tenuo-claude verify
|
|
147
161
|
```
|
|
148
162
|
|
|
149
|
-
Use `--native` when not
|
|
163
|
+
Use `--native` when Docker is not available. On the first native run, add `--install`. Alternatively, run `tenuo-claude onboard --local` for an interactive setup.
|
|
150
164
|
|
|
151
165
|
### Reference demo
|
|
152
166
|
|
|
153
167
|
Sample policy, MCP stub, and scripted tour in [demo/](demo/). The shipped `demo/tenuo.yaml` is richer than the bootstrap example; Cloud and approval overlays may already be present.
|
|
154
168
|
|
|
155
|
-
|
|
169
|
+
From repo root: `uv venv && uv sync && source .venv/bin/activate`, then:
|
|
170
|
+
|
|
171
|
+
**First time, local only** (no `.state/cloud.env`):
|
|
156
172
|
|
|
157
173
|
```bash
|
|
158
174
|
cd demo
|
|
@@ -160,18 +176,37 @@ tenuo-claude bootstrap
|
|
|
160
176
|
tenuo-claude demo
|
|
161
177
|
```
|
|
162
178
|
|
|
163
|
-
**
|
|
179
|
+
**First time, Cloud** (recommended for the reference demo with receipts):
|
|
164
180
|
|
|
165
181
|
```bash
|
|
166
182
|
cd demo
|
|
167
|
-
tenuo-claude
|
|
183
|
+
tenuo-claude bootstrap --cloud
|
|
184
|
+
# or: tenuo-claude onboard --cloud
|
|
185
|
+
tenuo-claude demo
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Paste Quick Connect (**Authorizer Only**) into `.state/cloud.env` and tenant-admin
|
|
189
|
+
key into `~/.tenuo/admin.env` when prompted. See [Cloud mode](#cloud-mode).
|
|
190
|
+
|
|
191
|
+
**Already Cloud-configured** (`.state/cloud.env` or `tenuo.cloud.yaml` present):
|
|
192
|
+
|
|
193
|
+
Do **not** run plain `bootstrap` — it switches to local mode and moves Cloud files
|
|
194
|
+
aside. Use:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
cd demo
|
|
198
|
+
tenuo-claude check && tenuo-claude up
|
|
168
199
|
tenuo-claude verify
|
|
169
200
|
tenuo-claude demo
|
|
170
201
|
```
|
|
171
202
|
|
|
203
|
+
If `check` fails on **cloud bindings** → `tenuo-admin setup`, then retry.
|
|
204
|
+
|
|
172
205
|
For human approval: [Cloud mode § Human approval](#human-approval-cloud), then `tenuo-claude demo --advanced --live-approval`.
|
|
173
206
|
|
|
174
|
-
If
|
|
207
|
+
If plain `bootstrap` was run on a Cloud-configured project, restore `.state/cloud.env`
|
|
208
|
+
and policy overlays from backup, then `tenuo-admin setup`. See
|
|
209
|
+
[Troubleshooting](docs/TROUBLESHOOTING.md).
|
|
175
210
|
|
|
176
211
|
From a git checkout, see [Build from source](#build-from-source).
|
|
177
212
|
|
|
@@ -184,21 +219,21 @@ From a git checkout, see [Build from source](#build-from-source).
|
|
|
184
219
|
| `up` / `down` | Start / stop authorizer. `up` flags: `--native`, `--docker`, `--install` (native, first run) |
|
|
185
220
|
| `install-authorizer` | Install `tenuo-authorizer` to `~/.tenuo/bin` (no manual `cargo`) |
|
|
186
221
|
| `refresh` | Re-apply `tenuo.yaml` (restarts authorizer if up) |
|
|
187
|
-
| `check` | Preflight: deps, credentials, wiring drift |
|
|
188
|
-
| `verify [--deep]` | Policy self-test against the authorizer |
|
|
222
|
+
| `check` | Preflight: deps, credentials, wiring drift, Cloud binding probe |
|
|
223
|
+
| `verify [--deep]` | Policy self-test against the authorizer (no agent session required) |
|
|
189
224
|
| `status` | Warrant, posture, Cloud summary |
|
|
190
225
|
| `onboard` | Interactive local or Cloud setup wizard |
|
|
191
226
|
| `bench [--json]` | Per-tool-call overhead |
|
|
192
227
|
| `audit [--tail N]` | Receipt trail |
|
|
193
228
|
| `revoke` | Revoke session warrant |
|
|
194
229
|
|
|
195
|
-
See also: [Policy](#policy-tenuoyaml) · [Cloud mode](#cloud-mode) · [docs/DETAILS.md](docs/DETAILS.md)
|
|
230
|
+
See also: [Policy](#policy-tenuoyaml) · [Cloud mode](#cloud-mode) · [Troubleshooting](docs/TROUBLESHOOTING.md) · [docs/DETAILS.md](docs/DETAILS.md)
|
|
196
231
|
|
|
197
232
|
---
|
|
198
233
|
|
|
199
234
|
## Build from source
|
|
200
235
|
|
|
201
|
-
For
|
|
236
|
+
For local development, the reference demo from git, or `./bin/tenuo-claude` instead of a PyPI install.
|
|
202
237
|
|
|
203
238
|
```bash
|
|
204
239
|
git clone https://github.com/tenuo-ai/claude-governance.git
|
|
@@ -222,13 +257,14 @@ Run commands via the repo launcher or editable install:
|
|
|
222
257
|
|
|
223
258
|
```bash
|
|
224
259
|
cd demo
|
|
225
|
-
tenuo-claude up
|
|
260
|
+
tenuo-claude check && tenuo-claude up # Cloud; see Reference demo if check fails
|
|
226
261
|
tenuo-claude demo
|
|
227
262
|
```
|
|
228
263
|
|
|
229
|
-
First local-only run: `tenuo-claude bootstrap` instead
|
|
264
|
+
First local-only run (no `.state/cloud.env`): use `tenuo-claude bootstrap` instead.
|
|
265
|
+
First Cloud run: `tenuo-claude bootstrap --cloud` or `onboard --cloud`.
|
|
230
266
|
|
|
231
|
-
Use `tenuo-claude up --native`
|
|
267
|
+
Use `tenuo-claude up --native` when Docker is not available.
|
|
232
268
|
|
|
233
269
|
Open Claude Code in `demo/`. See [demo/README.md](demo/README.md) and [Reference demo](#reference-demo) above.
|
|
234
270
|
|
|
@@ -292,8 +328,6 @@ Use Cloud when you need organization-scale governance, not just a single laptop:
|
|
|
292
328
|
every tool call at the hook and MCP proxy. Engineers cannot disable it with local
|
|
293
329
|
Claude permission edits or `--dangerously-skip-permissions`
|
|
294
330
|
|
|
295
|
-
Local mode (no Cloud account) remains fully supported for evaluation and single-project use.
|
|
296
|
-
|
|
297
331
|
### Cloud quickstart
|
|
298
332
|
|
|
299
333
|
Two keys, two files. Runtime never sees the admin key:
|
|
@@ -305,9 +339,7 @@ Two keys, two files. Runtime never sees the admin key:
|
|
|
305
339
|
|
|
306
340
|
**Do not** put the tenant-admin key in `.state/cloud.env` or your shell when running `tenuo-claude up`. Runtime refuses to start if an admin key is reachable.
|
|
307
341
|
|
|
308
|
-
**Fresh project**
|
|
309
|
-
|
|
310
|
-
Creates an example `tenuo.yaml` if none exists.
|
|
342
|
+
**Fresh project** (creates `tenuo.yaml` if none exists):
|
|
311
343
|
|
|
312
344
|
```bash
|
|
313
345
|
pip install tenuo-claude-code
|
|
@@ -315,9 +347,7 @@ mkdir my-project && cd my-project
|
|
|
315
347
|
tenuo-claude bootstrap --cloud
|
|
316
348
|
```
|
|
317
349
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
Prompts for credentials, then runs `init`, `tenuo-admin setup`, `up`, and `verify`. Pass a tenant-admin key to run setup in the same step.
|
|
350
|
+
The wizard prompts for a Quick Connect token (`tenuo_ct_…`), then runs `init`, `tenuo-admin setup`, `up`, and `verify`. For an explicit Cloud URL and API key without Quick Connect, use the manual setup block below.
|
|
321
351
|
|
|
322
352
|
Non-interactive:
|
|
323
353
|
|
|
@@ -327,7 +357,7 @@ tenuo-claude bootstrap --cloud --yes \
|
|
|
327
357
|
--admin-key "tc_…"
|
|
328
358
|
```
|
|
329
359
|
|
|
330
|
-
Omit `--admin-key` if `tenuo-admin setup` already ran.
|
|
360
|
+
Omit `--admin-key` if `tenuo-admin setup` already ran. Pass credentials with flags rather than `export TENUO_ADMIN_KEY`. Unset the admin key before `tenuo-claude up`; an admin key in the runtime environment causes startup to fail.
|
|
331
361
|
|
|
332
362
|
One-shot env vars for CI:
|
|
333
363
|
|
|
@@ -345,9 +375,9 @@ cd my-project
|
|
|
345
375
|
tenuo-claude onboard --cloud
|
|
346
376
|
```
|
|
347
377
|
|
|
348
|
-
|
|
378
|
+
If you do not pass an admin key to the wizard, run `tenuo-admin setup` before `up`, or place the admin key in `~/.tenuo/admin.env` and run setup yourself.
|
|
349
379
|
|
|
350
|
-
Manual equivalent. Credential templates in [templates/](templates/):
|
|
380
|
+
**Manual setup** (equivalent to the wizard). Credential templates are in [templates/](templates/):
|
|
351
381
|
|
|
352
382
|
```bash
|
|
353
383
|
cd my-project
|
|
@@ -357,13 +387,21 @@ mkdir -p .state ~/.tenuo
|
|
|
357
387
|
|
|
358
388
|
tenuo-claude init --cloud
|
|
359
389
|
tenuo-admin setup
|
|
360
|
-
tenuo-claude up
|
|
390
|
+
tenuo-claude check && tenuo-claude up
|
|
361
391
|
tenuo-claude verify
|
|
362
392
|
```
|
|
363
393
|
|
|
364
|
-
|
|
394
|
+
**Every session** (after onboarding):
|
|
365
395
|
|
|
366
|
-
|
|
396
|
+
```bash
|
|
397
|
+
tenuo-claude check && tenuo-claude up
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
If `check` reports **cloud bindings** failure, run `tenuo-admin setup` and retry.
|
|
401
|
+
|
|
402
|
+
### Verify onboarding
|
|
403
|
+
|
|
404
|
+
After onboarding, run:
|
|
367
405
|
|
|
368
406
|
```bash
|
|
369
407
|
tenuo-claude status
|
|
@@ -371,11 +409,14 @@ tenuo-claude check
|
|
|
371
409
|
tenuo-admin show
|
|
372
410
|
```
|
|
373
411
|
|
|
374
|
-
You should see: authorizer up, cloud profile merged, a trigger id in `tenuo-admin show`, and CHECK OK with no admin key in runtime env.
|
|
412
|
+
You should see: authorizer up, cloud profile merged, a trigger id in `tenuo-admin show`, **cloud bindings — trigger fire dry-run OK**, and CHECK OK with no admin key in runtime env.
|
|
375
413
|
|
|
376
414
|
Re-run `tenuo-admin setup` when Cloud capabilities change — setup syncs the local
|
|
377
|
-
gateway and reloads the authorizer when
|
|
378
|
-
`tenuo-claude refresh` for local-only policy edits (no
|
|
415
|
+
gateway, reconciles agent/trigger/holder bindings, and reloads the authorizer when
|
|
416
|
+
it is already running. Re-run `tenuo-claude refresh` for local-only policy edits (no
|
|
417
|
+
Cloud trigger change).
|
|
418
|
+
|
|
419
|
+
Stuck? [Troubleshooting (Q&A)](docs/TROUBLESHOOTING.md).
|
|
379
420
|
|
|
380
421
|
### Human approval (Cloud)
|
|
381
422
|
|
|
@@ -392,8 +433,8 @@ Both use the same session approval policy and the same hook/proxy approval workf
|
|
|
392
433
|
|
|
393
434
|
1. Configure a notification channel and identity binding in Cloud ([channels](https://docs.tenuo.ai/guides/adding-channels),
|
|
394
435
|
[identity bindings](https://docs.tenuo.ai/integrations/identity-bindings)).
|
|
395
|
-
2. Add approval gates in policy.
|
|
396
|
-
configs
|
|
436
|
+
2. Add approval gates in policy. Use `cloud.approver_identity_id` for team and
|
|
437
|
+
shared configs. Use `cloud.approver_identity` (display name) for demos only.
|
|
397
438
|
See [templates/tenuo.yaml.advanced.example](templates/tenuo.yaml.advanced.example).
|
|
398
439
|
3. Wire Cloud and re-run setup:
|
|
399
440
|
|
|
@@ -404,14 +445,14 @@ tenuo-claude up # if authorizer was down
|
|
|
404
445
|
tenuo-claude verify
|
|
405
446
|
```
|
|
406
447
|
|
|
407
|
-
For
|
|
448
|
+
For demos, display-name lookup is supported:
|
|
408
449
|
|
|
409
450
|
```bash
|
|
410
451
|
tenuo-claude onboard --cloud --advanced --approver "Alice Example"
|
|
411
452
|
```
|
|
412
453
|
|
|
413
|
-
If multiple Cloud identities share a display name,
|
|
414
|
-
|
|
454
|
+
If multiple Cloud identities share a display name, use `--approver-id` or
|
|
455
|
+
`cloud.approver_identity_id` in policy.
|
|
415
456
|
|
|
416
457
|
Reference demo:
|
|
417
458
|
|
|
@@ -430,9 +471,7 @@ Details: [docs/DETAILS.md § Human approval](docs/DETAILS.md#human-approval-clou
|
|
|
430
471
|
|
|
431
472
|
## Security
|
|
432
473
|
|
|
433
|
-
Tenuo works **alongside** Claude Code permissions
|
|
434
|
-
|
|
435
|
-
You still deploy hooks. Tenuo adds a signed session warrant, a local authorizer on every tool call, and a decision log per call. Policy is one file (`tenuo.yaml`).
|
|
474
|
+
Tenuo works **alongside** Claude Code permissions — it does not replace managed settings. `tenuo-claude init` wires a PreToolUse hook and MCP proxy; the authorizer enforces the session warrant on every tool call and logs a receipt. Policy is one file (`tenuo.yaml`).
|
|
436
475
|
|
|
437
476
|
### vs. Claude Code permissions
|
|
438
477
|
|
|
@@ -446,7 +485,7 @@ You still deploy hooks. Tenuo adds a signed session warrant, a local authorizer
|
|
|
446
485
|
| Org-wide deployment | Per-user settings; users can edit local hooks | Managed settings + shared policy; hook/proxy enforcement is not user-editable |
|
|
447
486
|
| `--dangerously-skip-permissions` | Bypasses Claude permission prompts | Hook and MCP proxy still enforce the warrant |
|
|
448
487
|
|
|
449
|
-
|
|
488
|
+
`--dangerously-skip-permissions` skips Claude's permission UI, not the warrant.
|
|
450
489
|
|
|
451
490
|
Org admins can block it in managed settings (`disableBypassPermissionsMode`).
|
|
452
491
|
|
|
@@ -463,7 +502,7 @@ For teams that need a **global configuration engineers cannot bypass**:
|
|
|
463
502
|
|
|
464
503
|
### Receipts
|
|
465
504
|
|
|
466
|
-
Every governed tool call
|
|
505
|
+
Every governed tool call carries a proof-of-possession signature; the authorizer verifies it before returning allow/deny.
|
|
467
506
|
|
|
468
507
|
What you can **read back** depends on mode:
|
|
469
508
|
|
|
@@ -504,11 +543,25 @@ Runtime refuses to start if an admin key is in the environment.
|
|
|
504
543
|
in version control, and the [Cloud capabilities above](#cloud-mode). See
|
|
505
544
|
[Tenuo Cloud docs](https://docs.tenuo.ai).
|
|
506
545
|
|
|
507
|
-
### Scope and
|
|
546
|
+
### Scope and boundaries
|
|
547
|
+
|
|
548
|
+
Tenuo governs **model-invoked tool calls**: Read, Bash, WebFetch, MCP tools,
|
|
549
|
+
subagent spawns, and the rest of the PreToolUse hook path. Each call is checked
|
|
550
|
+
against the signed session warrant before it runs.
|
|
551
|
+
|
|
552
|
+
**Agent Bash is in scope.** When the model uses the Bash tool, PreToolUse fires and
|
|
553
|
+
the authorizer applies your policy.
|
|
554
|
+
|
|
555
|
+
**TUI `!` shell is outside this scope.** In Claude Code, typing `!` in the input
|
|
556
|
+
box runs a command the **operator** typed. The model cannot invoke that path.
|
|
557
|
+
Prompt injection and tool overreach stay on the governed PreToolUse path; they do
|
|
558
|
+
not reach `!`.
|
|
559
|
+
|
|
560
|
+
Details: [docs/DETAILS.md § Agent tools vs operator shell](docs/DETAILS.md#agent-tools-vs-operator-shell).
|
|
508
561
|
|
|
509
|
-
|
|
562
|
+
### Fail-closed
|
|
510
563
|
|
|
511
|
-
Missing or broken `tenuo.yaml` denies every call until restored.
|
|
564
|
+
Missing or broken `tenuo.yaml` denies every governed tool call until restored.
|
|
512
565
|
|
|
513
566
|
Keys and credentials in `.state/` must be owner-only (`0600` in a `0700` directory).
|
|
514
567
|
|