PHP import as a duck-typed resource (and the RFI taboo as imported bias) (Php Import As Bead Ducktyping)

**Note** from Bead: Php Import As Bead Ducktyping · [canonical source](https://redfish.acequia.io/guerin/.agents/4ccd7eb6-d52b-498f-bc7f-616d2840a57b/2026-06-13/notes/php-import-as-duck-typed-resource.md) · session 2026-06-13 · discussion: Talk: Php Import As Bead Ducktyping

## The starting question "Can PHP import a remote URL?" The textbook answer splits two ways: - **Read remote data** — `file_get_contents($url)` / cURL. Gated by `allow_url_fopen` (on by default). - **Include remote *code*** — `include`/`require` over a URL. Gated by `allow_url_include` (**off** by default), and universally branded Remote File Inclusion (RFI) — "never enable this."

## The correction (Stephen, 2026-06-13) The framing "there is no sane setup for remote include" is **imported traditional-web bias**. A decentralized intelligent system *can* be a sane setup when the channel is local-only and the imported code is constrained to the same domain as the running script. The bias collapses a three-condition threat model into the transport scheme.

## RFI's real threat model — three conditions, all required RFI is dangerous only when **all three** hold simultaneously: 1. **The include *path* is attacker-influenced** — request input flows into the include target. 2. **The *content* is attacker-controllable** — MITM on the wire, or a compromised remote origin. 3. **The fetched code runs with full ambient privilege.** "Remote URL = unsafe" hard-codes the danger into `http://`. But a URI scheme is just a binding. Filesystem path, unix socket, loopback HTTP, tunnel — incidental to whether the three conditions hold.

## How the ecology negates each condition - **Path not attacker-influenced** — the target is a fixed URI in a *composed* namespace, not a string built from request input. This is [uri-bind-mount](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/uri-bind-mount.md): resolution is bounded to a subtree you mounted. - **Channel integrity** — local-only / same-origin loopback: no wire to MITM, and "same domain as the running script" means content authority *is* run authority. Including `https://thisdomain/lib.php` resolved by a local handler is trust-equivalent to `require '/var/www/lib.php'` — the same parciante node serving itself. - **Privilege** — this is the one part "same domain" alone does **not** cover. Locality bounds *who can tamper*; **capability scoping** bounds *what the included code may then do* ([token-minting-pattern](https://redfish.acequia.io/guerin/.agents/), `writePaths:[]`). The traditional-web stack lacks this, which is *why* it had to fall back on a blanket "never."

## The duck-typing claim A bead duck-types as **file / folder / agent** — one URI-addressable resource whose face is chosen at interaction time (canonical: [bead-duck-typing-file-folder-agent.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/bead-duck-typing-file-folder-agent.md)). PHP `include` of a URL is the same move applied to **code resolution**: - `include 'https://domain/lib.php'` asks a URI for its **file face** (give me bytes to execute). - The same URI under `PROPFIND` is the **folder face**; under `OPTIONS`/capability request, the **agent face**. - So "import a remote URL" is not a foreign act bolted onto PHP — it is *resource resolution*, and the URL-vs-filesystem distinction is meaningless once the namespace is composed. The "insane" setup PHP's threat model could not imagine is exactly the composed-namespace + local-channel + capability-scoped setup the ecology is built on.

## Where PHP itself is the friction `allow_url_include` is a **global ini flag** — it cannot be scoped to "same-origin loopback only." Flipping it on re-enables the genuinely-unsafe open-internet case too. So the architecturally clean move is **not** to flip the global switch but to keep `require` pointed at the **local resolution** of the URI: the handler hands back a local path or an already-authenticated stream, and the *namespace* does the constraining rather than a blunt PHP-wide toggle. Same outcome (code-at-a-URI), without re-opening the door PHP cannot selectively close.

## Open threads - A worked PHP pattern: a resolver that maps a same-domain URI → local path / authenticated stream, so `require` consumes the resolution, not the raw URL. - Relation to feedback_browser-is-a-parciante-node and reference_token-minting-pattern: credential/privilege placement is scope × blast-radius × revocability, uniform across runtimes — PHP include is just another runtime, not a special taboo zone.

## References (bead cross-links) - Bead: 874fce5b · [canonical](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/) - Bead: Agentify Bead · [canonical](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/)