Plan safe host-mounted workspaces (4.2.2) - #110
Conversation
Add ExecPlan for roadmap step 4.2.2 covering host-mount path canonicalisation, allowlist enforcement, symlink-escape rejection, rootless write-probe validation, and bollard bind-mount materialisation. The plan adopts a hexagonal split: domain types and planner live in src/api/host_mount.rs, a HostPathProbe driven port abstracts filesystem operations, and a DefaultHostPathProbe adapter under src/engine/connection/host_mount/ uses std::fs and cap_std at the host trust boundary. The engine integration populates HostConfig.mounts with typed bollard Mount values (RPRIVATE propagation, non_recursive, explicit read_only) only when workspace.source = "host_mount". The plan also introduces a [mounts] configuration section with an allowlist and read-only default, additive FilesystemError variants for allowlist and write-probe failures, rstest/proptest unit coverage, rstest-bdd behavioural coverage, and a testcontainers-backed e2e scenario proving a real rootless engine can read and write the bound directory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Reviewer's GuideAdds a detailed ExecPlan document for roadmap step 4.2.2 that designs and constrains the future implementation of safe host-mounted workspaces, including config schema changes, a hexagonal domain/adapter split, validation rules, testing strategy, and rollout steps, but makes no code or behaviour changes yet. Sequence diagram for planning and applying a host-mounted workspacesequenceDiagram
actor Operator
participant CLI
participant Library
participant Probe as DefaultHostPathProbe
participant Engine as EngineConnector
participant Docker as Bollard
Operator->>CLI: Configure workspace.source=HostMount
CLI->>Library: plan_host_mount_workspace(AppConfig, Probe)
Library->>Probe: canonicalize(host_path)
Probe-->>Library: canonical_host_path
Library->>Probe: probe_writable(canonical_host_path)
Probe-->>Library: Result
Library-->>CLI: HostMountPlan
CLI->>Engine: create_container_async(HostMountPlan)
Engine->>Docker: create_container(HostConfig.mounts with Mount)
Docker-->>Engine: container_id
Engine-->>CLI: container_id
CLI-->>Operator: Container with host-mounted workspace
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Supersede the prior 4.2.2 draft on this branch with a revision that sharpens the security-critical details after fresh external research and a community-of-experts review. The overall shape is unchanged: a dedicated [mounts] config section, a hexagonal HostPathProbe split, a typed bollard Mount, a deny-by-default allowlist, and a testcontainers write proof. Substantive changes: - Probe writability through a single held cap-std capability opened from the canonical path, closing the in-process resolve-then-probe TOCTOU window the prior draft left open. - Add a CanonicalHostPath newtype so the containment check can only run on canonicalised paths. - State the residual cross-process mount-time race precisely and embed a verbatim threat-model boundary (operator must own the parent chain). - Expand the negative-coverage matrix: sibling-prefix trap, exact-root match, symlinked allowlist root, and a no-litter-on-failure assertion. - Adopt googletest and pretty_assertions, an insta denial-message snapshot, and a trybuild signature-stability fixture. - Justify and record proptest over kani/verus for the containment invariant. - Reaffirm the [mounts] section over a [sandbox] alternative. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
This draft PR carries the ExecPlan for roadmap step 4.2.2, "Implement safe
host-mounted workspaces", at
docs/execplans/4-2-2-safe-host-mounted-workspaces.md.The plan materialises host-mounted workspaces with an explicit deny-by-default
allowlist, symlink-resolving canonicalisation, symlink-escape rejection, and a
rootless write-permission probe, then attaches a hardened typed bind mount.
src/api/host_mount.rs, asingle-pass
HostPathProbedriven port, and a default adapter insrc/engine/connection/host_mount/. The engine adapter populatesHostConfig.mountswith a typedbollard::models::Mount(RPRIVATEpropagation,
non_recursive, explicitread_only) only whenworkspace.source = "host_mount".[mounts]configuration section and twoPODBOT_MOUNTS_*environmentvariables; additive
FilesystemErrorvariants for allowlist andwrite-probe failures;
rstest/rstest-bdd/proptest/testcontainerscoverage.The plan is in DRAFT and must be approved before implementation begins.
Revision (2026-06-18)
This revision supersedes the original 2026-05-29 draft on this branch after a
fresh round of external research and a community-of-experts design review. Key
upgrades: the writability probe now runs through a single held
cap-stdcapability (closing the in-process resolve-then-probe TOCTOU window); a
CanonicalHostPathnewtype makes non-canonical containment checksunrepresentable; the residual cross-process mount-time race (runc
CVE-2025-31133 class) and the operator's trusted-parent-chain precondition are
stated precisely and embedded as a verbatim threat-model boundary; the
negative-coverage matrix gains the sibling-prefix trap, exact-root match,
symlinked-root, and no-litter cases;
googletest,pretty_assertions, aninstadenial-message snapshot, and atrybuildsignature-stability fixtureare adopted; and the choice of
proptestoverkani/verusis justified.See the plan's Supersession note and Decision log for the full rationale.
Test plan
References
docs/podbot-roadmap.mdstep 4.2.2docs/execplans/4-2-2-safe-host-mounted-workspaces.md