feat(nono): add restrictive core policy contract

This commit is contained in:
jb
2026-08-30 12:49:17 -04:00
parent 54c20e2012
commit 90f8090f61
19 changed files with 1862 additions and 9 deletions
+3 -2
View File
@@ -43,9 +43,9 @@ Ask about exact files, credential routes, and Unix sockets only when the request
Completion criterion: map every requested capability to an exact path, hostname, credential route, or socket and an explicit access level.
### 3. Choose a safe parent
### 3. Choose safe composition
Use one `extends` parent; build a transitive chain rather than multiple inheritance.
Nono 0.74 accepts either one `extends` parent or an ordered array. Multiple parents merge left to right, deduplicate shared ancestors, append list-valued grants and environment filters, and preserve restrictive decisions such as blocked networking. Use a single parent for ordinary profiles. Use multiple parents only when every additive capability and merge result has been reviewed with `nono profile show` and behavioral tests.
Apply these inheritance rules:
@@ -53,6 +53,7 @@ Apply these inheritance rules:
- Extend `nolabs-ai/pi` for offline mode. Set `network.block` to `true`, clear `open_urls.allow_origins`, disable `open_urls.allow_localhost`, and set `allow_launch_services` to `false`. Do not extend allowlisted `pi-local`: inherited proxy domains conflict with blocked networking.
- Extend `nolabs-ai/pi` rather than `pi-local` when an allowlisted child needs fewer domains than `pi-local`, or when creating an open-network profile. Reproduce only the required local filesystem/socket policy.
- Edit `pi-local` only after showing how the change affects every future project launched with it.
- For trusted generated profiles, materialize the reviewed fragments into one canonical profile and validate that file. Do not rely on multiple inheritance to widen a blocked core with a provider route.
An inherited broad capability cannot reliably be narrowed by an empty child array. Choose a restrictive parent instead.
@@ -4,9 +4,11 @@ Consult this reference when mapping interview answers into a profile. Treat `non
## Inheritance
Use a single string-valued `extends`. Local profiles may extend `pi-local`, registry profiles such as `nolabs-ai/pi`, or another available profile. Inheritance is transitive.
`extends` accepts one profile name or an ordered, non-empty array of profile names. Nono 0.74 merges multiple parents left to right and resolves each shared transitive ancestor once.
Treat included groups and list-valued capabilities as additive. An empty child list does not establish revocation. To create a narrower policy, derive from a narrower parent and add only the required capabilities.
Treat included groups, environment allow/deny lists, and list-valued capabilities as additive. An empty child list does not establish revocation. Restrictive decisions such as `network.block: true` remain restrictive when parent profiles are combined. To create a narrower policy, derive from a narrower parent and add only the required capabilities. When a trusted generator must combine a fail-closed core with one selected provider, materialize and validate one canonical profile instead of expecting inheritance to widen the blocked core.
Nono 0.74 `profile show --json` omits resolved environment, command-policy, connect-port, and custom-credential fields. Use strict validation plus behavioral `nono run` or `nono why --command` proofs for those capabilities rather than treating the resolved JSON as complete evidence.
## Runtime working directory
@@ -100,6 +102,10 @@ Set networking enabled without a domain allowlist inherited from the chosen pare
State that open mode allows destinations beyond those currently known to the project.
## Exact loopback ports
On Linux with Landlock network support, use `network.connect_port` for outbound-only access to exact TCP ports. Use `network.open_port` only when the sandbox must both connect and bind. A port rule does not establish hostname or credential access; validate those separately. Prove exact enforcement with live listeners on the selected port and an adjacent denied port because strict schema validation alone does not demonstrate kernel enforcement.
## URL opening and service launching
`open_urls.allow_origins` controls origins that sandboxed tools may ask the host to open. `open_urls.allow_localhost` controls localhost URL opening. These capabilities remain separate from direct Internet access.
@@ -116,6 +122,10 @@ The installed `nolabs-ai/pi` parent enables selected OpenAI, Anthropic, and GitH
Treat a credential route as a separate capability from reaching its domain. Confirm both the route and endpoint restrictions. Prefer nono-mediated credential routes over exposing real API keys inside the sandbox.
## Command policies
Place each caller edge under `command_policies.commands.<name>.from.<caller>`. Inherited invocation denials remain restrictive when a child declares a more permissive default, so verify the effective decision with `nono why --profile <profile> --command <name> --caller <caller> --json -- <args>`. Nono 0.74 creates a command-policy supervisor Unix socket under `TMPDIR`; keep the private runtime path short enough for Linux `SUN_LEN` until the tracked limitation is fixed.
## Local sources of truth
Read these when behavior or schema details are uncertain: