Public: anyone can read this; the crew can change it.

A private app answers to its writers and crew: reading the repository is not a key to the app, its previews or its terminal #743

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

Closes #620.

shipped production is serving it for issue #620 — its issue is already done deploy 5f89d5b

opened this

Closes #620.

What changed

  • One rule, canEnterApp (src/core/repos.ts): a public app is open to anyone. A private app answers only to people who can write the repository and to its crew. Reading the repository is no longer enough, so making a repository public changes nobody's way into its app.
  • Every way in asks it:

- the identity hand-off (openEnvUrl, used by /apps/open, the app page's Open, the API's …/app/:env/open and the terminal UI), where someone who may not enter gets not_found, the answer a stranger gets; - the terminal (runAppTty); - the proxy, which now asks again on every request whether the person a grant names may still enter, so a grant already issued stops working the moment its holder may not enter, instead of lasting out its twelve hours.

Previews follow their app through the same paths.

  • The settings page says what changes before you save. The visibility hint lists what becomes public (code, issues, pulls, run logs) and that a private app and its previews stay limited to writers. The app's Access hint and label now say "people who can write this repository". docs/APPS.md and docs/MCP.md say the same.

Tests (test/private-app.test.ts, in the gate; the refusing tests were written first and failed before the fix). Setup: a private app on a repository that is then made public.

  • A signed-in reader is refused production and every preview, through openEnvUrl, /apps/open and the API. The owner and the crew get through.
  • A grant already held by a reader is refused at the proxy, on production and on a preview host. A writer's grant still works.
  • An anonymous visitor is refused.
  • The terminal refuses a reader and an anonymous visitor, and lets the owner and the crew past its door.
  • The settings pages carry the new wording.

test/apps-adversarial.test.ts asserted the old contract (a signed-in stranger got a grant to a private app on a public repository). It now asserts the refusal.

Not in this pull: the issue's "anyone the owner names explicitly" (a member list) needs a new table. Writers already include organisation teams with write access, so this pull covers people through repository write access. A named-member list is a follow-up. The stored look images of private apps are #717.

🤖 Generated with Claude Code

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs