Public Access
365954c5412e151f77668b14c97af832548b1f54
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
597e5ae016 |
Take the release credentials off the command line, where anyone could read them
Three scripts prompted for a secret with Read-Host -AsSecureString or read -s, said in a comment that it therefore never lands in shell history, and then wrote it straight into the arguments of the next process. The comment was true and was answering the wrong question. A command line is not private: on Windows one call to Get-CimInstance Win32_Process hands every argument of every process running as this user to anything that asks, /proc/<pid>/cmdline is world-readable on Linux, and process-creation auditing and EDR agents keep their own copy either way. The values were the Android release signing key's passwords and the forge token — between them the whole capability to ship an update that every installed copy will fetch and run, which ADR 0011 rule 1 and ADR 0013 go to some length to keep off a runner and which was then left in a process listing on a desk. Both replacements are documented features of the tools rather than tricks. The Android passwords use .NET for Android's env: prefix, which puts the name of a variable on the command line and lets MSBuild read the value out of the environment itself. Set immediately before the build and cleared in a finally, so a failed signing does not leave them in the shell for whatever runs next, and -nodeReuse:false so no persistent MSBuild worker outlives the call still holding the inherited copy in its own environment. That prefix is unsupported when AndroidPackageFormat is aab, and the failure is silent — the package would be signed with the literal string "env:DODOSSH_ANDROID_STOREPASS" as its password. So the format is read back and the build stops if it is ever changed, in the same shape as the versionCode guard a few lines above: a wrong release refused here rather than discovered later on somebody's phone. vpk documents VPK_TOKEN as --token's environment fallback, so the flag is simply gone from both desktop scripts and the token never becomes an argument at all. Unset afterwards on the failure path too, which on macOS needs the exit status captured rather than a bare || stop_with. release-macos.sh had the same fault and was missed when the other two were first reported. Its Apple credentials were already right — a notarytool keychain profile rather than --password — and only the forge token was exposed. What this does not claim: an environment block is readable by a process holding rights over this one, the same as its memory is. The comments say so rather than implying the values are now safe. What is bought is real and narrower — off the command line, out of every process listing, out of the audit trail, and out of any log that echoes the invocation. Both PowerShell files parse, all three shell scripts pass bash -n, the AndroidPackageFormat probe evaluates and answers empty so the guard passes, and dotnet build accepts -nodeReuse:false. The signing itself is not exercised here: it needs the release keystore, which by design is not on this machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
890a5f2246 |
Give the desktop a macOS head, signed from the first release
The same application, the same Velopack and the same two-phase person-run release as Windows, with four things forced to differ. Signing is a precondition rather than an improvement: Gatekeeper refuses an un-notarized download outright instead of warning about it, so there was never the "unsigned for now" that ADR 0013 decision 8 argues for on Windows, and release-macos.sh refuses to start without the identities. The packaging split is narrower than it first looked, and the old claim at the foot of ci.yml is why it was worth checking rather than assuming. vpk cross-compiles when told to: 'vpk [osx] bundle' builds a real .app on any platform, and CI now publishes osx-arm64 and bundles it on every main and tag build, which is what catches a restore graph with no macOS native asset. There is no '[osx] pack' off a Mac, and that part is correct — pack drives codesign, notarytool and stapler, which exist nowhere else. The dylib signing loop in the script looks redundant beside vpk's own pass and is not. vpk signs with 'codesign --deep', which is the shape Apple documents as wrong for nested code, and platform-flags has recorded a notarization rejection that names no file since before any of this existed. Signing each native binary inside-out first leaves that pass nothing to get wrong. MacDeviceKeyStore reaches ADR 0007's conclusion through different hardware: a P-256 key in the Secure Enclave under an access control requiring user presence, so the platform enforces the gate rather than this process — which is the whole point of that ADR's amendment. The enclave holds no other kind of key, hence ECIES where Windows uses RSA-OAEP, and the shape that falls out is better than the Windows one: sealing needs only the public half and is silent, so only unlock prompts. IsSupported probes rather than infers, because three ordinary Macs answer no — an Intel machine without a T2, one with no login password, and every unsigned development build, since enclave keys need a signing identity. Two decisions worth stating because they are reversible. arm64 only: a second channel is small work and nobody here has an Intel Mac to walk Phase 18 on, and an x64 package would be the only artefact in this repository reaching users unverified. And the pack id stays DodoSSH.Desktop even though vpk names the bundle after it, so /Applications holds DodoSSH.Desktop.app: decision 2's reasoning binds harder here, because a pack id of DodoSSH would put Velopack's install root on top of ClientPaths.DataDirectory and let an uninstall take the user's un-synced outbox with it. CFBundleDisplayName puts the product name back in front of a person. Measured rather than assumed, since none of it is obvious: the publish and the bundle were both run, LSMinimumSystemVersion is 12.0 because that is the minos in the apphost's own LC_BUILD_VERSION, and vpk copies a custom Info.plist verbatim with no substitution at all — which is why the plist is a template the script renders and not a committed file. What is not done is the half that needs the hardware. There is no macOS runner, so nothing past "it bundles" has ever run. Phase 18 is the whole of the verification, and the two checks most likely to fail are the terminal against WKWebView and the enclave interop, neither of which has executed once. |