You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
No file-in path: --allow-host-path fails closed (correctly) and nothing replaces it, so network-disabled and non-trivial-payload are mutually exclusive #14
There is no supported way to get a file into a workspace.
export is one-way (workspace → host). --allow-host-path fails closed on
every host the Docker provider runs on. There is no put / copy / import
verb and no run --input. So the only way to deliver code is to inline it into
argv, which is bounded by ARG_MAX and written verbatim into the result package
and the host journal.
Measured, on headspace-cli 0.9.0 / docker 29.1.3 / Linux
$ headspace create --allow-host-path "$PWD" --json{"code": 3, "message": "policy cannot be satisfied by docker 29.1.3: filesystem scope ('/…') (engine docker 29.1.3 cannot restrict bind mounts)", "remediation": "host cannot satisfy: … -- request a lower limit or use a host/engine that supports it", "category": "policy_denied"}
To be clear: the refusal is right. The flag's own help says it fails closed
on a host that cannot enforce the scope, and Docker cannot. Failing closed
rather than handing over an unrestricted bind mount is exactly the posture that
makes headspace worth using. This issue is not asking for that to be relaxed.
The gap is that failing closed leaves nothing in its place, so "run my
harness in a bounded workspace" has no path that does not go through argv.
Why argv is not an adequate substitute
It does not scale. A multi-file harness plus its fixtures does not fit in
a command line, and ARG_MAX is a hard ceiling, not a soft one.
It reads badly in the result package. The nine-section package is built to
return compact evidence; a base64 blob in provenance.inputs is the
opposite of that.
What we would use
A copy-in that is the mirror of export, and inherits its discipline:
headspace put <ws> <host-path> <workspace-path>, or run --input NAME=HOST_PATH, streaming through the same .partial-then-atomic-rename path artifacts.py already implements for the outbound direction, digesting during
the copy.
Record path and digest in provenance, never contents — that is what keeps
the result package compact and keeps a copied-in secret out of the journal.
Bounded by the workspace's existing storage-bytes budget, so it cannot be
used to escape a declared ceiling.
The outbound machinery for this appears to already exist; this is asking for it
to run in the other direction under the same rules, not for a new subsystem.
Current workaround, and why it is not free
We serve the payload from a short-lived HTTP server on the host bound to the
docker bridge address, and run a one-line fetch-and-exec. It works. Its costs:
it requires --network enabled, so a workspace that should be network-
isolated cannot receive its own code;
it requires the caller to stand up and tear down an HTTP server to move a
file, which is a lot of moving parts for "put this script in the box";
fetch failures surface as the job's failure rather than as a policy or
input error, so a delivery problem is diagnosed as a computation problem.
A caller who genuinely needs --network disabled — the default, and the posture
most adversarial or untrusted-code use cases actually want — has no workaround
available at all. That combination is what makes this feel like a gap rather
than an inconvenience: network-disabled and non-trivial-payload are mutually
exclusive today.
Context
Filed from agentculture/embodiment, alongside #13, about there
being no way to pass a secret into a workspace without argv recording it. They
are independent features — a copy-in would not solve the secret problem, and an
env flag would not solve this one — but a caller trying to run a real harness
hits both at once. Happy to test a branch.
The gap
There is no supported way to get a file into a workspace.
exportis one-way (workspace → host).--allow-host-pathfails closed onevery host the Docker provider runs on. There is no
put/copy/importverb and no
run --input. So the only way to deliver code is to inline it intoargv, which is bounded by
ARG_MAXand written verbatim into the result packageand the host journal.
Measured, on headspace-cli 0.9.0 / docker 29.1.3 / Linux
To be clear: the refusal is right. The flag's own help says it fails closed
on a host that cannot enforce the scope, and Docker cannot. Failing closed
rather than handing over an unrestricted bind mount is exactly the posture that
makes headspace worth using. This issue is not asking for that to be relaxed.
The gap is that failing closed leaves nothing in its place, so "run my
harness in a bounded workspace" has no path that does not go through argv.
Why argv is not an adequate substitute
a command line, and
ARG_MAXis a hard ceiling, not a soft one.result.outcome_summary,result.provenance.inputs[],~/.headspace/workspaces/<ws>/journal.jsonlandstate.json— measured, sameprobe as No way to pass a secret into a workspace: argv is the only channel, and argv is recorded in four places #13. Serialising a source file through argv means
the source is now duplicated into the crash journal.
return compact evidence; a base64 blob in
provenance.inputsis theopposite of that.
What we would use
A copy-in that is the mirror of
export, and inherits its discipline:headspace put <ws> <host-path> <workspace-path>, orrun --input NAME=HOST_PATH, streaming through the same.partial-then-atomic-rename pathartifacts.pyalready implements for the outbound direction, digesting duringthe copy.
the result package compact and keeps a copied-in secret out of the journal.
storage-bytesbudget, so it cannot beused to escape a declared ceiling.
The outbound machinery for this appears to already exist; this is asking for it
to run in the other direction under the same rules, not for a new subsystem.
Current workaround, and why it is not free
We serve the payload from a short-lived HTTP server on the host bound to the
docker bridge address, and
runa one-line fetch-and-exec. It works. Its costs:--network enabled, so a workspace that should be network-isolated cannot receive its own code;
file, which is a lot of moving parts for "put this script in the box";
input error, so a delivery problem is diagnosed as a computation problem.
A caller who genuinely needs
--network disabled— the default, and the posturemost adversarial or untrusted-code use cases actually want — has no workaround
available at all. That combination is what makes this feel like a gap rather
than an inconvenience: network-disabled and non-trivial-payload are mutually
exclusive today.
Context
Filed from
agentculture/embodiment, alongside #13, about therebeing no way to pass a secret into a workspace without argv recording it. They
are independent features — a copy-in would not solve the secret problem, and an
env flag would not solve this one — but a caller trying to run a real harness
hits both at once. Happy to test a branch.