Skip to content

fix(file): bind copied workspace files to their source by storage key - #9209

Merged
waleedlatif1 merged 1 commit into
stagingfrom
fix/file-copy-secret-provenance
Oct 18, 2026
Merged

waleedlatif1 merged 1 commit into
stagingfrom
fix/file-copy-secret-provenance

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • The File operations resolved a selected workspace file's storage key through the VFS reference resolver, which only understands ids, paths, and names. A key never resolved, so a copy (write with fileInput), compress, decompress, or content read of a workspace file passed as a file object lost its source identity. The copy was stored with unknown secret provenance (an ERROR on every such write), and later reads of the copy were refused. Regressed when the operations moved in-process and the key-metadata lookup was replaced by the reference resolver.
  • Adds resolveWorkspaceFileStorageKey to the workspace-file reference application module. It maps the key to its current workspace row, requires the asserted workspace, authorizes that row by id under the caller's operation policy, and returns it only if the row's current key is the key whose bytes are read. Anything else is not_found, which callers already treat as "unbound", so they fail closed.
  • bindSelectedContentFile now gates on the key's storage prefix instead of the optional context field, so a block-reference file that has no context also binds. File picker values were already getting context inferred from the key.
  • manage_sharing had the same bug for picker values ({ name, path, key }) and always failed with "File not found". It now resolves through the same helper under the share policy.
  • Fail-closed cases behave as before: copying another member's file that has recorded secrets stays unknown; a superseded version key and another workspace's key are still refused.

Type of Change

  • Bug fix

Testing

  • New apps/sim/lib/internal/file/write-copy-provenance.integration.ts (real Postgres plus local storage, run through the real file operation, application authorization, metadata and provenance sidecars): 8/8 pass.
    • Red on pre-fix operations.ts: 5 failures. A clean copy came out unknown instead of exact for block references, block references without a context, and picker values. A copy of the caller's own secret-bearing file was unknown instead of exact with those entries. manage_sharing with a picker key returned 404.
    • Red with only the old context gate restored: the block-reference-without-context case fails.
    • Green on both trees (fail-closed guards): another member's secret-bearing source stays unknown; a superseded version key and a foreign-workspace key are refused (404).
  • Updated the one unit test that mocked the resolver into accepting a raw key. lib/internal/file/, lib/workspace-files/application/, tools/file, lib/execution/payloads, the tool-execution suite, and the suites that use the reference mock all pass (813 tests).
  • bun run lint, check:boundaries, check:comment-hygiene, check:test-patterns, check:explicit-any, check:file-names, check:source-conventions. Full type-check and audits are left to CI.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

The File operations resolved a selected workspace file's storage key through
the VFS reference resolver, which only understands ids, paths, and names, so a
key never resolved. Every copy, archive, or content read of a workspace file
given as a file object lost its source identity: the write recorded the copy's
secret provenance as unknown and later reads of the copy were refused. Picker
values passed to manage_sharing failed with "File not found" the same way.

Resolve the key to its current workspace file row first, then authorize that
row by id under the operation's policy, and bind only when the row's current
key is the key whose bytes are read. Gate on the key's storage prefix instead of
the optional `context` field so a block reference without one also binds.
@vercel

vercel Bot commented Oct 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 18, 2026 11:15pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Fixes workspace file copies and picker-based sharing by resolving storage keys to authorized file records.

  • File copies keep the source’s recorded secret history.
  • File sharing accepts a workspace file picker selection.

Review checks were static; tests were not run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Selected storage key] --> B[Find active workspace metadata]
  B --> C{Matches requested workspace?}
  C -- No --> D[Not found]
  C -- Yes --> E[Authorize file ID for requested operation]
  E --> F{Current key matches?}
  F -- No --> D
  F -- Yes --> G[Return authorized file record]
  G --> H[Bind copy provenance]
  G --> I[Apply sharing checks]
Loading

Reviews (1) · Last reviewed commit: "fix(file): bind copied workspace files t..." · Reviewed by Greptile

@waleedlatif1
waleedlatif1 merged commit 9f7b00d into staging Oct 18, 2026
53 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/file-copy-secret-provenance branch October 18, 2026 23:30

This branch was previously deployed

1 inactive deployment
Preview — 97e7a593 Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant