fix(server): load PR uploads from SSO organizations#21632

open3
batch-07-pr-media/context
batch-07-pr-media/sso
opened5d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 39m ago

GitHub returns an HTML sign-in page for some PR uploads in organizations enforcing SAML SSO. The media proxy rejects that response, leaving images and videos unavailable.

Resolve GitHub upload media in an asset-domain Effect service. On the HTML response, render the upload through GitHub's Markdown API in its repository context and fetch the returned signed URL without a bearer token. Use the upload's repository for legacy URLs, otherwise the PR context carried by the lower layer, with checkout fallback for older clients. Cache successful signed URLs within the service, bounded by time and size and keyed by account, repository, and upload; refresh a cached 403. Preserve media bytes, ranges, response policy, and login behavior. Supply the service through request middleware once per application router.

Rebuilt from @cbangera2's signed-URL fallback in #19191. Its endpoint, signed-host handling, HTML decoding, legacy URL support, and bounded cache intent are retained. The global URL-only cache and checkout-only enterprise-context assumption were replaced to match current architecture and the human EMU finding.

Depends on #21631.

Independent Opus and Sol reviews completed two full-stack rounds; the final round found no code defects.

Verification: 44 passing / 4 expected SSO failures became 48 passing server tests; the 3 mobile preview tests also pass. Related service suites and scoped server types pass, as do targeted lint/format with one existing test warning. Scoped Knip has unrelated existing export findings and none in changed files. Independent reviews found a request-provider regression and legacy context precedence issue; both are addressed without adding redundant test cases.

Before/after protocol and runtime proof: the full production dev server, including actual server.ts composition and the asset GET route, returns exact binary bytes with 200 and a cached range request with 206, one Markdown render, and no authorization on signed-host requests. The RPC schema and capability minting/resolution are real; only external GitHub responses are mocked. The initial wrong request-provider composition reproduced HTTP 500 and was corrected.

A real SAML/EMU account and GitHub's signed response remain unverified. Also unverified: full app media UI, macOS, Windows, Electron desktop, iOS, Android, native playback, and remote/relay/tunnel execution. No layout change. Human approval of the authentication-sensitive external calls and live enterprise-account verification remain merge gates. No merge is planned.

CI/review status: All executed current-head CI jobs passed, including lint, build/types, package tests, all eight server shards and the latest native fingerprint job. Web and release smoke were skipped for this layer; an earlier redundant fingerprint job was cancelled, then superseded by success. CI run. Macroscope requires human approval of the authenticated Markdown call and signed-URL cache; this remains a merge gate. No unresolved review threads at the current snapshot.

Implemented with GPT-6 Astra and GPT-6.1 Sol on Codex through T3 Code; independently reviewed by Claude Opus 5.5 and GPT-6 Sol.

Checks

All checks passed

Added 3 commits

  • fix(server): provide the media service to asset requests5bcf33f
  • fix(server): prefer the repository named by legacy uploads5ebb9aa
  • fix(server): load SSO-protected PR uploads through signed URLsbe56058
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval β€” This changes the production GitHub-media proxy to use repository-context Markdown rendering, credentials, presigned URLs, and bounded caching when direct uploads return SSO HTML. Mocked tests cover the main flows, but the authentication-sensitive external calls and broad request wiring merit human review.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

βœ… Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wireβ€”4.9 KiBβ€”6.8 KiBβœ…
CodexThread snapshot wireβ€”3.8 KiBβ€”4.9 KiBβœ…
CodexLive turn WebSocket wireβ€”1.2 KiBβ€”2.0 KiBβœ…
CodexLive turn WebSocket decodedβ€”20.8 KiBβ€”29.3 KiBβœ…
CodexLive turn messagesβ€”1β€”8βœ…
ClaudeTotal thread wireβ€”5.0 KiBβ€”6.8 KiBβœ…
ClaudeThread snapshot wireβ€”3.8 KiBβ€”4.9 KiBβœ…
ClaudeLive turn WebSocket wireβ€”1.2 KiBβ€”2.0 KiBβœ…
ClaudeLive turn WebSocket decodedβ€”21.2 KiBβ€”29.3 KiBβœ…
ClaudeLive turn messagesβ€”2β€”8βœ…

Baseline: unavailable Β· PR result: 5ebb9aa Β· Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack β†’

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 7bb569c7-68a9-4794-8113-0593435e3cde
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 2503bd508df4fa5f827f6c23cef252fc65596134 and 5ebb9aa198f9d91824f6cc723c649421520ede6b.

πŸ“’ Files selected for processing: 4
  • apps/server/src/assets/AssetAccess.test.ts
  • apps/server/src/assets/GitHubMediaFetch.ts
  • apps/server/src/http.ts
  • apps/server/src/server.ts

Limit details: You’ve used all 10 included reviews currently available.

πŸ“ Walkthrough

The change adds a scoped service for GitHub media fetching. It resolves repository context for eligible uploads, renders Markdown to obtain signed private image URLs, and caches qualifying media URLs. The HTTP route provides the service and logs the upstream hostname and error tag on fetch errors.

Changes: GitHub private media fetching

Layer / File(s)Summary
Fetch contract and redirect handling
apps/server/src/assets/GitHubMediaFetch.ts
The module defines the fetch service contract and tagged error. It validates initial URLs and redirects, limits redirect hops, and wraps HTTP client failures.
Signed URL rendering
apps/server/src/assets/GitHubMediaFetch.ts
The service renders eligible GitHub uploads as Markdown. It accepts extracted URLs only when they meet the HTTPS, host, and jwt query requirements.
Cached fetch workflow and route integration
apps/server/src/assets/GitHubMediaFetch.ts, apps/server/src/http.ts, apps/server/src/server.ts, apps/server/src/assets/AssetAccess.test.ts
The service reads credentials per request, resolves repository context, and caches qualifying signed media URLs. The server provides the service to the HTTP route. Tests cover repository selection, range requests, and cache refresh cases. Fetch errors still return the existing 502 response; route warnings now record the upstream hostname and error tag.

Priority: βž– Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant HTTPRoute
3 participant GitHubMediaFetch
4 participant GitHubREST
5 participant HTTPClient
6 HTTPRoute->>GitHubMediaFetch: Fetch asset with request headers
7 GitHubMediaFetch->>GitHubREST: Render eligible upload as Markdown
8 GitHubREST-->>GitHubMediaFetch: Return rendered Markdown
9 GitHubMediaFetch->>HTTPClient: Fetch signed media URL
10 HTTPClient-->>GitHubMediaFetch: Return media response
11 GitHubMediaFetch-->>HTTPRoute: Return media response or null

Suggested reviewers: maria-rcks

Merge Risk: βšͺ Minimal Β· up to 5ebb9

This change makes PR uploads in SSO-enforced GitHub organizations load by fetching signed media URLs. No concrete merge-blocking defect was found. Live enterprise-account verification remains a pre-merge step.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main change: enabling server-side loading of pull-request uploads from SSO-enforced organizations.
Description checkPassedThe description covers the problem, implementation, verification results, dependencies, limitations, and remaining approval gates. It does not use a separate Scope and approval section, but it provide…
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description covers the problem, implementation, verification results, dependencies, limitations, and remaining approval gates. It does not use a separate Scope and approval section, but it provides the required scope and approval context elsewhere.

✨ Finishing Touches
πŸ“ Generate docstrings
  • Commit to this branch
  • Create a new PR
πŸ§ͺ Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Usage-based review receipt

Note

This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.

Comment @coderabbitai help to get the list of available commands.