mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
ci(cli): surface notary log on non-Accepted; record signing validation
macOS validation (Developer ID D77MCV9NZ7) confirmed the hardened-runtime entitlements are correct and load-bearing: amy init derives a secp256k1 key cleanly, and dropping disable-library-validation reproduces the runtime dlopen Team-ID failure. The one unverified gap is whether Apple's notary service accepts the unsigned Mach-O dylibs embedded inside lib/*.jar (secp256k1/jna/sqlite/skiko), which it inspects recursively. - create-release.yml: the notarize step now submits with --output-format json, and on any non-Accepted status dumps `notarytool log` (per-file issues) and fails — so the first real run names the offending files instead of failing opaquely. No speculative in-jar signing yet; gather the log first. - BUILDING.md: record the validation result, the embedded-jar-native risk, the one-run way to decide it (workflow_dispatch dry_run with MAC_* secrets), and the staged fixes (sign-in-jar and/or strip the skiko/Compose leak). Note the desktop app shares the same jars and needs its own dry-run. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sso31DfSF9B6EFCVkEqWD
This commit is contained in:
@@ -323,10 +323,31 @@ jobs:
|
||||
done < <(find "$IMG" -type f)
|
||||
codesign --verify --strict --verbose=2 "$IMG/runtime/bin/java"
|
||||
# Notarize: zip the signed image, submit, wait for Apple's verdict.
|
||||
ditto -c -k --keepParent "$IMG" "$RUNNER_TEMP/amy-notarize.zip"
|
||||
xcrun notarytool submit "$RUNNER_TEMP/amy-notarize.zip" \
|
||||
--apple-id "$NOTARY_APPLE_ID" --password "$NOTARY_PASSWORD" \
|
||||
--team-id "$NOTARY_TEAM_ID" --wait
|
||||
# The notary service recursively inspects the lib/*.jar files, so any
|
||||
# unsigned Mach-O embedded in them (secp256k1/jna/sqlite/skiko natives)
|
||||
# can come back Invalid. Surface the per-file log so the first real run
|
||||
# is diagnostic rather than a bare failure.
|
||||
ZIP="$RUNNER_TEMP/amy-notarize.zip"
|
||||
OUT="$RUNNER_TEMP/notary-submit.json"
|
||||
ditto -c -k --keepParent "$IMG" "$ZIP"
|
||||
if ! xcrun notarytool submit "$ZIP" \
|
||||
--apple-id "$NOTARY_APPLE_ID" --password "$NOTARY_PASSWORD" \
|
||||
--team-id "$NOTARY_TEAM_ID" --wait --output-format json > "$OUT"; then
|
||||
echo "::warning::notarytool submit exited non-zero"
|
||||
fi
|
||||
cat "$OUT"
|
||||
STATUS="$(jq -r '.status // "Unknown"' "$OUT" 2>/dev/null || echo Unknown)"
|
||||
SUBMISSION_ID="$(jq -r '.id // empty' "$OUT" 2>/dev/null || true)"
|
||||
if [ "$STATUS" != "Accepted" ]; then
|
||||
echo "::error::Notarization status: $STATUS"
|
||||
if [ -n "$SUBMISSION_ID" ]; then
|
||||
echo "----- notary log -----"
|
||||
xcrun notarytool log "$SUBMISSION_ID" \
|
||||
--apple-id "$NOTARY_APPLE_ID" --password "$NOTARY_PASSWORD" \
|
||||
--team-id "$NOTARY_TEAM_ID" || true
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# jpackage pins libicu to the build host's version (libicu74 on
|
||||
# ubuntu-24.04). Rewrite the .deb so it installs across Debian/Ubuntu.
|
||||
|
||||
+22
@@ -281,6 +281,28 @@ Gatekeeper verifies notarization **online** on first run — fine for a CLI.
|
||||
Note the Homebrew-core jvm bundle (`amy-<version>-jvm.tar.gz`) is **not** signed:
|
||||
Homebrew removes the quarantine attribute on its own downloads.
|
||||
|
||||
> **Validated (Developer ID `D77MCV9NZ7`):** signing every Mach-O in the bundled
|
||||
> JRE with hardened runtime + `amy.entitlements` lets `amy init` derive a key via
|
||||
> secp256k1 with no library-validation crash. Dropping `disable-library-validation`
|
||||
> reproduces `UnsatisfiedLinkError: … different Team IDs` on the runtime-extracted
|
||||
> `libsecp256k1-jni.dylib` — so that entitlement is load-bearing, not decorative.
|
||||
>
|
||||
> **Open risk — embedded jar natives.** The notary service unpacks `lib/*.jar`
|
||||
> recursively and checks every Mach-O for a signature + hardened runtime. Our
|
||||
> sign loop only touches loose files, so 9 unsigned natives ride along inside
|
||||
> jars on a macOS build: `secp256k1` (1, required at runtime), `jna` (2),
|
||||
> `sqlite` (2), and `skiko` (4, dead weight — Compose UI the CLI never renders).
|
||||
> Whether `notarytool` returns `Accepted` or `Invalid` on these is **unverified**
|
||||
> (the local validation had no notary creds). **Decide it with one run:** set the
|
||||
> six `MAC_*` secrets and trigger `create-release.yml` via `workflow_dispatch`
|
||||
> with `dry_run=true` — the sign+notarize step runs regardless of `dry_run` and
|
||||
> now prints the per-file notary log on a non-`Accepted` verdict. If it comes
|
||||
> back `Invalid`, the fix is to codesign the dylibs *inside* those jars before
|
||||
> zipping (and/or strip the unused `skiko`/Compose jars from the CLI image — the
|
||||
> `:commons` core/ui split the size budget already flags). The **desktop** app
|
||||
> bundles the same jars through Compose/jpackage notarization, so run a desktop
|
||||
> dry-run too; its in-jar handling differs and is likewise unverified.
|
||||
|
||||
Generating the values:
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user