verify.sh bash
101 lines 4.4 KB
Raw
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700 feat(companion): add production macOS distribution path Human minor ⚠ breaking 25 days ago
1 #!/bin/bash
2 set -euo pipefail
3
4 app=""
5 package_file=""
6 manifest=""
7 signature=""
8 checksums=""
9 public_key_file="${KNOWTATION_UPDATE_PUBLIC_KEY_FILE:-}"
10 while [[ $# -gt 0 ]]; do
11 case "$1" in
12 --app) app="$2"; shift 2 ;;
13 --package) package_file="$2"; shift 2 ;;
14 --manifest) manifest="$2"; shift 2 ;;
15 --signature) signature="$2"; shift 2 ;;
16 --checksums) checksums="$2"; shift 2 ;;
17 --public-key-file) public_key_file="$2"; shift 2 ;;
18 *) echo "unknown argument: $1" >&2; exit 2 ;;
19 esac
20 done
21
22 repo_root="$(cd "$(dirname "$0")/../../.." && pwd)"
23 for required in "$app" "$package_file" "$manifest" "$signature" "$checksums" "$public_key_file"; do
24 [[ -e "$required" ]] || { echo "missing verification input: $required" >&2; exit 2; }
25 done
26 [[ "${KNOWTATION_APPLE_TEAM_ID:-}" =~ ^[A-Z0-9]{10}$ ]] || {
27 echo "KNOWTATION_APPLE_TEAM_ID is required" >&2; exit 1;
28 }
29 verification_tmp="$(mktemp -d "${TMPDIR:-/tmp}/knowtation-release-verify.XXXXXX")"
30 trap 'rm -rf "$verification_tmp"' EXIT
31
32 verify_identity() {
33 local target="$1"
34 local expected_identifier="$2"
35 local information
36 information="$(codesign -d --verbose=4 "$target" 2>&1)"
37 grep -Fqx "Identifier=$expected_identifier" <<< "$information"
38 grep -Fqx "TeamIdentifier=$KNOWTATION_APPLE_TEAM_ID" <<< "$information"
39 }
40
41 codesign --verify --deep --strict --verbose=4 "$app"
42 node "$repo_root/scripts/release/macos/verify-runtime-manifest.mjs" \
43 --app "$app" --require-committed-source
44 spctl --assess --type execute --verbose=4 "$app"
45 verify_identity "$app" "store.knowtation.companion"
46 verify_identity "$app/Contents/Library/LaunchServices/KnowtationCustodyAgent.app" \
47 "store.knowtation.companion.custody"
48 verify_identity "$app/Contents/Helpers/knowtation" "store.knowtation.cli"
49 verify_identity "$app/Contents/Helpers/knowtation-mcp" "store.knowtation.mcp"
50 verify_identity "$app/Contents/Resources/runtime/node/bin/node" "store.knowtation.runtime.node"
51 custody_app="$app/Contents/Library/LaunchServices/KnowtationCustodyAgent.app"
52 test -f "$custody_app/Contents/embedded.provisionprofile"
53 codesign -d --entitlements :- "$custody_app" > "$verification_tmp/custody-entitlements.plist" 2>/dev/null
54 test "$(plutil -extract com.apple.application-identifier raw \
55 "$verification_tmp/custody-entitlements.plist")" = \
56 "$KNOWTATION_APPLE_TEAM_ID.store.knowtation.companion.custody"
57 test "$(plutil -extract keychain-access-groups.0 raw \
58 "$verification_tmp/custody-entitlements.plist")" = \
59 "$KNOWTATION_APPLE_TEAM_ID.store.knowtation.companion.custody"
60 pkgutil --check-signature "$package_file"
61 spctl --assess --type install --verbose=4 "$package_file"
62 xcrun stapler validate "$app"
63 xcrun stapler validate "$package_file"
64
65 (cd "$(dirname "$checksums")" && shasum -a 256 -c "$(basename "$checksums")")
66 unzip -t "$(dirname "$manifest")/Knowtation-0.1.0-100-macos-arm64.zip"
67
68 node "$repo_root/scripts/release/macos/verify-update-manifest.mjs" \
69 --manifest "$manifest" \
70 --signature "$signature" \
71 --public-key-file "$public_key_file" \
72 --trust "$app/Contents/Resources/update-trust.json" \
73 --package "$package_file"
74
75 test "$(plutil -extract CFBundleIdentifier raw "$app/Contents/Info.plist")" = "store.knowtation.companion"
76 test "$(plutil -extract CFBundleShortVersionString raw "$app/Contents/Info.plist")" = "0.1.0"
77 test "$(plutil -extract CFBundleVersion raw "$app/Contents/Info.plist")" = "100"
78 lipo -verify_arch arm64 "$app/Contents/MacOS/Knowtation"
79 lipo -verify_arch arm64 "$app/Contents/Helpers/knowtation"
80 lipo -verify_arch arm64 "$app/Contents/Helpers/knowtation-mcp"
81 lipo -verify_arch arm64 "$app/Contents/Resources/runtime/node/bin/node"
82 while IFS= read -r -d '' native; do
83 test "$(lipo -archs "$native")" = "arm64"
84 done < <(find "$app/Contents/Resources/runtime" -type f \( -name '*.node' -o -name '*.dylib' \) -print0)
85
86 if find "$app" -type f \( -name '.env' -o -name '*.pem' -o -name '*.p12' -o -name 'local.yaml' \) -print -quit | grep -q .; then
87 echo "secret-bearing or local configuration file found in app" >&2
88 exit 1
89 fi
90
91 if find "$app/Contents/Resources/runtime/node_modules" -type d \( -name sharp -o -name 'sharp-*' -o -name 'libvips-*' \) -print -quit | grep -q .; then
92 echo "excluded sharp/libvips dependency found" >&2
93 exit 1
94 fi
95
96 if grep -q "No license text was present" "$app/Contents/Resources/THIRD-PARTY-NOTICES.txt"; then
97 echo "runtime dependency is missing distributable license text" >&2
98 exit 1
99 fi
100
101 echo "release verification passed"
File History 1 commit
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700 feat(companion): add production macOS distribution path Human minor ⚠ 25 days ago