Skip to content

Commit 04dde43

Browse files
authored
fix(release): configure Speakeasy macOS signing (#34)
1 parent a26567d commit 04dde43

8 files changed

Lines changed: 54 additions & 24 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ jobs:
129129
cp target/aarch64-apple-darwin/release/kit stage/kit
130130
if [[ $SIGN_RELEASE == true ]]; then
131131
codesign --force --options runtime --timestamp \
132-
--identifier com.danielkov.kit \
132+
--identifier com.speakeasy.kit \
133133
--sign "$MACOS_SIGNING_IDENTITY" stage/kit
134134
codesign --verify --strict --verbose=2 stage/kit
135135
ditto -c -k --keepParent stage/kit "$RUNNER_TEMP/kit-notarization.zip"

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "kit"
3-
version = "0.1.97"
3+
version = "0.1.98"
44
edition = "2024"
55
rust-version = "1.94.0"
66
publish = false

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ target/release/kit tui --mcp-config mcp.json \
558558
On macOS, `.cargo/config.toml` routes `cargo run` through a runner that signs the
559559
fresh debug binary before executing it. Set `KIT_CODESIGN_IDENTITY`, or put the
560560
certificate name in the gitignored `.kit-codesign-identity` file. Both paths use
561-
the stable identifier `com.danielkov.kit`, overridable with
561+
the stable identifier `com.speakeasy.kit`, overridable with
562562
`KIT_CODESIGN_IDENTIFIER`. A changed identity, a missing certificate, or a
563563
locked Keychain may prompt again. `cargo install`
564564
does not run the runner; sign its installed binary separately. Apple Development

docs/releasing.md

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,55 @@ Clippy, and tests, builds Linux x86-64 and macOS arm64 archives, generates
2020
checksums, and publishes them to the tagged GitHub release. Prerelease tags are
2121
marked as prereleases on GitHub.
2222

23-
## Optional macOS signing and notarization
23+
## macOS signing and notarization
2424

25-
The macOS build does not require Apple credentials. When none are configured,
26-
the workflow publishes an unsigned, unnotarized archive and identifies it as
27-
such in the release notes. This is the expected setup until signing credentials
28-
are added to the repository.
25+
The release workflow signs the standalone Mach-O executable with the code-signing
26+
identifier `com.speakeasy.kit`, enables the hardened runtime, and submits it to
27+
Apple's notary service. This Developer ID distribution does not require an Apple
28+
App ID or provisioning profile.
2929

30-
To enable signing and notarization, configure all of these repository secrets:
30+
Create the credentials as follows:
3131

32-
- `MACOS_CERTIFICATE_P12_BASE64`
33-
- `MACOS_CERTIFICATE_PASSWORD`
34-
- `MACOS_SIGNING_IDENTITY`
35-
- `APPLE_API_KEY_P8_BASE64`
36-
- `APPLE_API_KEY_ID`
37-
- `APPLE_API_ISSUER_ID`
32+
1. In Keychain Access, use **Certificate Assistant > Request a Certificate From
33+
a Certificate Authority** to save a certificate signing request (CSR).
34+
2. In Apple Developer **Certificates, Identifiers & Profiles**, create a
35+
**Developer ID Application** certificate from that CSR. If that option is not
36+
available for your role, ask the team's Account Holder to create it. Import
37+
the downloaded certificate on the Mac that created the CSR.
38+
3. In Keychain Access, export the Developer ID certificate together with its
39+
private key as a password-protected PKCS#12 (`.p12`) file. Record the exact
40+
identity shown by `security find-identity -v -p codesigning`. It normally has
41+
the form `Developer ID Application: <Organization> (<TEAM_ID>)`.
42+
4. In App Store Connect **Users and Access > Integrations**, create a team API
43+
key that can access the notary service. Record its key ID and issuer ID, and
44+
retain the downloaded `.p8`; Apple does not allow it to be downloaded again.
45+
5. Store the `.p12`, its password, and the `.p8` in the company's secret manager.
46+
Configure these repository Actions secrets:
47+
48+
- `MACOS_CERTIFICATE_P12_BASE64`: base64-encoded `.p12`
49+
- `MACOS_CERTIFICATE_PASSWORD`: `.p12` export password
50+
- `MACOS_SIGNING_IDENTITY`: exact Keychain identity from step 3
51+
- `APPLE_API_KEY_P8_BASE64`: base64-encoded `.p8`
52+
- `APPLE_API_KEY_ID`: App Store Connect API key ID
53+
- `APPLE_API_ISSUER_ID`: App Store Connect issuer ID
54+
55+
For example, from a trusted Mac authenticated to GitHub CLI:
56+
57+
```sh
58+
repo=speakeasy-api/kit
59+
base64 < DeveloperIDApplication.p12 | gh secret set MACOS_CERTIFICATE_P12_BASE64 -R "$repo"
60+
read -r -s 'p12_password?P12 password: '; echo
61+
printf %s "$p12_password" | gh secret set MACOS_CERTIFICATE_PASSWORD -R "$repo"
62+
unset p12_password
63+
printf %s 'Developer ID Application: Example Corp (TEAMID)' | gh secret set MACOS_SIGNING_IDENTITY -R "$repo"
64+
base64 < AuthKey_KEYID.p8 | gh secret set APPLE_API_KEY_P8_BASE64 -R "$repo"
65+
printf %s 'KEYID' | gh secret set APPLE_API_KEY_ID -R "$repo"
66+
printf %s 'issuer-uuid' | gh secret set APPLE_API_ISSUER_ID -R "$repo"
67+
```
3868

3969
The workflow fails on a partial configuration rather than silently publishing
40-
an unsigned build. Downloaded `.p8` keys cannot be downloaded again, so retain
41-
the original in the company's secret manager.
70+
an unsigned build. With none of these secrets configured, it still publishes an
71+
unsigned, unnotarized archive and identifies it as such in the release notes.
4272

4373
## Verify a release
4474

scripts/codesign-runner.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ if [ "$(basename "$binary")" = kit ]; then
1212
if [ -z "$identity" ] && [ -r "$root/.kit-codesign-identity" ]; then
1313
IFS= read -r identity < "$root/.kit-codesign-identity"
1414
fi
15-
identifier="${KIT_CODESIGN_IDENTIFIER:-com.danielkov.kit}"
15+
identifier="${KIT_CODESIGN_IDENTIFIER:-com.speakeasy.kit}"
1616
if [ -n "$identity" ] && security find-identity -v -p codesigning 2>/dev/null | grep -Fq "\"$identity\""; then
1717
codesign --force --options runtime --identifier "$identifier" --sign "$identity" "$binary"
1818
else

scripts/notarize-release.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ Builds, Developer ID signs, and notarizes the macOS ARM64 release binary on
99
this Mac. The exact signed binary is preserved under dist/notarize/vVERSION/.
1010
1111
Required configuration (`.env` or environment variables):
12+
KIT_CODESIGN_IDENTITY
1213
KIT_NOTARY_API_KEY_DOCUMENT
1314
KIT_NOTARY_API_KEY_VAULT
1415
KIT_NOTARY_API_KEY_ID
1516
KIT_NOTARY_API_ISSUER_ID
1617
1718
Optional overrides:
18-
KIT_CODESIGN_IDENTITY
1919
KIT_CODESIGN_IDENTIFIER
2020
EOF
2121
}
@@ -57,8 +57,8 @@ if [[ -n $(git status --porcelain) ]]; then
5757
exit 1
5858
fi
5959

