Skip to content
This repository was archived by the owner on Oct 24, 2026. It is now read-only.

docs: managed patch signing, with its threat model, and a changelog entry - #762

Closed
eseidel wants to merge 2 commits into
mainfrom
docs/managed-patch-signing
Closed

eseidel wants to merge 2 commits into
mainfrom
docs/managed-patch-signing

Conversation

@eseidel

@eseidel eseidel commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Why

The next CLI release (1.6.132, target Mon 2026-10-26) signs every new release by default with a key Shorebird manages for the org (Google Cloud KMS), and Shorebird signs patches server-side. That closes the hole where anyone able to tamper with an app's network traffic (for example with a fraudulent TLS certificate from a compromised CA) could serve it a patch. The patch signing page still says signing is optional and needs your own key, so it would be wrong on launch day.

This PR:

  • Patch signing page: a three-mode overview (managed default, self-managed, unsigned), a Managed signing section (how to turn it on, how it works, patching rules, what happens if signing is unavailable), a threat model table saying plainly what managed signing does and doesn't protect against compared with self-managed and unsigned, switching to your own key, and --no-patch-signing. The existing guide is now under Self-managed signing; "Test and verify signed patch" moves up a level since it applies to both.
  • Changelog entry "New releases are signed by default" (CLI 1.6.132, 2026-10-26).
  • Rollback, System Architecture, Code Push guide and Security Tools pages: their patch-signing text now says signing is on by default, so the site tells one security story.

What could go wrong

  • The docs describe CLI behavior from shorebird#4161 (not merged yet): the flag is --no-patch-signing (the PRD said --no-sign), and the version is 1.6.132. If either changes before release, this needs a matching edit; I'll check at landing.
  • A pending decision (step 3755) may limit managed signing by default to some Flutter versions and change the default verification mode. The page doesn't claim a version range or change the Trade-offs section, so it stays true either way, but may need a line added once that's decided.
  • Console signing status isn't mentioned, since that work is still held.

Screenshots

Intro with the three modes:

Threat model table:

Changelog entry (expanded):

Landing

Held until Shorebird CLI 1.6.132 (managed signing on by default) is released, so the docs don't describe a default users don't have yet. At that point I'll check the version, date, and flag name match what shipped, and that "You don't need to change your Flutter version" (patch signing page and changelog) still holds after step 3755 decides on any Flutter version gate, then land.

🤖 Generated with Claude Code

…ntry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eseidel

eseidel commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Adversarial review (separate agent, no context from the author; checked against shorebird#4161 and _shorebird#4133/#4146/#4147)

No blockers. Verified: --no-patch-signing (release only, conflicts with key flags), release fails closed when the key fetch fails, patch refuses --public-key-path/--public-key-cmd/--private-key-path/--sign-cmd on managed releases, 1.6.132 minimum for patching managed releases (426), server fails closed on signing, summary line text, all anchors resolve.

  1. should-fix code-push-guide.mdx:302-325, system-architecture.mdx:188-190, security-tools.mdx:21-24 (untouched): still say patches are signed only with a key you control / "only you can change your app", contradicting the new default and threat model.
  2. should-fix changelog/managed-patch-signing.md:24: "Releases made before this stay unsigned" is wrong for customers who already sign with their own key.
  3. should-fix patch-signing.mdx:90: the only GFM footnote on the site adds a "Footnotes" entry to the page TOC and renders at the very bottom, after the KMS examples.
  4. should-fix patch-signing.mdx:251-254: "This works the same for managed and self-managed" but the suggested negative test (patch without / with a different private key) can't be done on a managed release.
  5. should-fix (policy) patch-signing.mdx:71-74: advising --no-patch-signing when signing is unavailable runs against _shorebird#4133's deliberate choice not to suggest opting out; at minimum say the release stays unsigned for good.
  6. should-fix (conditional) patch-signing.mdx:29, changelog:19: "You don't need to change your Flutter version" would become false if step 3755 adds a Flutter version gate; drop it or put it on the landing checklist.
  7. nit patch-signing.mdx:67-68: "stops before building" isn't true on CI without --release-version (a speculative build runs first); "before uploading" always holds.
  8. nit :53: key is created on first key fetch (including --dry-run), not first release.
  9. nit :51: "one signing key" per org is true today but the server supports app keys and rotation.
  10. nit :54: "can't be exported, by Shorebird or anyone else" overreaches; SOFTWARE-protection KMS keys, Google is covered by the table's Google row.
  11. nit :87: Self-managed "Protected" against a Google Cloud compromise isn't true if the customer's own key is in GCP KMS (an example on this page).
  12. nit :23: mode is fixed per platform build, not per release; one release version can mix modes across platforms.
  13. nit :57: "builds the patch against that release's key" is unclear.
  14. nit changelog title: "Patches are signed by default" overstates; patches to existing releases aren't signed. "New releases are signed by default".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eseidel

eseidel commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Responses to the adversarial review (fixes in the latest commit):

  1. Fixed: Code Push guide, System Architecture and the Security Tools card now describe signing as on by default, with self-managed keys as the way to keep Shorebird out of the trust base.
  2. Fixed: "Releases made before this without your own key stay unsigned".
  3. Fixed: footnote replaced by a sentence under the table; "Footnotes" no longer appears in the page TOC.
  4. Fixed: the negative test is now marked self-managed only, noting managed releases refuse such patches before they're published.
  5. Kept the advice, since Eric decided (2026-10-23, arc step 3757) that the user's own opt-out flag is the escape hatch when signing is unavailable; added that the release stays unsigned for good and only a new release turns signing back on.
  6. Kept: it's true today and is the launch's core message. Added it to the Landing checklist, to recheck after step 3755.
  7. Fixed: "stops before uploading".
  8. Fixed: "the first time shorebird release needs one" (covers --dry-run).
  9. Fixed: "Shorebird creates a signing key for your organization", without claiming exactly one.
  10. Fixed: "Cloud KMS doesn't let anyone export it, including Shorebird."
  11. Fixed: "Protected, unless your key is in Google Cloud".
  12. Fixed: "fixed when you release each platform".
  13. Fixed: "builds the patch with the same public key, so it matches the release".
  14. Fixed: retitled "New releases are signed by default".

Build, Vale and cspell pass; screenshots in the description are updated.

@eseidel

eseidel commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Moved to shorebirdtech/_shorebird#4184; docs now live in the monorepo.

@eseidel eseidel closed this Oct 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant