Skip to content

fix(files): refuse delegated version reads no provenance observer records - #8843

Merged
waleedlatif1 merged 1 commit into
stagingfrom
fix/chat-delegation-hardening
Oct 9, 2026
Merged

waleedlatif1 merged 1 commit into
stagingfrom
fix/chat-delegation-hardening

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • A version text read redacted secrets only when the caller's transport had installed a delivery observer. Chat's transports install one today, but the guarantee depended on how they are composed. readWorkspaceFileVersionText now refuses a delegated caller with no observer before loading any bytes, and the v2 file error policy maps that refusal to 503 SERVICE_UNAVAILABLE. Direct callers are unchanged
  • The version-history policy comment overstated the download rule. Download stays direct-only, but it is not a hard boundary for a writer: reverting to a version and downloading the current file reaches the same bytes, with provenance tracked at each step. Delete remains a real boundary, because a revert never purges history
  • Integration coverage for chat version access that was previously only probed by hand:
    • workspace pinning holds without the invocation scope (the delegated principal's own check)
    • the files.use capability is enforced
    • a version with unknown secret provenance is withheld
    • a secret stays redacted after Chat reverts to the version holding it

Type of Change

  • Bug fix

Testing

  • lib/workspace-files/__integration__/copilot-file-versions.integration.ts (real Postgres, local storage, Chat's in-process transports), 5 new cases, 10/10 pass:
    • a delegated version read through the in-process route with no file-read layer answers 503 and returns no secret. It fails with the new guard removed (200 with the raw secret)
    • a chat pinned to another of the user's workspaces gets 404 on list and revert without the invocation scope, whether the request asserts the file's workspace or the chat's
    • a member whose permission group hides Files is refused with PERMISSION_GROUP_CAPABILITY_BLOCKED
    • a version with unknown provenance answers 503 even with a registry
    • after Chat reverts to a secret-bearing version, a current-file read shows only [REDACTED_SECRET], and 503 without a registry
  • Existing file-versions.integration.ts (28) and copilot-permission-config.integration.ts pass; lib/workspace-files, app/api/v2/files, lib/api/server/routes unit suites pass
  • bun run lint, bun run type-check, bun run check:audits, root bun run test (one load timeout in lib/mothership/agent-cli/services.test.ts, which passes on its own)

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)

@vercel

vercel Bot commented Oct 9, 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 9, 2026 7:14am 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 9, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

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

Summary

Delegated version-text reads now require a delivery observer before loading file bytes. The file API returns 503 SERVICE_UNAVAILABLE when that observer is missing. Direct callers are unchanged.

  • Adds five integration cases for missing observers, workspace limits, Files access, unknown secret provenance, and redaction after a revert.
  • Clarifies why version downloads remain direct-only while reverting preserves secret provenance.
  • No actionable issues found. Tests were inspected, not run.
  • waleedlatif1 explicitly acknowledges that a writer can revert a version and download the current file; version download is therefore not a hard boundary for a writer.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Authorized version-text read] --> B{Delegated caller?}
  B -- No --> E[Load version and extract text]
  B -- Yes --> C{Delivery observer installed?}
  C -- No --> D[Return 503 without loading file bytes]
  C -- Yes --> F[Load version and its secret provenance]
  F --> G[Await delivery observer]
  G --> E
  E --> H[Return text to caller's transport]
Loading

Reviews (1) · Last reviewed commit: "fix(files): refuse delegated version rea..." · Reviewed by Greptile

@waleedlatif1
waleedlatif1 merged commit f7ef6ed into staging Oct 9, 2026
47 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/chat-delegation-hardening branch October 9, 2026 16:57

This branch was previously deployed

1 inactive deployment
Preview — 1556d78d Deployed Oct 9, 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