The direct answer

Review the resources a worker may receive through inherited descriptors and explicitly configured standard streams, separately from its arguments and environment. For a selected POSIX Popen profile, declare extra-descriptor and standard-channel policy before process creation. That policy does not establish a sandbox, immutable input or complete control over the child’s later actions.

Look beyond the command and its environment

Imagine a trusted preprocessing service preparing job J-A. Its fixed native worker W-A needs one already authorized text input I-A and returns a summary. The parent also holds unrelated resources D-X and D-Y. A reviewer approves the executable and arguments and removes unnecessary environment variables. One question remains: what open resources could cross the process boundary?

Python’s descriptor documentation explains that Unix descriptors also refer to pipes and sockets. A useful review therefore identifies the referenced object and permitted operation, not just a filename or descriptor number. D-X could represent an unrelated connection even if its name never appears in the arguments. These labels describe an original fictional worksheet, not inspected files, connections or processes.

Freeze one creation profile and its exact boundary

Both official pages inspected identify Python 3.15.2 documentation. No installed interpreter, wrapper or operating-system configuration was inspected. Select direct POSIX Popen, a trusted fully qualified native executable, fixed argument sequence, shell disabled, application-controlled working directory and complete allowlisted environment. Exclude custom argument objects, pre-execution callbacks, alternate launchers and Windows behavior. W-A’s actual behavior requires separate review; its name is not a safety claim.

In the Popen contract, close_fds=True closes descriptors other than 0, 1 and 2 before the child program executes; pass_fds explicitly preserves selected descriptors on POSIX. Nonempty pass_fds forces close_fds=True. For J-A, choose close_fds=True and pass_fds=(). The intended statement is narrow: no extra parent descriptors are intentionally preserved for the executed worker through this selected interface.

Record standard channels as permitted resources

Choose stdin=DEVNULL, stdout=PIPE and stderr=PIPE. The standard-stream options distinguish these from None, which leaves the stream unredirected. DEVNULL uses the null device; PIPE creates a pipe. An empty pass_fds list therefore does not mean the worker has no descriptors or no communication channels.

Proposed J-A resource ledger; not observed
Resource categoryDeclared decision
Input I-ASeparately authorized job input under W-A’s reviewed operand contract; no extra descriptor passed.
Unrelated parent D-X and D-YExcluded from the extra-descriptor allowlist.
Worker standard inputNull-device input, not a parent application stream.
Worker standard output and errorSeparate application-controlled pipe channels; contents remain untrusted.
Working directory and environmentTrusted per-job selections; neither establishes descriptor or filesystem isolation.

The useful positive is ordinary summary preparation with this exact ledger and the separately admitted executable/input. It is eligible for a future implementation review, not reported as a successful invocation. Capturing output is not permission to send it to a model or publish it.

Use eight cards to challenge the inheritance claim

Original acceptance cards; all PROPOSED_UNRUN
CardProposed decision
J-A matches the complete ledgerAccept the narrow inheritance plan for later authorized verification; keep executable, input and OS rights as separate prerequisites.
Arguments and environment are reviewed, descriptor settings unknownHold. Those records do not establish this boundary.
pass_fds now names D-XReject the changed plan pending authorization of that specific object and operation. close_fds does not erase this explicit exception.
stdin now refers to an unrelated parent resourceReject the changed standard-channel selection, even with an empty extra-descriptor list.
Only an earlier inheritable-flag snapshot is suppliedDo not accept it as an atomic inventory or proof about later process creation.
A wrapper, platform or launch API changesHold outside the selected contract; do not transfer the POSIX review automatically.
W-A can open another resource under its OS rightsThe inheritance worksheet does not authorize that access or establish that it is blocked.
Output grows, stalls or completion is uncertainKeep the result incomplete; the descriptor plan supplies no memory ceiling, termination or complete-result evidence.

Each card changes one declared condition. A reviewer should name the changed gate rather than treating every rejection as proof that close_fds enforced the application’s entire policy.

Keep flags, object ownership and timing separate

The inheritability rules say Python-created descriptors are non-inheritable by default, and distinguish Unix execution of a new program from fork: non-inheritable descriptors can still be inherited at fork. The selected profile makes a before-execution claim, not a claim that no intermediate child ever possessed a resource.

For a future real review, maintain ownership and lifecycle evidence for any resource deliberately passed. A familiar number does not authenticate the object currently behind it or make its contents immutable. This worksheet establishes no atomic parent snapshot or resistance to concurrent close/reuse. Unknown concurrent setup requires separate supported coordination evidence; it must not be repaired by assuming an earlier inventory stayed current.

A controlled working directory also does not confine filesystem access. Removing credentials from the environment does not prove that other authority vanished. Review OS identity, filesystem and network permissions separately, along with the worker and its dependencies.

State what this review has not tested

No candidate subprocess was launched and no candidate descriptor, pipe, stream or socket was opened, queried, inherited or closed. No Python module was imported for these cases, no environment was inspected, and no worker or resource-limit experiment ran. Documentation reads and private editorial file handling are separate operations.

Boundary is a prelaunch model router with planned request-path checks, not a shipped process supervisor. Its synthetic action exercise and existing mock evidence do not validate this POSIX profile. Keep inheritance admission, execution outcome, output completeness and subsequent authorization as distinct evidence.

Primary sources

Official references supporting the guidance. Examples in this guide are synthetic and are not reports of a production incident.

  1. Python 3.15.2 documentation: subprocess
  2. Python 3.15.2 documentation: os descriptor operations and inheritance