150 lines
6.9 KiB
Markdown
150 lines
6.9 KiB
Markdown
# Nono policy fields in this environment
|
|
|
|
Consult this reference when mapping interview answers into a profile. Treat `nono profile validate` and the installed parent profiles as authoritative for the installed nono version.
|
|
|
|
## Inheritance
|
|
|
|
`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, 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
|
|
|
|
`workdir.access: "readwrite"` grants the directory from which nono launches the process. It does not mean the directory containing the profile.
|
|
|
|
Use the working-directory grant for a single active repository. Add explicit filesystem paths when one session needs several repositories or client directories.
|
|
|
|
## Filesystem access
|
|
|
|
Use directory fields for recursive directory-tree access:
|
|
|
|
| Field | Capability |
|
|
| --- | --- |
|
|
| `filesystem.read` | Read a directory tree |
|
|
| `filesystem.write` | Write a directory tree |
|
|
| `filesystem.allow` | Read and write a directory tree |
|
|
|
|
Use exact-file fields for one file:
|
|
|
|
| Field | Capability |
|
|
| --- | --- |
|
|
| `filesystem.read_file` | Read one file |
|
|
| `filesystem.write_file` | Write one file |
|
|
| `filesystem.allow_file` | Read and write one file |
|
|
|
|
Prefer enumerating exact repositories. Grant a shared parent only after confirming that every current and future child directory may receive the selected capability.
|
|
|
|
Resolve symlinks before reasoning about access. nono enforcement and audit output may use canonical targets.
|
|
|
|
## Internet tiers
|
|
|
|
### Offline
|
|
|
|
Derive from `nolabs-ai/pi`, not allowlisted `pi-local`. Inherited proxy domains conflict with blocked networking. Clear the inherited URL-opening and service-launch capabilities too:
|
|
|
|
```json
|
|
{
|
|
"extends": "nolabs-ai/pi",
|
|
"network": {
|
|
"block": true
|
|
},
|
|
"open_urls": {
|
|
"allow_origins": [],
|
|
"allow_localhost": false
|
|
},
|
|
"allow_launch_services": false
|
|
}
|
|
```
|
|
|
|
Validate the resolved policy and confirm that it reports `network blocked` with no approved URL origins.
|
|
|
|
### Allowlisted
|
|
|
|
Set networking enabled with a non-empty hostname list:
|
|
|
|
```json
|
|
{
|
|
"network": {
|
|
"block": false,
|
|
"allow_domain": [
|
|
"example.internal",
|
|
"registry.npmjs.org"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
Use hostnames only. URL paths belong in credential endpoint rules, not `allow_domain`.
|
|
|
|
Inherited hostname lists may remain effective. Derive from `nolabs-ai/pi` when the intended list must be smaller than `pi-local`'s list.
|
|
|
|
Collect domains by operation rather than guessing:
|
|
|
|
- source fetch and issue API
|
|
- package metadata and package artifacts/CDNs
|
|
- language toolchains and binary downloads
|
|
- model or application APIs
|
|
- deployment, telemetry, or error reporting
|
|
|
|
### Open
|
|
|
|
Set networking enabled without a domain allowlist inherited from the chosen parent. Derive from `nolabs-ai/pi`, not an allowlisted `pi-local`, unless installed documentation proves the inherited allowlist can be removed.
|
|
|
|
```json
|
|
{
|
|
"network": {
|
|
"block": false
|
|
}
|
|
}
|
|
```
|
|
|
|
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.
|
|
|
|
`allow_launch_services` controls service launching on supported platforms. Set it to `false` for offline profiles and inspect the inherited value for other tiers.
|
|
|
|
The installed `nolabs-ai/pi` parent enables selected OpenAI, Anthropic, and GitHub origins, localhost URL opening, and service launching. Child profiles must review those inherited settings rather than assuming `network.block` or `allow_domain` controls them.
|
|
|
|
## Unix sockets
|
|
|
|
`filesystem.unix_socket` controls pathname-mediated Unix sockets independently of Internet networking. Add only exact socket paths required by local services. Diagnose socket denials separately from domain denials.
|
|
|
|
## Credentials
|
|
|
|
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:
|
|
|
|
- `profiles/nono/pi-local.json`
|
|
- `~/.config/nono/packages/nolabs-ai/pi/profiles/pi.json`
|
|
- `~/.config/nono/packages/nolabs-ai/pi/README.md`
|
|
- `~/.config/nono/packages/nolabs-ai/pi/skills/nono-sandbox/SKILL.md`
|
|
- `/usr/share/doc/nono-ai-bin/README.md`
|
|
- `nono profile --help`
|
|
|
|
Stage candidates under `~/.config/nono/profile-drafts/`, then inspect them with:
|
|
|
|
```bash
|
|
nono profile validate --draft <name> --strict
|
|
nono profile show ~/.config/nono/profile-drafts/<name>.json
|
|
```
|
|
|
|
Validate the repository copy with `nono profile validate --strict profiles/nono/<name>.json`.
|
|
|
|
When promoting over an existing regular active profile, nono requires `~/.config/nono/profile-drafts/<name>.base` to contain the active profile's lowercase SHA-256 digest. Prefer nono's profile-edit workflow to create this guard. Preserve the repository symlink convention instead of promotion when the profile belongs in this repository.
|