Enhance macOS build tools with keychain management and troubleshooting guidance

This commit updates the `README_MAS.md` to include important notes on keychain trust settings and the installation of Apple intermediate certificates, addressing common codesigning issues. Additionally, the `build_mas_pkg.sh` script is enhanced with functions to prepare the login keychain for signing, diagnose chain failures, and provide clear error messages for authorization issues during the build process. These improvements aim to streamline the macOS build experience and assist developers in resolving keychain-related errors effectively.
This commit is contained in:
2026-01-22 23:27:20 +09:00
parent 7a954b3f32
commit 8d49b87b7c
2 changed files with 168 additions and 4 deletions

View File

@@ -89,6 +89,16 @@ If you see errors like:
This is almost always a **keychain search list / trust chain** issue.
#### Important: do NOT “Always Trust” your Apple Distribution / Installer certs
Setting your leaf signing certificates (e.g. **Apple Distribution** / **3rd Party Mac Developer Installer**) to **Always Trust** can make things worse by overriding the normal trust chain and causing codesign to fail chain building.
If you changed trust settings:
- In **Keychain Access → login → My Certificates**
- open the cert → **Trust**
- set **“When using this certificate” = “Use System Defaults”**
Fix (safe, common): ensure the System keychains are included in the user search list:
```bash
@@ -98,6 +108,36 @@ security list-keychains -d user -s "$HOME/Library/Keychains/login.keychain-db"
Then re-run the build/sign script.
#### Install the correct Apple intermediate certificates (WWDR)
If the System keychains are already in the search list and you still get chain errors, youre likely missing an Apple intermediate (commonly **WWDR**).
Download the current Apple WWDR intermediate certificate(s) from Apples official Certificate Authority page:
- `https://www.apple.com/certificateauthority/`
Then import into the **System** keychain (recommended):
- Keychain Access → **System** keychain → File → **Import Items…** → select the downloaded `.cer`
Or via CLI (requires admin):
```bash
sudo security add-certificates -k /Library/Keychains/System.keychain "/path/to/WWDR.cer"
```
Verify its visible:
```bash
security find-certificate -a -c "Apple Worldwide Developer Relations" /Library/Keychains/System.keychain | head -n 10
```
If needed, you can also verify the chain for your distribution cert:
```bash
security verify-cert -c "Apple Distribution: Dry Ark LLC (7628766FL2)" 2>&1 | head -n 80
```
```bash
security find-identity -p codesigning -v
security find-identity -p basic -v
@@ -172,6 +212,52 @@ Outputs:
---
## Troubleshooting — `productbuild` fails with CSSM `-60008` (authorization)
If you see something like:
- `SignData failed ... CSSM Exception: -60008 Unable to obtain authorization for this operation`
That means the **Installer** certificate is present, but macOS is not allowing `productbuild` to use the **private key** without additional authorization.
### Fix option A (recommended): set key partition list (CLI)
This is the standard “allow Apple tools to sign without GUI prompts” fix:
```bash
security unlock-keychain "$HOME/Library/Keychains/login.keychain-db"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "<login-keychain-password>" "$HOME/Library/Keychains/login.keychain-db"
```
Note: if your password contains characters like `!` or `$` and you paste it into a command in `zsh`,
the shell can modify it (history/variable expansion) and `security ... -k` may claim its “incorrect”.
Use **single quotes** (or the env var path shown below) to avoid this, e.g.:
```bash
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k 'p@ssw0rd!$' "$HOME/Library/Keychains/login.keychain-db"
```
Then rerun:
```bash
./build_tools/macos/build_mas_pkg.sh --run ...
```
This repos script also supports:
- `--keychain-password <pw>` (or env var `STRAWBERRY_KEYCHAIN_PASSWORD`)
### Fix option B: Keychain Access UI (one-time)
1. Open **Keychain Access**
2. Select **login** keychain → **My Certificates**
3. Find your installer cert (e.g. `3rd Party Mac Developer Installer: ...`) and **expand it**
4. Select the **private key** under it
5. **Get Info → Access Control**
- Add `/usr/bin/productbuild` (and optionally `/usr/bin/pkgbuild`) to the allowed apps
---
## Step 7 — Upload + submit for review
- Upload the `.pkg` using Apples **Transporter** app (App Store Connect).

View File

@@ -1,12 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail
# Guard: this script must be executed with bash (not sourced into zsh, not run via sh).
if [[ -z "${BASH_VERSION:-}" ]]; then
echo "Error: this script must be run with bash (it uses bash arrays)." >&2
echo "Run:" >&2
echo " bash ./build_tools/macos/build_mas_pkg.sh --run ..." >&2
exit 2
fi
ts() { date +"%H:%M:%S"; }
lower() { echo "$1" | tr '[:upper:]' '[:lower:]'; }
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd -- "${script_dir}/../.." && pwd)"
prepare_login_keychain_for_signing() {
# Some setups require explicitly granting Apple tooling access to the private key(s)
# (otherwise productbuild/codesign can fail with authorization errors like:
# CSSM Exception: -60008 Unable to obtain authorization for this operation
# or "User interaction is not allowed").
#
# This function is optional and only runs if a keychain password is provided.
local keychain_path="$HOME/Library/Keychains/login.keychain-db"
local pw="${1:-}"
if [[ -z "$pw" ]]; then
echo "==> [$(ts)] Note: no keychain password provided; skipping keychain access-control preparation."
echo " If productbuild later fails with -60008 authorization errors, fix it with either:"
echo " - Keychain Access → login → My Certificates → select the *private key* under the Installer cert → Get Info → Access Control → allow productbuild"
echo " - OR (CLI): security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k <password> \"$keychain_path\""
return 0
fi
echo "==> [$(ts)] Preparing login keychain for signing (unlock + key partition list)"
# Unlock so Security/Authorization can use keys without prompting.
security unlock-keychain -p "$pw" "$keychain_path" >/dev/null 2>&1 || true
# Allow Apple tools (codesign/productbuild) to access the private key without GUI prompts.
# This is the standard fix used for non-interactive signing.
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$pw" "$keychain_path" >/dev/null 2>&1 || true
}
ensure_keychain_search_list() {
# codesign builds the cert chain using the user keychain search list.
# If the list is missing the System keychain, you can get:
@@ -27,6 +61,22 @@ ensure_keychain_search_list() {
security list-keychains -d user -s "$login_kc" "$system_kc" "$roots_kc" >/dev/null 2>&1 || true
}
diagnose_chain_failure() {
echo "==> [$(ts)] Codesign failed. Common causes on macOS:"
echo " - System keychains not in the user keychain search list"
echo " - Missing/invalid WWDR intermediate certificate"
echo " - Keychain/key access issues"
echo
echo "==> [$(ts)] Keychain search list:"
security list-keychains -d user || true
echo
echo "==> [$(ts)] Checking for Apple WWDR intermediate in System keychain:"
security find-certificate -a -c "Apple Worldwide Developer Relations" /Library/Keychains/System.keychain 2>/dev/null | head -n 5 || true
echo
echo "==> [$(ts)] If WWDR is missing, install the current Apple WWDR intermediate certificate (via Xcode or Apple Developer portal)."
echo "==> [$(ts)] Then re-run this script."
}
preflight_identity() {
local what="$1"
@@ -67,8 +117,17 @@ Optional:
--entitlements <plist> Codesign entitlements (default: dist/macos/entitlements.mas.plist)
--bundle-id <id> Override CFBundleIdentifier (default: com.dryark.strawberry)
--pkg-out <path> Output .pkg path (default: <build-dir>/strawberry-mas.pkg)
--keychain-password <pw> OPTIONAL: unlock/login keychain + set key partition list for Apple tools
(alternative: set env var STRAWBERRY_KEYCHAIN_PASSWORD)
Examples:
# Tip: if your keychain password contains characters like ! or $, prefer the env var or single quotes.
STRAWBERRY_KEYCHAIN_PASSWORD='your-login-keychain-password' \
./build_tools/macos/build_mas_pkg.sh --run --release --clean \
--codesign-identity "Apple Distribution: Your Name (TEAMID)" \
--installer-identity "3rd Party Mac Developer Installer: Your Name (TEAMID)" \
--provisionprofile "$HOME/Library/MobileDevice/Provisioning Profiles/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.provisionprofile"
./build_tools/macos/build_mas_pkg.sh --run --release --clean \
--codesign-identity "Apple Distribution: Your Name (TEAMID)" \
--installer-identity "3rd Party Mac Developer Installer: Your Name (TEAMID)" \
@@ -95,6 +154,7 @@ provisionprofile=""
entitlements=""
bundle_id="com.dryark.strawberry"
pkg_out=""
keychain_password="${STRAWBERRY_KEYCHAIN_PASSWORD:-}"
while [[ $# -gt 0 ]]; do
case "$1" in
@@ -109,6 +169,7 @@ while [[ $# -gt 0 ]]; do
--entitlements) entitlements="${2:-}"; shift 2 ;;
--bundle-id) bundle_id="${2:-}"; shift 2 ;;
--pkg-out) pkg_out="${2:-}"; shift 2 ;;
--keychain-password) keychain_password="${2:-}"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
esac
@@ -182,6 +243,7 @@ echo "==> [$(ts)] Embedding provisioning profile"
cp -f "$provisionprofile" "${app_path}/Contents/embedded.provisionprofile"
ensure_keychain_search_list
prepare_login_keychain_for_signing "$keychain_password"
preflight_identity "codesign" "codesigning" "$codesign_identity"
preflight_identity "installer" "basic" "$installer_identity"
@@ -231,10 +293,26 @@ codesign --verify --deep --strict --verbose=2 "$app_path"
echo "==> [$(ts)] Building signed .pkg for App Store upload"
rm -f "$pkg_out" >/dev/null 2>&1 || true
productbuild \
--component "$app_path" /Applications \
--sign "$installer_identity" \
"$pkg_out"
if ! productbuild \
--component "$app_path" /Applications \
--sign "$installer_identity" \
"$pkg_out"; then
echo "Error: productbuild failed while signing the .pkg." >&2
echo "Common cause: keychain/private-key authorization (e.g. CSSM -60008)." >&2
echo >&2
echo "Fix options:" >&2
echo "1) Keychain Access UI:" >&2
echo " - Keychain Access → login → My Certificates" >&2
echo " - Find: $installer_identity" >&2
echo " - Expand it and select the *private key* under it" >&2
echo " - Get Info → Access Control → allow /usr/bin/productbuild (optionally also allow /usr/bin/pkgbuild)" >&2
echo "2) CLI (recommended for repeatable builds):" >&2
echo " security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k <password> \"$HOME/Library/Keychains/login.keychain-db\"" >&2
echo >&2
echo "Tip: you can also rerun this script with:" >&2
echo " --keychain-password <login-keychain-password>" >&2
exit 1
fi
echo "==> [$(ts)] Verifying pkg signature"
pkgutil --check-signature "$pkg_out" || true