Skip to content

Commit ee1838b

Browse files
committed
fix(sign): make browser passkey profiles optional
1 parent 7f57a58 commit ee1838b

10 files changed

Lines changed: 386 additions & 157 deletions

File tree

.github/scripts/macos-signing-keychain.sh

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ owned_cert_path() {
3232
owned_profile_path() {
3333
case "$1" in
3434
"$RUNNER_TEMP"/browseros-passkey-profile-*.provisionprofile) return 0 ;;
35+
"$RUNNER_TEMP"/browserclaw-passkey-profile-*.provisionprofile) return 0 ;;
3536
*) return 1 ;;
3637
esac
3738
}
@@ -168,9 +169,13 @@ setup_keychain() {
168169

169170
local run_tag="${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}"
170171
local cert_path="$RUNNER_TEMP/browseros-signing-cert-$run_tag.p12"
171-
local profile_path=""
172+
local browseros_profile_path=""
173+
local browserclaw_profile_path=""
172174
if [ -n "${PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64:-}" ]; then
173-
profile_path="$RUNNER_TEMP/browseros-passkey-profile-$run_tag.provisionprofile"
175+
browseros_profile_path="$RUNNER_TEMP/browseros-passkey-profile-$run_tag.provisionprofile"
176+
fi
177+
if [ -n "${PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64:-}" ]; then
178+
browserclaw_profile_path="$RUNNER_TEMP/browserclaw-passkey-profile-$run_tag.provisionprofile"
174179
fi
175180
local keychain_path="$RUNNER_TEMP/browseros-ci-signing-$run_tag.keychain-db"
176181
local original_keychains_file="$RUNNER_TEMP/browseros-ci-original-keychains-$run_tag.txt"
@@ -207,7 +212,8 @@ setup_keychain() {
207212

208213
{
209214
printf 'cert_path=%s\n' "$cert_path"
210-
printf 'profile_path=%s\n' "$profile_path"
215+
printf 'browseros_profile_path=%s\n' "$browseros_profile_path"
216+
printf 'browserclaw_profile_path=%s\n' "$browserclaw_profile_path"
211217
printf 'keychain_path=%s\n' "$keychain_path"
212218
printf 'original_default_keychain=%s\n' "$original_default_keychain"
213219
printf 'original_keychains_file=%s\n' "$original_keychains_file"
@@ -217,19 +223,26 @@ setup_keychain() {
217223
trap cleanup_after_setup_error ERR
218224

219225
rm -f "$cert_path"
220-
if owned_profile_path "$profile_path"; then
221-
rm -f "$profile_path"
222-
fi
226+
local profile_path
227+
for profile_path in "$browseros_profile_path" "$browserclaw_profile_path"; do
228+
if owned_profile_path "$profile_path"; then
229+
rm -f "$profile_path"
230+
fi
231+
done
223232
security delete-keychain "$keychain_path" >/dev/null 2>&1 || true
224233
rm -f "$keychain_path"
225234

226235
decode_certificate "$cert_path"
227-
if [ -n "$profile_path" ]; then
228-
# The profile is an app-ID-specific authorization document. Keep it in
229-
# runner-owned temporary storage so neither source checkout nor artifact
230-
# staging can accidentally retain it after signing.
231-
decode_base64_value "$PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64" "$profile_path"
232-
chmod 600 "$profile_path"
236+
# Each profile authorizes one exact App ID. Decode them to separate,
237+
# runner-owned paths so a product can never accidentally consume its
238+
# sibling's authorization document and cleanup can remove both reliably.
239+
if [ -n "$browseros_profile_path" ]; then
240+
decode_base64_value "$PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64" "$browseros_profile_path"
241+
chmod 600 "$browseros_profile_path"
242+
fi
243+
if [ -n "$browserclaw_profile_path" ]; then
244+
decode_base64_value "$PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64" "$browserclaw_profile_path"
245+
chmod 600 "$browserclaw_profile_path"
233246
fi
234247
security create-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$keychain_path"
235248
security set-keychain-settings -lut 21600 "$keychain_path"
@@ -259,10 +272,12 @@ setup_keychain() {
259272
append_env "${GITHUB_ENV:-}" MACOS_CERTIFICATE_NAME "$codesign_identity"
260273
append_env "${GITHUB_ENV:-}" MACOS_KEYCHAIN_PATH "$keychain_path"
261274
append_env "${GITHUB_ENV:-}" MACOS_SIGNING_STATE_PATH "$state_path"
262-
append_env "${GITHUB_ENV:-}" PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH "$profile_path"
275+
append_env "${GITHUB_ENV:-}" PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH "$browseros_profile_path"
276+
append_env "${GITHUB_ENV:-}" PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH "$browserclaw_profile_path"
263277
append_env "${GITHUB_OUTPUT:-}" codesign_identity "$codesign_identity"
264278
append_env "${GITHUB_OUTPUT:-}" keychain_path "$keychain_path"
265-
append_env "${GITHUB_OUTPUT:-}" passkey_profile_path "$profile_path"
279+
append_env "${GITHUB_OUTPUT:-}" browseros_passkey_profile_path "$browseros_profile_path"
280+
append_env "${GITHUB_OUTPUT:-}" browserclaw_passkey_profile_path "$browserclaw_profile_path"
266281
append_env "${GITHUB_OUTPUT:-}" state_path "$state_path"
267282
trap - ERR
268283
}
@@ -277,7 +292,8 @@ cleanup_keychain() {
277292
fi
278293

279294
local cert_path=""
280-
local profile_path=""
295+
local browseros_profile_path=""
296+
local browserclaw_profile_path=""
281297
local keychain_path=""
282298
local original_default_keychain=""
283299
local original_keychains_file=""
@@ -286,7 +302,8 @@ cleanup_keychain() {
286302
while IFS= read -r state_line; do
287303
case "$state_line" in
288304
cert_path=*) cert_path="${state_line#cert_path=}" ;;
289-
profile_path=*) profile_path="${state_line#profile_path=}" ;;
305+
browseros_profile_path=*) browseros_profile_path="${state_line#browseros_profile_path=}" ;;
306+
browserclaw_profile_path=*) browserclaw_profile_path="${state_line#browserclaw_profile_path=}" ;;
290307
keychain_path=*) keychain_path="${state_line#keychain_path=}" ;;
291308
original_default_keychain=*) original_default_keychain="${state_line#original_default_keychain=}" ;;
292309
original_keychains_file=*) original_keychains_file="${state_line#original_keychains_file=}" ;;
@@ -319,9 +336,12 @@ cleanup_keychain() {
319336
if owned_cert_path "$cert_path"; then
320337
rm -f "$cert_path"
321338
fi
322-
if owned_profile_path "$profile_path"; then
323-
rm -f "$profile_path"
324-
fi
339+
local profile_path
340+
for profile_path in "$browseros_profile_path" "$browserclaw_profile_path"; do
341+
if owned_profile_path "$profile_path"; then
342+
rm -f "$profile_path"
343+
fi
344+
done
325345
if owned_smoke_path "$smoke_path"; then
326346
rm -f "$smoke_path"
327347
fi

.github/workflows/nightly-macos-product.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ on:
5858
required: true
5959
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64:
6060
required: false
61+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64:
62+
required: false
6163
SENTRY_DSN:
6264
required: true
6365
SPARKLE_PRIVATE_KEY:
@@ -203,6 +205,7 @@ jobs:
203205
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
204206
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
205207
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64: ${{ secrets.PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64 }}
208+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64: ${{ secrets.PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64 }}
206209
shell: bash
207210
run: bash .github/scripts/macos-signing-keychain.sh setup
208211

@@ -225,7 +228,8 @@ jobs:
225228
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
226229
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
227230
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
228-
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH: ${{ steps.macos_signing.outputs.passkey_profile_path }}
231+
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH: ${{ steps.macos_signing.outputs.browseros_passkey_profile_path }}
232+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH: ${{ steps.macos_signing.outputs.browserclaw_passkey_profile_path }}
229233
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
230234
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
231235
PRODUCT: ${{ inputs.product }}

.github/workflows/release-macos.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ on:
111111
required: false
112112
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64:
113113
required: false
114+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64:
115+
required: false
114116
SPARKLE_PRIVATE_KEY:
115117
required: false
116118
SLACK_WEBHOOK_URL:
@@ -338,6 +340,7 @@ jobs:
338340
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
339341
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
340342
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64: ${{ secrets.PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64 }}
343+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64: ${{ secrets.PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64 }}
341344
shell: bash
342345
run: bash .github/scripts/macos-signing-keychain.sh setup
343346

@@ -357,7 +360,8 @@ jobs:
357360
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
358361
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
359362
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
360-
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH: ${{ steps.macos_signing.outputs.passkey_profile_path }}
363+
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH: ${{ steps.macos_signing.outputs.browseros_passkey_profile_path }}
364+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH: ${{ steps.macos_signing.outputs.browserclaw_passkey_profile_path }}
361365
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
362366
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
363367
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}