60-
identity=${KIT_CODESIGN_IDENTITY:-Developer ID Application: Inlucent Limited (TAMRUK8SL6)}
61-
identifier=${KIT_CODESIGN_IDENTIFIER:-com.danielkov.kit}
60+
identity=${KIT_CODESIGN_IDENTITY:?KIT_CODESIGN_IDENTITY must be set}
61+
identifier=${KIT_CODESIGN_IDENTIFIER:-com.speakeasy.kit}
6262
api_key_document=${KIT_NOTARY_API_KEY_DOCUMENT:?KIT_NOTARY_API_KEY_DOCUMENT must be set}
6363
api_key_vault=${KIT_NOTARY_API_KEY_VAULT:?KIT_NOTARY_API_KEY_VAULT must be set}
6464
api_key_id=${KIT_NOTARY_API_KEY_ID:?KIT_NOTARY_API_KEY_ID must be set}
@@ -88,7 +88,7 @@ umask 077
8888
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp}/kit-notary.XXXXXX")
8989
trap 'rm -rf "$tmp_dir"' EXIT
9090
api_key="$tmp_dir/AuthKey_${api_key_id}.p8"
91-
op document get "$api_key_document" --vault "$api_key_vault" --output "$api_key" >/dev/null
91+
op document get "$api_key_document" --vault "$api_key_vault" --out-file "$api_key" >/dev/null
9292
chmod 600 "$api_key"
9393
source_dir="$tmp_dir/source"
9494
mkdir -p "$source_dir"

scripts/sign-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if [ -z "$KIT_CODESIGN_IDENTITY" ] && [ -r "$root/.kit-codesign-identity" ]; the
77
IFS= read -r KIT_CODESIGN_IDENTITY < "$root/.kit-codesign-identity"
88
fi
99
: "${KIT_CODESIGN_IDENTITY:?set KIT_CODESIGN_IDENTITY or create .kit-codesign-identity}"
10-
KIT_CODESIGN_IDENTIFIER="${KIT_CODESIGN_IDENTIFIER:-com.danielkov.kit}"
10+
KIT_CODESIGN_IDENTIFIER="${KIT_CODESIGN_IDENTIFIER:-com.speakeasy.kit}"
1111

1212
if [ "$(uname -s)" != Darwin ]; then
1313
echo "codesigning is only supported on macOS" >&2

0 commit comments

Comments
 (0)