# Extension trust and paths ## Function BT treats every installed `.bts` package as a trusted local program dependency. Extensions do not declare per-package permissions, and the runtime does not distinguish packages downloaded from the official catalog from packages copied, privately built, modified, or distributed in closed-source form. Loading an extension never contacts the website. The official catalog is a separate distribution boundary: it lists only reviewed open-source versions and is responsible only for the exact package and hash that it publishes. Installing any other extension is the user's own trust decision and remains unrestricted by the catalog. BT's optional process-wide policy still applies uniformly to the whole process. `BT_PERMISSION_ALLOW` and `BT_PERMISSION_DENY` can restrict BT itself, but they do not grant different capabilities to different extensions. Path roles let WASM extensions receive project paths in the WASI preopened project directory. The host resolves BT path syntax, validates the object required by the role, prevents a converted role path from escaping the project root, and passes a WASI-relative string to the extension. ## Syntax No extension permission declaration is required. A path role is declared only in `bindings.json`: ```json { "name": "copy_to", "id": 2, "params": [ { "name": "target", "type": "string", "role": "path_write" } ], "returns": "bool" } ``` ## Trust boundaries | Source | Runtime treatment | Official catalog review | | ------ | ------ | ------ | | Official catalog package | Same host ABI and process policy as every other `.bts` | Applies only to the published version, source commit, and SHA-256 | | Manually copied package | Same host ABI and process policy | None | | Private or closed-source package | Same host ABI and process policy | None | | Locally modified or rebuilt package | Same host ABI and process policy | None, even when it uses the same name | The catalog does not act as an allowlist, and BT does not query it while loading local packages. Removing a version from the catalog does not disable or delete an installed copy. ## Path role fields | Field | Type | Required | Default | Valid values | Meaning | | ------ | ------ | ------ | ------ | ------ | ------ | | `name` | String | Yes | None | snake_case identifier | Parameter name exposed to BT scripts. | | `type` | String | Yes | None | Must be `string` for a path role | Runtime parameter type. | | `role` | String | No | `value` | `value`, `path_read`, `path_write`, `path_dir` | Selects ordinary value handling or host path conversion. | | Role | Path requirements | | ------ | ------ | | `path_read` | The target must exist and be a file. | | `path_write` | An existing target must not be a directory; a new target must have an existing parent directory. | | `path_dir` | The target must exist and be a directory. | ## Return value Path roles do not have a separate script return value. A valid argument is converted and passed to the WASM extension. Invalid types, missing objects, invalid output parents, project escapes, or a process-wide filesystem denial return an English runtime error. ## Path conversion example ```bt ok = file_demo('@/in.txt').copy_to('@/out.txt') // Output: true print ok ``` The host processes each path in this order: 1. Resolve `@` from the project root and ordinary relative paths from the applicable source directory. 2. Canonicalize existing paths and output parents. 3. Reject role paths that escape the project root, including escapes through symbolic links. 4. Check the file or directory shape required by the role. 5. Convert the result to a WASI-relative path such as `in.txt`, `nested/out.txt`, or `.`. The WASM module receives a guest-relative path and must not assume that it receives a host absolute path. When the process-wide filesystem capability is enabled, the WASI runtime preopens the project root for reading and writing; this is uniform for every WASM extension and is not selected by manifest metadata. ## Notes - The `permissions` field has been removed. A package that still contains it fails manifest validation and must be rebuilt in the new `.bts` format. - Installing an extension means trusting its code. Extension code can use every host capability implemented by its ABI, subject only to the process-wide BT policy and operating-system account. - Process-wide resource limits, package validation, WASM memory isolation, bounded queues, call timeouts, and object lifecycle checks remain runtime stability rules rather than extension authorization. - `path_read` and `path_dir` require an existing target. - `path_write` requires an existing parent when creating a new file. - A path role rejects an empty string and a converted path outside the project root. - Pure BT extensions normally use the BT standard library directly; the WASI path conversion rules primarily apply to WASM extensions. - [Native background processes](/en/docs/extensions/host-process) run outside the WASI sandbox and inherit the operating-system account's authority.