packages/browseros/.env.example

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ MACOS_CERTIFICATE_NAME=
1111
PROD_MACOS_NOTARIZATION_APPLE_ID=
1212
PROD_MACOS_NOTARIZATION_TEAM_ID=
1313
PROD_MACOS_NOTARIZATION_PWD=
14-
# Local path to BrowserOS's Developer ID provisioning profile. The profile
15-
# must authorize the public-key-credential entitlement and BrowserOS groups.
14+
# Optional local paths to the app-specific Developer ID profiles. Without a
15+
# profile, the app still signs and runs but macOS platform passkeys stay off.
1616
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH=
17+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH=
1718

1819
# Cloudflare R2
1920
R2_ACCOUNT_ID=

packages/browseros/bos_build/ci_workflow_test.py

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ def test_macos_release_sets_up_ci_keychain_before_build_and_cleans_up(self):
276276
self.assertIn("MACOS_CERTIFICATE_P12", secrets)
277277
self.assertIn("MACOS_CERTIFICATE_PWD", secrets)
278278
self.assertIn("PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64", secrets)
279+
self.assertIn("PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64", secrets)
279280
self.assertLess(setup_index, build_index)
280281
self.assertLess(build_index, cleanup_index)
281282
self.assertLess(cleanup_index, upload_index)
@@ -287,6 +288,7 @@ def test_macos_release_sets_up_ci_keychain_before_build_and_cleans_up(self):
287288
"MACOS_CERTIFICATE_PWD",
288289
"MACOS_KEYCHAIN_PASSWORD",
289290
"PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64",
291+
"PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64",
290292
):
291293
self.assertEqual(setup["env"][name], f"${{{{ secrets.{name} }}}}")
292294
self.assertEqual(
@@ -299,7 +301,11 @@ def test_macos_release_sets_up_ci_keychain_before_build_and_cleans_up(self):
299301
)
300302
self.assertEqual(
301303
build["env"]["PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH"],
302-
"${{ steps.macos_signing.outputs.passkey_profile_path }}",
304+
"${{ steps.macos_signing.outputs.browseros_passkey_profile_path }}",
305+
)
306+
self.assertEqual(
307+
build["env"]["PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH"],
308+
"${{ steps.macos_signing.outputs.browserclaw_passkey_profile_path }}",
303309
)
304310
self.assertEqual(cleanup["if"], "always()")
305311
self.assertEqual(
@@ -1857,16 +1863,28 @@ def test_internal_builder_uses_reservation_and_frozen_artifact_source(self):
18571863
"PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64",
18581864
triggers["workflow_call"]["secrets"],
18591865
)
1866+
self.assertIn(
1867+
"PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64",
1868+
triggers["workflow_call"]["secrets"],
1869+
)
18601870
setup = self.named_step(
18611871
workflow, "build", "Import macOS signing certificate"
18621872
)
18631873
self.assertEqual(
18641874
setup["env"]["PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64"],
18651875
"${{ secrets.PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64 }}",
18661876
)
1877+
self.assertEqual(
1878+
setup["env"]["PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64"],
1879+
"${{ secrets.PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64 }}",
1880+
)
18671881
self.assertEqual(
18681882
build["env"]["PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH"],
1869-
"${{ steps.macos_signing.outputs.passkey_profile_path }}",
1883+
"${{ steps.macos_signing.outputs.browseros_passkey_profile_path }}",
1884+
)
1885+
self.assertEqual(
1886+
build["env"]["PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH"],
1887+
"${{ steps.macos_signing.outputs.browserclaw_passkey_profile_path }}",
18701888
)
18711889
self.assertNotIn("BROWSERCLAW_ONBOARD_RESOURCE_VERSION", build["env"])
18721890
for secret in (
@@ -2453,7 +2471,8 @@ def test_setup_imports_p12_and_cleanup_restores_keychain_state(self):
24532471
smoke_path = self.runner_temp / "browseros-ci-codesign-smoke-123-4"
24542472

24552473
self.assertEqual(outputs["codesign_identity"], self.identity_sha1)
2456-
self.assertEqual(outputs["passkey_profile_path"], "")
2474+
self.assertEqual(outputs["browseros_passkey_profile_path"], "")
2475+
self.assertEqual(outputs["browserclaw_passkey_profile_path"], "")
24572476
self.assertTrue(keychain_path.exists())
24582477
self.assertTrue(state_path.exists())
24592478
self.assertFalse(cert_path.exists())
@@ -2489,27 +2508,37 @@ def test_setup_imports_p12_and_cleanup_restores_keychain_state(self):
24892508
self.assertFalse(keychain_path.exists())
24902509
self.assertFalse(state_path.exists())
24912510

2492-
def test_setup_decodes_passkey_profile_and_cleanup_removes_it(self):
2511+
def test_setup_decodes_both_passkey_profiles_and_cleanup_removes_them(self):
24932512
result = self._run_helper(
24942513
"setup",
24952514
PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64="cHJvZmlsZS1ieXRlcw==",
2515+
PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64="Y2xhdy1wcm9maWxlLWJ5dGVz",
24962516
)
24972517
self.assertEqual(result.returncode, 0, result.stderr + result.stdout)
24982518
outputs = self._outputs()
2499-
profile_path = Path(outputs["passkey_profile_path"])
2500-
self.assertEqual(profile_path.read_bytes(), b"profile-bytes")
2501-
self.assertEqual(profile_path.stat().st_mode & 0o777, 0o600)
2519+
browseros_profile_path = Path(outputs["browseros_passkey_profile_path"])
2520+
browserclaw_profile_path = Path(outputs["browserclaw_passkey_profile_path"])
2521+
self.assertEqual(browseros_profile_path.read_bytes(), b"profile-bytes")
2522+
self.assertEqual(browserclaw_profile_path.read_bytes(), b"claw-profile-bytes")
2523+
self.assertEqual(browseros_profile_path.stat().st_mode & 0o777, 0o600)
2524+
self.assertEqual(browserclaw_profile_path.stat().st_mode & 0o777, 0o600)
2525+
env_lines = self.github_env.read_text(encoding="utf-8").splitlines()
25022526
self.assertIn(
2503-
f"PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH={profile_path}",
2504-
self.github_env.read_text(encoding="utf-8").splitlines(),
2527+
f"PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH={browseros_profile_path}",
2528+
env_lines,
2529+
)
2530+
self.assertIn(
2531+
f"PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH={browserclaw_profile_path}",
2532+
env_lines,
25052533
)
25062534

25072535
cleanup = self._run_helper(
25082536
"cleanup",
25092537
MACOS_SIGNING_STATE_PATH=outputs["state_path"],
25102538
)
25112539
self.assertEqual(cleanup.returncode, 0, cleanup.stderr + cleanup.stdout)
2512-
self.assertFalse(profile_path.exists())
2540+
self.assertFalse(browseros_profile_path.exists())
2541+
self.assertFalse(browserclaw_profile_path.exists())
25132542

25142543
def test_setup_uses_fingerprint_when_common_name_is_duplicated(self):
25152544
result = self._run_helper("setup", CODESIGN_REJECT_COMMON_NAME="1")

packages/browseros/bos_build/docs/nightly-macos-ci.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ Run the Mac runner in the logged-in GUI user's session. Codesign and
239239
BrowserOS's base64-encoded Developer ID provisioning profile. The signing
240240
helper decodes it into runner-owned temporary storage; BrowserOS validates
241241
and embeds it, and unconditional cleanup removes the temporary copy.
242+
- The `PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64` repository secret containing
243+
BrowserOS neo's profile for `com.browseros.BrowserClaw`. Apple profiles are
244+
App-ID-specific, so the BrowserOS profile cannot be reused for neo even though
245+
both apps use the same signing team and certificate.
246+
- Both profile secrets are optional while Apple approval is pending. A missing
247+
profile leaves the corresponding app normally signed and usable but without
248+
macOS platform passkeys. A configured but invalid profile fails before the
249+
long build so releases cannot silently ship the wrong App ID authorization.
242250
- Enough disk for two Chromium outputs and DMGs.
243251

244252
Set these repository variables:

packages/browseros/bos_build/docs/release-ci.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,19 @@ matching signing key and build-time secrets.
210210

211211
Windows signing needs the eSigner secrets and `SPARKLE_PRIVATE_KEY`. macOS uses
212212
repository variables `BROWSEROS_REPO_PATH` and `BROWSEROS_CHROMIUM_SRC` plus
213-
the signing and notarization secrets on the persistent builder. Signed
214-
BrowserOS releases also require `PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64`, a
215-
base64-encoded Developer ID provisioning profile for
216-
`com.browseros.BrowserOS`. The profile must authorize team `8YMKWU47S5`, the
217-
BrowserOS keychain groups, and
213+
the signing and notarization secrets on the persistent builder. Signed macOS
214+
releases require separate base64-encoded Developer ID provisioning profiles:
215+
`PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64` for `com.browseros.BrowserOS` and
216+
`PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64` for
217+
`com.browseros.BrowserClaw`. Each profile must authorize team `8YMKWU47S5`, its
218+
bundle-specific keychain groups, and
218219
`com.apple.developer.web-browser.public-key-credential`; the build validates
219-
those claims before signing. BrowserOS neo does not consume this app-specific
220-
profile.
220+
those claims before signing. The profiles are not interchangeable because
221+
Apple assigns the managed capability to an exact App ID.
222+
Until Apple approves a profile, its secret may remain unset: the corresponding
223+
browser still builds, signs, and runs with the standard entitlements, but macOS
224+
platform passkeys are unavailable. Once a secret is configured, a missing,
225+
wrong, or malformed profile is a hard release error.
221226
`BROWSEROS_CHROMIUM_SRC` is a dedicated, CI-owned APFS clone base. Setup keeps
222227
its pinned Chromium identity strict but repairs local Git changes and
223228
BrowserOS-owned output directories before the release runs against a disposable

packages/browseros/bos_build/lib/env.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"MACOS_CERTIFICATE_PWD",
2525
"MACOS_KEYCHAIN_PASSWORD",
2626
"POSTHOG_API_KEY",
27+
"PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_B64",
2728
"PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_B64",
2829
"PROD_MACOS_NOTARIZATION_PWD",
2930
"R2_SECRET_ACCESS_KEY",
@@ -127,6 +128,11 @@ def macos_browseros_passkey_profile_path(self) -> Optional[str]:
127128
"""Developer ID profile authorizing BrowserOS platform passkeys."""
128129
return os.environ.get("PROD_MACOS_BROWSEROS_PASSKEY_PROFILE_PATH")
129130

131+
@property
132+
def macos_browserclaw_passkey_profile_path(self) -> Optional[str]:
133+
"""Developer ID profile authorizing BrowserOS neo platform passkeys."""
134+
return os.environ.get("PROD_MACOS_BROWSERCLAW_PASSKEY_PROFILE_PATH")
135+
130136
@property
131137
def macos_keychain_password(self) -> Optional[str]:
132138
"""macOS login keychain password (used to unlock keychain on build servers)"""

0 commit comments

Comments
 (0)