Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1c57661
PSSO migrations for final schema shape
JordanMontgomery Jun 11, 2026
35524ad
Remove unneeded comment
JordanMontgomery Jun 11, 2026
cf5aac9
Cleanup comments, fix clock skew bug
JordanMontgomery Jun 11, 2026
98060b3
Initial work to refactor endpoints/handlers
JordanMontgomery Jun 15, 2026
b362490
Merge branch 'feature/fleet-macos-password-sync' into JM-46942-api-en…
JordanMontgomery Jun 15, 2026
9051e35
Lint + fixes from testing
JordanMontgomery Jun 15, 2026
084bb1f
Fix lint
JordanMontgomery Jun 15, 2026
1b54368
Initial work to refactor cofnig
JordanMontgomery Jun 16, 2026
f8d11cd
Fix review comments
JordanMontgomery Jun 16, 2026
5a5e3b5
Merge branch 'JM-46942-api-endpoint-refactor' into JM-47172-api-gitops
JordanMontgomery Jun 16, 2026
499ce6c
Update cloner for PSSO fields
JordanMontgomery Jun 16, 2026
23c2c48
Fix schema
JordanMontgomery Jun 16, 2026
946f145
Fix tests
JordanMontgomery Jun 17, 2026
14993d4
Merge branch 'feature/fleet-macos-password-sync' into JM-47172-api-gi…
JordanMontgomery Jun 17, 2026
240cb8f
Fix issues with getting/setting partials in gitops
JordanMontgomery Jun 17, 2026
deae1c7
Fix comment and failing tests
JordanMontgomery Jun 17, 2026
c950e66
Add gitops secret redaction
JordanMontgomery Jun 17, 2026
a6e709f
Cleanup crypto
JordanMontgomery Jun 17, 2026
c4a4ee3
Add activity
JordanMontgomery Jun 17, 2026
ba15820
Merge branch 'JM-47172-api-gitops' into JM-47122-crypto-cleanup
JordanMontgomery Jun 17, 2026
f34f699
Update PSSO research doc, removed remediated findings
JordanMontgomery Jun 17, 2026
4d01629
Update doc
JordanMontgomery Jun 17, 2026
6f04ba8
Fix tests
JordanMontgomery Jun 17, 2026
20376c9
Fix potential secret unmasking
JordanMontgomery Jun 18, 2026
30bc8ca
Merge branch 'JM-47172-api-gitops' into JM-47122-crypto-cleanup
JordanMontgomery Jun 18, 2026
3626714
Merge branch 'feature/fleet-macos-password-sync' into JM-47122-crypto…
JordanMontgomery Jun 18, 2026
fb76838
Cleanup bootstrap a bit
JordanMontgomery Jun 18, 2026
1eb6cac
Combine fleet desktop and SSO ext
JordanMontgomery Jun 18, 2026
865cac7
Fix Add missed files
JordanMontgomery Jun 18, 2026
c8fdefa
Add assoc domains to profile
JordanMontgomery Jun 18, 2026
36ce458
Update signing info
JordanMontgomery Jun 19, 2026
8dc5373
Fix macos ext payload
JordanMontgomery Jun 19, 2026
0e3a2b3
fix README wording
JordanMontgomery Jun 19, 2026
2838d83
Update comment
JordanMontgomery Jun 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 75 additions & 13 deletions .github/workflows/fleet-desktop-macos-build.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
name: Build Fleet Desktop (macOS)

# Builds the native macOS Fleet Desktop app (apps/fleet-desktop-macos/), code signs
# and notarizes it with Fleet's Developer ID certificates, and uploads the signed
# Builds the native macOS Fleet Desktop app (apps/fleet-desktop-macos/) and its
# embedded Platform SSO extension (FleetPSSOExtension.appex), code signs and
# notarizes them with Fleet's Developer ID certificates, and uploads the signed
# .pkg as a workflow artifact. No GitHub Release is created.
#
# The app and extension carry managed Associated Domains entitlements
# (com.apple.developer.associated-domains{,.mdm-managed}). Those are restricted
# entitlements: codesign only honors them when a Developer ID provisioning
# profile that grants them is embedded in the bundle. The profiles are provided
# as base64 repo secrets (never committed) and embedded at sign time — see the
# README's "Signing secrets" section.
#
# This workflow always signs and notarizes. If the certs or provisioning
# profiles are unavailable (e.g. a fork PR that can't read secrets), it fails
# loudly rather than producing an unsigned artifact.
Comment thread
JordanMontgomery marked this conversation as resolved.

on:
push:
Expand Down Expand Up @@ -36,6 +48,8 @@ env:
# of Fleet's macOS artifacts (orbit Fleet Desktop, fleetd-base.pkg).
APPLICATION_SIGNING_IDENTITY_SHA1: 604D877399AAEB7630A78B84F288E2D28A2EDE42
INSTALLER_SIGNING_IDENTITY_SHA1: 4608F71FB42E1845C7FC9B2D2B6A7A8D11BBD940
# Embedded SSO extension bundle (relative to Fleet Desktop.app/Contents).
APPEX_REL_PATH: PlugIns/FleetPSSOExtension.appex

jobs:
build:
Expand All @@ -52,7 +66,7 @@ jobs:
with:
persist-credentials: false

- name: Build app and create pkg
- name: Build app (with embedded extension) and create pkg
run: |
chmod +x build.sh build-pkg.sh
./build-pkg.sh
Expand All @@ -69,7 +83,7 @@ jobs:
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain

# Developer ID Application certificate — signs the .app (codesign).
# Developer ID Application certificate — signs the .app/.appex (codesign).
echo "$APPLE_APPLICATION_CERTIFICATE" | base64 --decode > application.p12
security import application.p12 -k build.keychain -P "$APPLE_APPLICATION_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
rm application.p12
Expand All @@ -82,24 +96,71 @@ jobs:
security set-key-partition-list -S apple-tool:,apple:,codesign:,productsign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
security find-identity -vv

- name: Code sign app
- name: Embed provisioning profiles
env:
APPLE_FLEET_DESKTOP_APP_PROFILE_B64: ${{ secrets.APPLE_FLEET_DESKTOP_APP_PROFILE_B64 }}
APPLE_PSSO_EXT_PROFILE_B64: ${{ secrets.APPLE_PSSO_EXT_PROFILE_B64 }}
run: |
APP="build/Fleet Desktop.app"
APPEX="$APP/Contents/$APPEX_REL_PATH"

if [ -z "$APPLE_FLEET_DESKTOP_APP_PROFILE_B64" ] || [ -z "$APPLE_PSSO_EXT_PROFILE_B64" ]; then
echo "::error::Missing provisioning profile secrets (APPLE_FLEET_DESKTOP_APP_PROFILE_B64 / APPLE_PSSO_EXT_PROFILE_B64). The app and extension carry restricted Associated Domains entitlements that codesign cannot honor without them."
exit 1
fi

# Developer ID profiles authorizing the restricted entitlements.
echo "$APPLE_PSSO_EXT_PROFILE_B64" | base64 --decode > "$APPEX/Contents/embedded.provisionprofile"
echo "$APPLE_FLEET_DESKTOP_APP_PROFILE_B64" | base64 --decode > "$APP/Contents/embedded.provisionprofile"

- name: Verify profiles authorize the signing certificate
run: |
APP="build/Fleet Desktop.app"
APPEX="$APP/Contents/$APPEX_REL_PATH"

# AMFI requires the signing certificate to be listed in the embedded
# profile's DeveloperCertificates, or it SIGKILLs the app at launch.
# codesign, Gatekeeper, and notarization all pass regardless — so
# without this check a profile cut against the wrong cert produces a
# signed, notarized pkg that silently won't launch. Even two certs from
# the same team will result in a broken, unusable app - they must be the
# same cert
check='import sys,plistlib,hashlib; pl=plistlib.loads(sys.stdin.buffer.read()); h=[hashlib.sha1(bytes(c)).hexdigest().upper() for c in pl.get("DeveloperCertificates",[])]; print(" authorizes:",h); sys.exit(0 if sys.argv[1].upper() in h else 1)'
for prof in "$APPEX/Contents/embedded.provisionprofile" "$APP/Contents/embedded.provisionprofile"; do
echo "Checking $prof"
if ! security cms -D -i "$prof" | python3 -c "$check" "$APPLICATION_SIGNING_IDENTITY_SHA1"; then
echo "::error::$prof does not authorize signing certificate $APPLICATION_SIGNING_IDENTITY_SHA1. AMFI will SIGKILL the app at launch (notarization does NOT catch this). Regenerate the Developer ID provisioning profile selecting that certificate."
exit 1
fi
done

- name: Code sign app and extension
run: |
BINARY_PATH="build/Fleet Desktop.app/Contents/MacOS/FleetDesktop"
APP="build/Fleet Desktop.app"
APPEX="$APP/Contents/$APPEX_REL_PATH"

# Sign the universal binary first, then the bundle (no --deep).
# Sign inside-out: the embedded extension first, then the host app.
# Each bundle is sealed with its own entitlements + embedded profile.
codesign --force --sign "$APPLICATION_SIGNING_IDENTITY_SHA1" \
--options runtime --timestamp "$APPEX/Contents/MacOS/FleetPSSOExtension"
codesign --force --sign "$APPLICATION_SIGNING_IDENTITY_SHA1" \
--options runtime --timestamp "$BINARY_PATH"
codesign --verify --verbose "$BINARY_PATH"
--options runtime --timestamp \
--entitlements FleetPSSOExtension/FleetPSSOExtension.entitlements "$APPEX"

codesign --force --sign "$APPLICATION_SIGNING_IDENTITY_SHA1" \
--options runtime --timestamp "build/Fleet Desktop.app"
--options runtime --timestamp "$APP/Contents/MacOS/FleetDesktop"
codesign --force --sign "$APPLICATION_SIGNING_IDENTITY_SHA1" \
--options runtime --timestamp \
--entitlements FleetDesktop/FleetDesktop.entitlements "$APP"

codesign --verify --deep --strict --verbose=2 "build/Fleet Desktop.app"
codesign --display --verbose=4 "build/Fleet Desktop.app"
codesign --verify --deep --strict --verbose=2 "$APP"
codesign --display --verbose=4 "$APP"
codesign --display --entitlements - "$APPEX"

- name: Rebuild pkg with signed app
run: |
# build-pkg.sh reuses the already-signed app (ditto preserves the signature).
# build-pkg.sh reuses the already-signed app (ditto preserves the
# signature and the embedded, signed appex).
./build-pkg.sh

- name: Sign pkg
Expand Down Expand Up @@ -156,6 +217,7 @@ jobs:
spctl --assess --type install --verbose "$PKG_PATH"

- name: Cleanup keychain
if: always()
run: security delete-keychain build.keychain || true

- name: Upload pkg artifact
Expand Down

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6 changes: 0 additions & 6 deletions apple-sso-extension/Assets.xcassets/Contents.json

This file was deleted.

Loading
Loading