Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions docs/notes/agent-capability-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,63 @@ generated output of one policy engine, not your architecture.
3. **Policy ⇄ Sandboy overlap** — how much of `[exec]`/`[network]` should be
*compiled down* into a Sandboy policy (real enforcement) vs stay advisory
context? Ideally `owen policy` emits a `sandboy` policy for mode (B).

---

## 8. Addendum (2026-07-05): authoring language for `owen.policy` — CUE, not TOML

§3 sketched `owen.policy.toml` as a single flat file. That's fine while there is
one profile. It stops being fine the moment there is more than one — `no-net`,
`worktree-only`, a `windows`-tagged exec profile, a `trusted-repo` vs
`untrusted-repo` split — because those need to **compose** ("inherit the base,
add these steps"), and TOML has no merge semantics of its own. Composing TOML by
hand means copy-pasting the base into every profile, and a copy that forgets
`network.default = "deny"` is precisely the failure mode this whole layer exists
to prevent — a config bug that reads as a permission grant.

**Decision: author `owen.policy` in [CUE](https://cuelang.org).** The reason to
prefer it over "TOML + a templating layer" is CUE's *unification* model: a
parent and a child don't override each other, they unify, and unification is a
**compile error** if they disagree. A leaf profile that tries
`network: "allow"` against a base that says `network: "deny"` doesn't silently
win — it fails to build. That is a materially different guarantee than
inheritance-with-override (Terragrunt-style merge, Jsonnet `+`), where the leaf
always wins and a mistaken override ships silently.

```text
policies/
no-net.cue # network: "deny" — the floor, never overridden
worktree-only.cue # repo.read/write confined to the worktree
default-processes.cue # exec allowlist
gates/
own-net.cue # unifies the policies above + step list
own-net.windows.cue # must *explicitly* switch to a different process
# profile to add e.g. `powershell` — can't inherit a
# denylist that silently forgot it
```

Compiled down to flat JSON for whatever actually enforces it at runtime (the
Sandboy policy, `owen policy check`'s consumer) — the authoring layer is for
humans; the enforcement point should stay a boring, strict parser with no CUE
evaluation at run time.

Runner-up: **Nickel** (`import` + record merge via `&`, typed contracts) — a
reasonable second choice if the policy ever wants functions or generated
defaults; picked CUE first specifically because a security floor benefits more
from "conflicts are hard errors" than from programmability.

**Rejected for this use** (fine tools, wrong fit for a security source of
truth): **Jsonnet** (`+`/`super` composition is generative — right for stamping
out many manifests, wrong posture for policy, and a silent-override bug is just
as easy as in TOML with fancier syntax); **Dhall** (safe and total, but more
ergonomic weight than this scale needs — CUE gets the same "disagreement is an
error" property more cheaply); **HCL/Terragrunt** (`include` + `merge_strategy`
gives structural inheritance, but drags in Terraform's whole tooling/mental
model for a project that has nothing to do with infrastructure deployment).

**This does not change §0/§1.** WIT/Wasmtime stays the *execution* boundary for
tool components that parse untrusted input (already spiked as `audit/adapters`,
per `sandboy-isolation-adr.md` §6's update) — it is not a candidate for policy
*authoring*. The two axes stay separate: CUE composes the data, WIT/Sandboy
enforce it. See `007/docs/zero-trust-framework.md` for how 007 concretely
consumes a CUE-authored policy as `.007/gate.lock.json`.
9 changes: 9 additions & 0 deletions sandboy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ tcp_bind = []
# omit seccomp_deny to use the curated default denylist
```

This TOML is the file Sandboy actually reads, and it should stay exactly this
plain. Once there's more than one profile (`no-net`, `worktree-only`, a Windows
exec allowlist) to compose without copy-pasting, author the source in CUE and
render it down to this shape (`cue export step.cue --out toml > step.toml`) —
Sandboy's runtime never needs to know CUE exists. Full rationale and the
`#Policy`/`#Base`/`#NoNet` schema this maps onto:
[`007/docs/zero-trust-framework.md`](https://github.com/PhysShell/007/blob/main/docs/zero-trust-framework.md)
§12.

## Build & run

> **Authored, not compiled here.** Written in a network-restricted sandbox
Expand Down
Loading