Skip to content

feat(cli): ship the terminal client for macOS in every release - #48

Merged
mahype merged 3 commits into
mainfrom
feat/cli-release-macos
Sep 28, 2026
Merged

mahype merged 3 commits into
mainfrom
feat/cli-release-macos

Conversation

@mahype

@mahype mahype commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Why

The terminal client (torromail) built on macOS but could not store a secret there: the platform store fell through to secret-tool, which a Mac does not have. Releases also shipped it only for Linux and Windows.

What

  • torromail-keychain (new, macOS only): creates keychain items with the same access list the app's teamScopedAccess() uses — any binary signed by the TorroMail team reads them without a dialog. It is the one crate allowed unsafe, confined to its sys module; the workspace still forbids it everywhere else. An unsigned build never replaces an item it cannot read, because only it could read the replacement.
  • torromail-control: KeychainStore is the macOS platform store.
  • torromail-tui: keychain dialogs are off for the whole run (as in the server). The background check installs a launchd agent on macOS (com.torromail.check, every 15 minutes). Notifications go through Notification Center.
  • Release: scripts/build-cli-macos.sh builds torromail + torromail-mcp universal, signs them with the Developer ID under the hardened runtime, has them notarized and packs torromail-<version>-universal-macos.tar.gz. The existing macOS release job runs it, and the publish step now requires a download for every system (macOS, Linux x86_64 and aarch64, Windows).
  • scripts/install-macos.sh installs a signed local build. README, RELEASING.md and AGENTS.md are updated.

Verification

  • cargo test --workspace --locked: all 41 suites pass. There is a new launchd test for macOS.
  • Real keychain, signed with the team's development identity:
    • A second binary reads what the first one wrote without a dialog, also under the hardened runtime.
    • Items the app created (mail passwords, client-key-*) are readable.
    • An unsigned binary is refused without a dialog.
  • torromail check with the installed build logged into all 6 real accounts via the app's keychain items.
  • scripts/build-cli-macos.sh ran end to end locally with NOTARIZE=0: universal binaries, Team ID in the signature, smoke test, tarball.
  • Not verified yet: notarization inside GitHub Actions. That only runs on a tag, so a -rc tag after merge is the safe first run.

🤖 Generated with Claude Code

mahype and others added 3 commits September 25, 2026 09:40
The terminal surface built on macOS but could not keep a secret there: the
platform store fell through to secret-tool, which a Mac does not have. It now
uses the keychain with the app's own access list — any binary signed by the
TorroMail team reads the item without a dialog — so the app, the server and
the terminal client share passwords and client keys.

- torromail-keychain: new crate mirroring the app's teamScopedAccess(). It
  is the one crate allowed unsafe, confined to its sys module; the rest of
  the workspace still forbids it. An unsigned build never replaces an item
  it cannot read, since only it could read the replacement.
- torromail-control: KeychainStore as the macOS platform store.
- torromail-tui: keychain dialogs off for the run; the background check
  installs a launchd agent on macOS; notifications via Notification Center.
- Release: scripts/build-cli-macos.sh builds torromail and torromail-mcp
  universal, signs them with the Developer ID under the hardened runtime,
  notarizes and packs torromail-<version>-universal-macos.tar.gz. The macOS
  release job runs it, and publishing now requires a download for every
  system.
- scripts/install-macos.sh installs a signed local build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mahype
mahype merged commit 4075ec7 into main Sep 28, 2026
3 checks passed
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