feat(protocol): attach private artifacts to file inputs - #169
Conversation
|
Merge after #170. Both PRs started from the same Architecture decision numbering: this PR is 23. #170 is 22. |
Agents can copy a local fixture into the private artifact store (`artifacts add` / `artifact.add`) and attach it to a file input (`upload`) by basename. File bytes never travel on the socket. Linux Chromium uses DOM.setFileInputFiles; WebKit returns UNSUPPORTED_CAPABILITY. Downloads stay denied. Closes #168
66428d2 to
a9b1c4e
Compare
|
Rebased onto current main (settings, auth, isolated sessions). Mergeable with main. If #170 merges first, this will likely need another rebase because both still touch CLI/protocol/docs. |
SarthakWade
left a comment
There was a problem hiding this comment.
This PR must not merge in its current design because it crosses the repository's local-file security boundary.
artifact.add is an agent and MCP protocol command that accepts any absolute regular file readable by the host. Only the destination basename and extension are constrained. An agent can therefore ingest a sensitive local file under an allowed .txt or .json name, navigate to a page, and attach it through Linux upload. Keeping bytes off the socket does not prevent exfiltration. This directly contradicts SECURITY.md, which classifies reading outside the artifact store as a vulnerability, so architecture decision 23 needs to be revised before implementation. Ingest should require trusted user mediation, be limited to user-approved roots with descriptor-relative no-follow access, or remain outside the agent/MCP surface.
Additional blockers are an unbounded read before the 5 MiB check and ambiguous completion semantics after DOM.setFileInputFiles. There are also target-state and capability-hint gaps described inline. The existing pathname handoff to Chromium is not identity-pinned after the store lock is released; while same-UID filesystem access is a documented limitation, the design should explicitly document that remaining race or introduce a brokered descriptor-safe handoff where the engine permits it.
GitHub currently reports the branch as mergeable with no conflicts and directly based on current main. The required Linux E2E check is failing at authentication-storage-state with a closed DevTools pipe before the new upload scenario runs, so this head has no successful Linux upload E2E result. Other checks passed and macOS E2E was skipped.
Ingest is a local CLI/TTY operator path, never a protocol or MCP command. Upload still attaches store basenames only. Bound the ingest reader, treat successful CDP attachment as completion, revalidate file inputs before attach, and suppress WebKit upload hints.
|
Addressed the CHANGES_REQUESTED review on P0 P1 P1 P2 P2 Protocol tests 60/60, MCP stdio, |
# Conflicts: # apps/headless/Tests/fixture-server.mjs # apps/headless/Tests/linux-e2e.sh # docs/roadmap/architecture-decisions.md
SarthakWade
left a comment
There was a problem hiding this comment.
Re-reviewed the final implementation and verified the complete CI matrix. Uploads are limited to validated files already inside the private artifact store, target state is revalidated, Linux pins the validated DOM object through attachment, and the remaining same-UID pathname limitation is documented. Protocol, runtime, Linux E2E, macOS build, and macOS E2E checks all pass.
Summary
Adds
headless uploadfor attaching a file that already exists in Headless's private artifact store to a visible, enabled file input. Agents may reference only a validated artifact basename.Arbitrary local-path ingest is intentionally not exposed through CLI, protocol, or MCP. File bytes and source paths never enter protocol parameters, logs, flows, snapshots, diagnostics, or errors. Downloads remain denied.
Security
Trusted user-mediated staging of new local files remains tracked by #168 and is not completed by this PR.
Verification