feat(webauthn): Touch ID + Google passkey sign-in via patched from-source CEF#25
Open
wenkaifan0720 wants to merge 1 commit into
Open
feat(webauthn): Touch ID + Google passkey sign-in via patched from-source CEF#25wenkaifan0720 wants to merge 1 commit into
wenkaifan0720 wants to merge 1 commit into
Conversation
…ed from-source CEF
OSR/windowless browsers can't host the WebAuthn UI, and unbranded CEF can't
reach the macOS platform authenticator (Touch ID / Secure Enclave) at all --
its keychain-access-group derives from an empty MAC_TEAM_IDENTIFIER_STRING, so
it asks for ".org.chromium.Chromium.webauthn", which no entitlement can match.
This adds first-class passkey support in two independent pieces:
1. openAuthWindow op (protocol v3 -> v4): a new IPC op (0x39) that opens a
windowed Chrome-runtime browser (CEF_RUNTIME_STYLE_CHROME) sharing the OSR
tile's cookie jar, so the sign-in ceremony runs somewhere that can host the
WebAuthn UI the off-screen tile cannot. Plumbed through main.mm ->
FlutterCefPlugin.swift / CefWebSession.swift / CefProfileHost.swift ->
cef_web_controller.dart (openAuthWindow(url)).
2. From-source patched CEF build: native/build-cef-from-source.sh fetches
Chromium+CEF at the pinned rev and applies ONE 13-line patch
(native/patches/campus_webauthn_keychain.patch) hardcoding the KLAJ5X6PJP
team prefix on the keychain group. This is Tier-2 (build libcef from source
with a patch), NOT a Chromium fork -- the patch is a single entry in CEF's
own patch.cfg pipeline.
Build config is load-bearing: is_official_build=true (matches the stock
Spotify prebuilt, strips DCHECKs, and -- critically -- fixes Google-account
caBLE/QR passkey sign-in that a non-official build breaks). H.264/AAC via
proprietary_codecs + ffmpeg_branding="Chrome" (royalty-bearing; gate prod
distribution on legal sign-off).
No-drift: a patched framework built under the same CEF_VERSION would otherwise
collide with the stock content hash and every consumer would silently fetch the
UNPATCHED framework. CEF_FRAMEWORK_VARIANT ("campus-webauthn-h264") is folded
into cef_host_hash.sh's digest so the patched build gets a DISTINCT GCS key, and
build_cef_host.sh hard-fails if the marker is non-stock but the framework lacks
the patch.
Signing: the passkey keychain group needs the browser (top-level cef_host)
process entitled + an embedded Developer-ID provisioning profile blessing that
group; helpers keep the minimal entitlements. entitlements.browser.plist
documents the browser-process superset (the work_canvas release script derives
it from the profile at sign time).
Tested: webauthn.io Touch ID and Google-account QR/phone-passkey sign-in both
complete end-to-end in a notarized Campus dev build (reaches Google's passkey
enrollment page). The -67030 process_requirement log line is a benign red
herring -- present in the working build too.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds on-device Touch ID passkeys and Google-account QR/phone-passkey sign-in to the CEF webview, via a patched from-source CEF — Tier-2 (build libcef with a 13-line patch), not a Chromium fork.
Two independent pieces:
openAuthWindowop (protocol v3 → v4) — new IPC op0x39that opens a windowed Chrome-runtime browser (CEF_RUNTIME_STYLE_CHROME) sharing the OSR tile's cookie jar. The OSR/windowless tile can't host WebAuthn UI; this runs the ceremony in a window that can. Plumbedmain.mm→FlutterCefPlugin.swift/CefWebSession.swift/CefProfileHost.swift→cef_web_controller.dart(openAuthWindow(url)).From-source patched CEF —
native/build-cef-from-source.shfetches Chromium+CEF at the pinned rev and applies one 13-line patch (native/patches/campus_webauthn_keychain.patch) that hardcodes theKLAJ5X6PJPteam prefix on the WebAuthn keychain-access-group. Unbranded CEF derives it from an emptyMAC_TEAM_IDENTIFIER_STRING→.org.chromium.Chromium.webauthn, which no entitlement can match, so Touch ID is unreachable without this.Why the build config matters
is_official_build=trueis load-bearing three ways — don't downgrade to a baredcheck_always_on=falsebuild:chrome_paths_mac.mmon CEF'sVersions/Alayout);proprietary_codecs=true ffmpeg_branding="Chrome"add H.264/AAC — royalty-bearing (MPEG-LA / Via-LA). Gate prod distribution on legal sign-off.No-drift
A patched framework under the same
CEF_VERSIONwould collide with the stock content hash → every consumer silently fetches the unpatched framework.CEF_FRAMEWORK_VARIANT(campus-webauthn-h264) is folded intocef_host_hash.sh's digest so the patched build gets a distinct GCS key, andbuild_cef_host.shhard-fails if the marker is non-stock but the framework lacks the patch. The stock digest is byte-identical to before (no republish of the existing stock host).Testing
Notarized Campus dev build, user-confirmed:
Merge / rollout notes
cef_hostprebuilt for its new content hash (make publish-cef-host) so consumers fetch it instead of a ~2 hr local build.work_canvasthen bumps its pin to this merge SHA (make pin-cef) — companion PR.entitlements.browser.plistis a documented hand-apply reference; thework_canvasrelease script derives browser entitlements from the provisioning profile at sign time.🤖 Generated with Claude Code