Feature/codesigning - #1
Merged
Merged
Conversation
First slice of the fastlane match replacement, chosen because it is the part nothing else can substitute for: generating a key pair, getting Apple to certify it, and keeping both halves. Apple never gives you a private key. You generate one locally, send only the public half inside a CSR, and Apple returns a certificate that vouches for it. So a certificate whose key is lost is dead permanently, and an expired certificate cannot be renewed at all: there is no such endpoint, only creating a new one, which means a new key and a new CSR. That is why the portal's Download button cannot rescue anybody, and why this command writes the key to disk before it calls Apple. Failing after the request would leave a certificate whose key we never persisted, which is unrecoverable; failing before it leaves an unused key, which costs nothing. The CSR must be RSA 2048. Apple rejects ECDSA, which is what most modern tooling emits by default. rcgen cannot generate RSA keys, so the key comes from the rsa crate as PKCS#8 PEM and rcgen re-parses it purely to produce the self-signature. The test asserts the result through openssl rather than through our own types, since checking our output with our own parser would prove nothing. It reads stdout and stderr together: macOS ships LibreSSL, which prints the verify banner to stderr while OpenSSL proper puts it on stdout, and reading one stream makes the test depend on which implementation the machine has. Key material is Zeroizing, Debug is hand-written to redact it, and the private key file is opened 0600 at creation rather than chmod'ed after, so it is never briefly world-readable. certificateContent stays out of the list output: it is large, and printing it invites pasting certificate bodies somewhere they should not go. Revoking asks for the id twice. It is irreversible and breaks every provisioning profile embedding that certificate for the whole team at once, including builds already running in CI, so it should be hard to do by accident and impossible to do by autocomplete. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGeEFM4hBGSZYXjFWguaWa
Two runners on purpose. The CSR tests verify our output through openssl rather than through our own parser, and the hosts ship different ones: ubuntu has OpenSSL 3, macOS has LibreSSL, and they disagree about which stream the verify banner goes to. That difference already cost a debugging round locally, so a single-host matrix would let the same class of bug through unnoticed. macOS is also where this crate's signing work has to run eventually, since keychain access exists nowhere else. fail-fast is off because when a test fails on exactly one host, that asymmetry is the most useful part of the report. The rustdoc job pays for itself immediately: it found a link to a `KeyPair` type that does not exist, in the paragraph explaining that a lost private key is unrecoverable. The intra-doc links carry real weight here, since the certificate module's warnings point at the csr module that explains them, and a broken one drops that thread silently. Also fixes a pre-existing unclosed `<key-id>` HTML tag in the CLI's help text, which rustdoc reads as a tag rather than a placeholder. openssl version is printed before the tests because it decides how the CSR verification behaves and changes under us whenever GitHub bumps runner images. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PGeEFM4hBGSZYXjFWguaWa
keypair34
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.