Skip to content

Commit 796e5db

Browse files
bryaneganclaude
andcommitted
Update docs: delegation API, scoping, Z3 redesign, security checklist
- ARCHITECTURE.md: container crate now four API layers (Task, Delegation, Builder, Forge) with key types updated - README.md: delegation code example, system_prompt_fragment, is_scoped_within - SECURITY.md: delegation security checklist (forward_api_key opt-in, is_scoped_within for privilege escalation, narrow_is_sufficient, tool name validation) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 902d9f5 commit 796e5db

3 files changed

Lines changed: 31 additions & 17 deletions

File tree

README.md

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -289,31 +289,36 @@ The `gleisner-lacerta` crate includes a Z3-powered policy lattice module (behind
289289

290290
## Container Library
291291

292-
`gleisner-container` provides three API tiers:
292+
`gleisner-container` provides four API layers:
293293

294294
```rust
295-
// Task API — for agents and automation (declare needs, get minimal sandbox)
296-
let sb = TaskSandbox::new("/workspace")
295+
// Task API — declare needs, sandbox derives itself
296+
let task = TaskSandbox::new("/workspace")
297297
.needs_tools(["claude", "git"])
298-
.needs_network(["api.anthropic.com"])
299-
.build()?;
300-
301-
// One-liner for Claude Code
302-
let sb = claude_code_sandbox("/workspace")?;
303-
304-
// Builder API — for explicit control
298+
.needs_network(["api.anthropic.com"]);
299+
println!("{}", task.explain()); // audit: why each permission
300+
println!("{}", task.system_prompt_fragment()); // for inner agent
301+
let sb = task.build()?;
302+
303+
// Delegation API — Claude-to-Claude coordination
304+
let result = Delegation::to("/workspace")
305+
.task("Fix the auth bug in src/auth.rs")
306+
.context("JWT expiry check skipped on line 42")
307+
.allow_tools(["cargo", "git"])
308+
.forward_api_key()
309+
.timeout(Duration::from_secs(300))
310+
.build()?.execute()?;
311+
312+
// Builder API — explicit control
305313
let mut sb = Sandbox::new();
306-
sb.rootfs()
307-
.bind_ro_all(["/usr", "/lib"])
308-
.project_dir("/workspace")
309-
.allow_domains(["api.anthropic.com"])
310-
.seccomp(SeccompPreset::Nodejs);
314+
sb.rootfs().project_dir("/workspace")
315+
.allow_domains(["api.anthropic.com"]);
311316

312317
// Forge API — auto-configure from package metadata
313318
let sb = ForgeComposition::new(report, project_dir).sandbox()?;
314319
```
315320

316-
Key capabilities: `explain()` audits why each permission was granted, `narrow()` compares declared vs observed usage to suggest tighter configs, `merge()` combines multi-agent requirements.
321+
Key capabilities: `explain()` audits grants, `narrow()` tightens configs from observed usage, `merge()` combines multi-agent needs, `is_scoped_within()` proves delegation safety, `system_prompt_fragment()` generates boundary-aware prompts for inner agents.
317322

318323
## Documentation
319324

docs/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ The project is a Cargo workspace with ten crates. All version numbers and lint c
6464
| `gleisner-scapes` | Event infrastructure. Audit event types, broadcast channel event bus, JSONL audit log writer. | `EventBus`, `EventPublisher`, `AuditEvent`, `EventKind`, `JsonlWriter` |
6565
| `gleisner-forge` | Nickel package evaluation for minimal.dev. Content-addressed evaluation, topological dependency ordering, sandbox policy composition, Lean 4 proof verification (via `lake build`), CycloneDX 1.6 SBOM with proof-carrying Declarations, attestation metadata extraction. | `ForgeConfig`, `EvalContext`, `ComposedEnvironment`, `VerifyConfig`, `PackageVerification`, `PolicyComplianceProof` |
6666
| `gleisner-bridger` | SBOM generation. Cargo.lock parsing, CycloneDX 1.6 JSON output. | `Sbom`, `Component` |
67-
| `gleisner-container` | Container library with three API tiers: **Task API** (`TaskSandbox` — declare what the task needs, sandbox derives itself), **Builder API** (`Sandbox`explicit mounts, namespaces, Landlock, seccomp), **Forge API** (`ForgeComposition`auto-configure from package metadata). Features: `rootfs()` auto-discovery, `bind_ro_all()` batch mounts, `Stdio` control, timeouts, signal detection, `explain()` capability auditing, `narrow()` runtime tightening, `merge()` for multi-agent sandboxes, `claude_code_sandbox()` one-liner. Optional features: `forge` (package-aware), `lattice` (Z3 policy verification), `attestation`. | `TaskSandbox`, `Sandbox`, `Command`, `Output`, `Stdio`, `ForgeComposition`, `CapabilityExplanation`, `NarrowingReport`, `ObservedCapabilities` |
67+
| `gleisner-container` | Container library with four API layers: **Task API** (`TaskSandbox` — declare needs, sandbox derives itself; `explain()`/`narrow()`/`merge()`/`system_prompt_fragment()`), **Delegation API** (`Delegation`Claude-to-Claude coordination with `is_scoped_within()` scope verification, `forward_api_key()` opt-in, context file injection), **Builder API** (`Sandbox`explicit `rootfs()`/`bind_ro_all()`/`project_dir()`, `Stdio` control, timeouts, signal detection), **Forge API** (`ForgeComposition` — auto-configure from package metadata). Optional features: `forge`, `lattice` (Z3 verification), `audit` (JSONL observer), `attestation`. | `TaskSandbox`, `Delegation`, `Sandbox`, `Command`, `Output`, `ForgeComposition`, `ObservedCapabilities` |
6868

6969
### Dependency Graph
7070

docs/SECURITY.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,15 @@ Practical steps for users setting up Gleisner in a new environment.
529529
either task alone.
530530
- [ ] **Use Z3 `verify_against_policy()`** (with `lattice` feature) to
531531
formally prove a container config satisfies your security baseline.
532+
- [ ] **Use `is_scoped_within()`** before delegation to prove the inner
533+
sandbox can't do anything the outer sandbox can't. Catches privilege
534+
escalation in multi-agent setups.
535+
- [ ] **Use `Delegation` with `.forward_api_key()`** only when needed.
536+
API key forwarding is opt-in — the inner process could exfiltrate it.
537+
- [ ] **Use `narrow_is_sufficient()`** to verify a tighter config still
538+
covers observed behavior before deploying it.
539+
- [ ] **Validate tool names** — the task API rejects `/`, `\`, `;`, `'`,
540+
backtick, and null characters in tool names to prevent injection.
532541

533542
### Verification
534543

0 commit comments

Comments
 (0)