---
title: Permission Model
description: How network and knowledge-base permissions are requested and checked at install time; a gem's own storage, files and folders, and document extraction need no permission.
section: dev
order: 30
updated: 2026-11-05
translation_of: zh
source_sha: 6abd1a9aec85
---
# Permission Model
## Principles
A gem lists the permissions it needs in its manifest. Only these need to be requested: network (`network`), the user's models (`llm` under `providers`, which spends the user's money), the knowledge base (`knowledge`), email (`email`), and the user's accounts (`connections`). A gem's own storage, files, and document extraction (`ctx.extract`) are not permissions; every tool of every gem has them.
There is no confirmation step at install time (as in a phone app store, the user sees what the gem can do on its store page and installs it with one click). Install records the permissions listed in the manifest, and at run time only this record is consulted; the manifest is not read again.
**Anything that needs configuration by the user is off until configured.** Which mailboxes the gem can read, which parts of the knowledge base it can use, which external account it uses: at install time there are none of these, and the gem's requests are rejected until the user turns them on in the gem's page. On upgrade, what the user already turned on is kept; anything new is likewise off by default. There is no confirmation popup at run time.
## Network
```json
"permissions": {
"network": {
"hosts": ["api.open-meteo.com"],
"reason": "Look up weather forecasts"
}
}
```
| Field | Required | Description |
| --- | --- | --- |
| `hosts` | Yes | External hosts the gem may reach. Host names only (`api.example.com`), with no scheme or path and no wildcards. If the service is not on the default port, include the port (`api.example.com:8443`; a different port is a different host). Internationalized domain names are written in `xn--` form. IP addresses and `localhost` may be listed only when `allowLocalNetwork` is `true`. A request to a host that is not listed is rejected before it is sent. |
| `allowLocalNetwork` | No | Whether the gem may reach the user's own machine and local network. Defaults to `false`; see below. When `true`, `hosts` may be empty. |
| `reason` | Yes | Why the gem needs network access. Shown on the gem's page. |
`ctx.http.fetch` and `ctx.extract.fromUrl` in tools (download a document, then extract its text), and agents that can use the browser, are all checked against this same permission, including every redirect hop. On top of it sit the user's own network rules ("Settings › System › Network access"); a gem's permission can only narrow these, never widen them.
### Local machine and internal network
Notochord sorts addresses into two classes with different rules:
- **External network**: websites and online services. The user can choose allowlist or blocklist mode; the default is open.
- **Local machine and internal network**: the user's computer (`localhost`, `127.0.0.1`, `[::1]`), addresses on the home or company network (`10.x.x.x`, `172.16–31.x.x`, `192.168.x.x`, `169.254.x.x`, `100.64–127.x.x`, and the IPv6 equivalents), and domain names that resolve to those addresses (for example a company-internal `wiki.corp.example.com`).
Why they are separate: the local machine and internal network hold the user's own devices and internal services (router and NAS admin pages, printers, the company's OA system and wiki). These often have no password, because normally only people inside can reach them, and they often hold internal data. A web page the AI reads may hide instructions, and a third-party gem may try to probe the user's internal network; if these addresses were freely reachable, that would open a door between the internet and the user's internal network. So by default none of them can be reached, and only addresses the user has listed personally are allowed.
For a gem to reach the local machine and internal network:
- Write `"allowLocalNetwork": true` in the manifest (in a Gem Studio draft, write `"allow_local_network": true`, or tick "Local machine and internal network" under Permissions in the overview). The gem's page states that it can reach the local-machine and internal-network addresses the user has listed.
- The gem can reach only the addresses the user has listed under "Network access › Local machine and internal network"; the gem cannot specify them itself. Local and internal addresses do not go into `hosts`.
- A gem without `allowLocalNetwork` cannot reach an address even if the user has listed it.
- Example: a gem that helps a developer test a website. Only after the user adds `localhost:5173` to the list can its agent open `http://localhost:5173` in the browser.
- Downloads of [`resources`](/en/dev/manifest.md#resources) never reach the local machine or internal network.
## Files are not a permission
A gem's code can touch only two kinds of files: **the folder of this one run**, and **the folder of the conversation it was called from**. Nothing outside the conversation is reachable, just like the AI in the conversation (its file tools also work only in the conversation folder). There are no fixed paths to request, and nothing to write in the manifest: every tool has `ctx.files`. For the read and write interface, see the [Tools API](/en/dev/tools.md#ctxfiles).
### Run folder
Every run has its own folder:
| Who is running | Where the run folder is |
| --- | --- |
| A SOP or tool called from a chat | In the conversation's working directory, at `runs/-Notochord