Skip to content
Merged
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ the compiled policy allows on truthful evidence.** Remove isolation or the broke
and Interlock makes no claim about child-process writes. This honesty is enforced
by the broker tests, not just asserted here.

See [Enforcement model — transport is not authority](docs/concepts/enforcement-model.md)
for how this guarantee holds across local, agent, and cloud-sandbox environments.

## Install

**Prebuilt binary (no Go toolchain).** The installer detects your platform,
Expand Down
5 changes: 3 additions & 2 deletions UPSTREAM.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
".gitattributes": "3d38cf98dcc69b2af4941b76ed3f04e51273fdbd4fc54032e88cf3223b4b9198",
".goreleaser.yml": "cdb7f4f950f7e70c0052205966cb11ef7b9a0b270ff03a670deba696cf1c61b8",
"LICENSE": "bd17d47aefaa7406616179288058001b6532881a2517254fe668d7e9c4965cfb",
"README.md": "77979fdd7a0781305d65bf2576cb7368ea339a640f7fab9d6d8ea4a37888e3b0",
"README.md": "39b4cc851a57c654132a73b84d594e61c8a568fd3aed26d86e503133dcdb84c8",
"assets/interlock-boundary.png": "9ae73098102d0589bf1bb912af6d39df4d1465eb93e8cea5b7e982e6fa79ef51",
"assets/interlock-boundary.svg": "0bbb5aacc90e9311aef732dc2075aa0896ec25d0789b6612a3d98922646a0f1e",
"assets/interlock-hero.png": "a30def06d493775458455ed891f1631200a61eafa54fa53d64474a3d340e2757",
Expand Down Expand Up @@ -78,6 +78,7 @@
"derive/review.go": "59349539a8dbb8664b89b0f2a3cabc50da03e3975727ccae36bda70d3968f704",
"derive/schema.go": "4d10bca81110512a10aaf6306d5a5a2ebc4193058b4500cd92022a99b42d4f1e",
"doc.go": "ffda943422fc0104acff178f17f096df5d9d0e9065e598aa0d817c457edfb198",
"docs/concepts/enforcement-model.md": "998939bdf003cc0e192fe68ca30d29e5ad76d4682bfeb14d582d40c478dec15d",
"e2e/coverage_test.go": "1240b8a56703d3c2b2492ef63049dc4573b769c444549cd693b178c06d3ab136",
"e2e/e2e_test.go": "28a8d8c7aa3dfa327b615c00454a438264e2b898abc84fe5c0efb9be0a2fdf3f",
"e2e/isolation_test.go": "9498039e244184c8ce2460742af70dd93af9e5eada183119344f2d4d5df222e2",
Expand Down Expand Up @@ -116,7 +117,7 @@
"generator": "operatorstack/interlock:project-upstream",
"schema_version": 1,
"source": {
"commit": "4006eba0241ef7c9e0df634d083be7f2888e6fdb",
"commit": "15a45d5d730690e825b3c9cf1de077ec876a0c2b",
"path": "labs/21-interlock",
"repository": "operatorstack/intelligence-flow"
}
Expand Down
81 changes: 81 additions & 0 deletions docs/concepts/enforcement-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Enforcement model — transport is not authority

Interlock runs in more than one place: a laptop, a local coding agent, a cloud
sandbox, and CI. This document explains what changes between those places and
what does not.

Read [the enforcement boundary](../../README.md#the-enforcement-boundary-what-is-and-isnt-guaranteed)
first. It defines the three modes and the V1 guarantee. This document adds the
operational view: **the transport changes with the environment; the authority
does not change.**

## Two rules

1. **Transport changes.** The transport carries the request to the controller.
The controller answers `allow` or `deny`. The transport is different in each
environment.
2. **Authority does not change.** The broker makes the evidence. The gate blocks
the merge. The authority is the same in every environment.

The controller is transport. The broker and the gate are authority. Do not
confuse the two. The way a decision is *asked* is not the thing that makes the
decision *trustworthy*.

## Where Interlock runs

| Environment | Controller runs | Hooks fire | Extra setup | Result |
|---|---|---|---|---|
| Local (laptop) | On the laptop | Yes | None | Works |
| Local agent (Claude Code, Cursor) | On the laptop | Yes | None | Works |
| Cloud sandbox (Claude Code remote, Devin, Codespaces) | In the sandbox | Yes, after setup | Hydrate the controller. Wire the hooks. | Works after setup |

In every environment the messages stay local (JSON-Lines over stdio). The sandbox
does **not** need network access to decide.

## The authority does not move

### Broker

The broker makes hash-bound evidence. The broker does the protected action. The
controller cannot fake this. The engine compares claims; the broker makes the
claims truthful.

The V1 guarantee is Strict mode: the agent cannot modify the protected artifact,
and only the broker can — and only for a request the compiled policy allows on
truthful evidence. The broker tests enforce this, they do not just assert it. See
the [`broker`](../../broker) package.

### CI gate

The gate runs Interlock in CI. The gate blocks the merge if the check fails. The
gate runs in one environment you control. The gate runs for every change, from
every environment.

## Fail-closed

If the controller does not answer, the result is `deny`. Default deny also applies
when no rule matches. A missing or unreachable controller cannot open the gate.

## Set up the controller

- **Do** put the controller in the sandbox. Keep the messages local.
- **Do not** put the controller on another network. A locked sandbox cannot reach
it. Then Interlock denies **every** action.

Use a network controller only when a local controller is not possible. Then add
authentication and a latency budget.

## Cloud agents and sandboxes (deferred)

V1 needs no special code for cloud agents. The gate makes every environment safe.
Whatever the sandbox does, the change must pass the same gate to reach `main`.

The transport ergonomics for sandboxes — how a request reaches a controller
inside a remote agent — is future work. It is tracked in
[operatorstack/pitot#18](https://github.com/operatorstack/pitot/issues/18).

## Remember

- Local hooks give fast feedback. They are not the guarantee.
- The gate gives the guarantee. It runs in one place you control.
- Cloud agents need no special code. Every change must pass the same gate.
Loading