Stored credentials, delivered by name: admin prompts, sudo, and the iPhone lock screen run unattended
Interceptor no longer stops at a password. interceptor macos secret register <name> opens a native box with two secure fields (Secure Event Input, so no event tap sees the keystrokes), a release gate picker, and a target list, and stores the value in the macOS keychain. From then on every surface references the secret by name: interceptor type <ref> --secret <name> in the browser, interceptor macos type --secret <name> in a native field, interceptor macos sudo --secret <name> -- <command> for root, interceptor macos authdialog fill --secret <name> --submit for the macOS administrator prompt, and interceptor ios type|keys|unlock --secret <name> for passcode sheets and the lock screen.
The daemon is the only process that ever holds a value, and only for the length of one delivery. It logs the action first (name only), checks the secret's target allowlist against the real target (sudo, macos:<bundleId>, browser:<host>, ios, any), resolves, and hands the value to exactly one delivery leg. A mismatch fails with target_denied before the keychain is read. Values never appear on argv, in the daemon log, the events file, monitor artifacts, MCP results, or interceptor diagnose; browser fields that received a secret are recorded as ***SECURE*** by the monitor.
Unattended by default, gated when you say so
- Releases are unattended unless the secret was registered with
--gate touchid(orbiometry), which asks the OS prompt: Touch ID, Apple Watch, or the Mac password when no sensor is available. The prompt names the secret, the target, and the requesting session. interceptor macos secret unlock <name> --for 30mtakes one prompt now and releases silently inside the window;secret lockcloses it.interceptor macos secret reveal <name>is always gated, prints only to a terminal, and is refused under--jsonand over MCP.interceptor macos secret set <name> --stdincovers headless registration; passing a value on argv is refused.- The administrator prompt filler handles both shapes macOS shows: Apple's Touch ID sheet (it presses "Use Password…" first) and the user-name + password form (it corrects the user name to the current user).
Storage and the iPhone
- On the signed build the bridge keeps items in the data-protection keychain under its own access group, so no keychain permission dialog can appear and a package upgrade keeps access. The bridge now embeds a Developer ID provisioning profile with the
keychain-access-groupsentitlement; ad-hoc dev builds and rebrands keep launching and fall back to the login keychain. interceptor ios unlock --secret <name>wakes the phone, swipes up, types the passcode into SpringBoard's passcode field, and waits for the lock state to clear;--probereports the lock screen without typing. It works while the on-device runner is resident, so the first unlock after a reboot is manual.ios typeandios keysfall back to SpringBoard when a Face ID or Settings passcode sheet owns the keyboard.ios press lockposts the Power key through the HID event path because the old XCTest lock call no longer locks on iOS 27.interceptor ios loginreads the Apple ID password from a hidden prompt or stdin and refuses--password; its session token store moved offsecurity add-generic-password, which exposed the token on the process list.- MCP tiers:
macos sudoandsecret revealare exec,secret rmandauthdialog filldestructive,secret list|statusread; the operator allowlist gates them as before.
Fixes that were built as 0.23.38 to 0.23.40 and never published
- Browser verbs exit non-zero on failure (#237). Every generic action (
back,forward,navigate,scroll,cookies,eval, and the rest) went through one shared print that never mapped a failed result to the exit code, sointerceptor backprinted Chrome's "Cannot find a next page in history." and exited 0. The guard now lives at that single print, the compound JSON path matches it, and an end-to-end test pins the contract against a real daemon. back/forwarddrive the page's own history when the tabs API refuses (#237). Chromium marks every entry an extension itself navigated to as skippable, sochrome.tabs.goBackrejected for pages Interceptor opened. Navigation now tries the API, falls back to a page-sidehistory.go(±1), and confirms the tab moved before reporting success.- Windowless profiles (#162). A connected profile with zero windows made
chrome.tabGroups.queryreject with "No current window" beforeopencould create one. The group helpers treat that as no groups,opencreates the window in the background,tabsanswers[], and tab-targeted verbs return an actionable hint. - Linux
install.shno longer matches itself (#172). The browser-running check anchored itspgreppattern to the executable, so--bravein the installer's own argv no longer reads as a running browser. - Stale extension snapshots are named (#241). Extensions report their version when they register;
interceptor diagnoseprints it next to the CLI's and namesinterceptor reload --context <id>when they differ. The reportedscreenshot-runner.jserror only comes from an extension older than 0.18.3. - Idle-spin watchdog (#216). A standalone daemon that burns CPU with no clients and nothing in flight now logs it, emits
daemon_spin_detected, and recycles itself after a minute so the next call gets a fresh process.INTERCEPTOR_SPIN_WATCHDOG=offdisables it.
Cross-surface version parity
Chromium MV3, Electron MV2, CLI, daemon, native bridge, Safari, and Windows installers all report 0.24.2. Browser-only and Full macOS packages are live on their separate Sparkle channels; Safari and Windows packages are attached below.
Verification
- 1,395 Bun tests passed, 9 platform skips, 0 failures, with 3,967 assertions
- 409 Swift bridge tests passed with 18 permission or platform skips
- All three TypeScript projects, the production build, and the capability-blind audit passed; the iOS runner test build succeeded
- GitHub CI passed on #245 after three automated review rounds; all 15 actionable review findings were fixed and every review thread was resolved
- Live on the installed build:
macos sudo --secret admin -- /usr/bin/idreturneduid=0; a signed package installed through Installer.app with the Touch ID sheet filled from the vault and again headless throughmacos sudo … installer; browser and native deliveries landed while wrong-host and wrong-bundle secrets were refused; secrets stored on 0.24.0 survived the upgrade with no keychain prompt; the daemon log, events file, metadata file, bridge log, monitor artifacts, anddiagnoseoutput contained no value - Browser, Full, and Safari packages passed Developer ID signing, Apple notarization, stapling, Gatekeeper, and payload version checks; the Full package's bridge carries the embedded provisioning profile and
keychain-access-groupsentitlement - The Windows x64 and ARM64 installers passed outer signature and hash verification; x64 also passed install, verify, repair, and uninstall on a disposable Windows runner; both installers have GitHub attestations and were re-downloaded and re-verified from the draft release
- Public additions, expanded release payloads, appcast entries, release notes, and asset names were checked for internal planning markers, private filesystem paths, and personal data
- Live Sparkle downloads match the local notarized packages byte for byte
Implemented in #245. Closes #244; also resolves #237, #172, #241, and #216, and confirms the #162 fix.
Follows 0.23.37
This release retains the session-scoped browser groups from #243 (soft per-session groups for agent shells, hard-scoped explicit groups, --shared-group, and the idle sweeper) and Sparkle's observed update outcomes from #238.
Assets
- Interceptor-Browser-0.24.2.pkg: signed and notarized browser-only macOS installer
- Interceptor-Full-0.24.2.pkg: signed and notarized full computer-use macOS installer
- Interceptor-Safari-0.24.2.pkg: signed and notarized Safari extension installer
- Interceptor-Browser-0.24.2-windows-x64.exe: signed Windows x64 installer
- Interceptor-Browser-0.24.2-windows-arm64.exe: signed Windows ARM64 installer
- SHA256SUMS: checksums for all five installers