Skip to content

privacy: the dashboard sends your repo names to GitHub from the browser #100

Description

@pitimon

Found by an independent Fable review, verified against source.

What happens

dashboard/src/ui/dashboard/components/ProjectUsagePanel.jsx:70 calls, from the user's browser:

fetch(`https://api.github.com/repos/${repoId}`)

repoId is derived from the local project key — i.e. the repositories you work on, including private ones. dashboard/src/ui/components/HeaderGithubStar.jsx does the same for this repo's own star count.

There is a gate (shouldFetchGithubStars({ prefersReducedMotion, screenshotCapture })) but it gates on reduced-motion and screenshot-capture mode. It is not a privacy control and the user is never asked.

Why it matters

It contradicts the README's own privacy section, rewritten in #95:

  • README:154 claims avatars are "Fetched server-side so your browser doesn't contact them directly."
  • README:152 lists api.github.com only under "Quota chips + Limits page" — asking your provider about your own plan.

Neither covers a browser-side request whose URL path is the name of a repo you have checked out. Sending a private repo name to a third party is a different class of disclosure from fetching a public price list, and it is the one thing the product's headline claim is about.

Why it slipped

The outbound-call table in #95 was assembled by grepping src/ only. dashboard/src/ was never scanned, and both offending files live there. The claim was researched, just not exhaustively — which is precisely why it needs a validator rather than another careful read (#101, filed alongside this).

Options

  1. Route it through the existing avatar proxy (/api/avatar-proxy in src/lib/local-api.js, already host-allowlisted) so the browser talks only to loopback. Makes README:154 true as written. Note the repo name still reaches GitHub — from the local server rather than the browser — so the README must say so either way.
  2. Make it genuinely opt-in, default off, with a Settings toggle.
  3. Drop the enrichment. Star counts and owner avatars on a private-usage dashboard are decoration; the panel works without them.

My preference is 3 for ProjectUsagePanel (the feature earns little and costs the strongest claim in the product) and 1 or 2 for HeaderGithubStar, which only ever requests this public repo and discloses nothing about the user.

Whatever is chosen, the README outbound table must match it exactly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions