Repository navigation
Description
Why: Gatehouse §6.10 (lines 837 and 839) requires hardware-backed, non-exportable custody for the proxy's sealing, root and signing keys. The #2436 probe of 2026-10-31 (result) ran the Developer-ID-signed, notarized bep from #2792. The login keychain gave it an exportable key, so bep refused it with "the keychain made the key exportable". Signing alone is not enough. An installed Mac cannot run the proxy until this lands, so T102 (#2772) waits on it.
Waits on: nothing. gominimal/inbox#1187 is done: the App ID dev.minimal.bep and the Developer ID provisioning profile exist, and the release has the secret MACOS_BEP_PROVISION_PROFILE (2026-10-31).
Work
- Keys in the Secure Enclave (
crates/bep/src/keys.rs,keys::keychain):- Generate each role's key with
kSecAttrTokenIDSecureEnclave,kSecUseDataProtectionKeychain,kSecAttrIsPermanent, and access controlkSecAttrAccessibleWhenUnlockedThisDeviceOnly. - Use the access group
3G47C5HY64.dev.minimal.bep(kSecAttrAccessGroup). - Find, load, relabel and remove calls use the data-protection keychain and the same group.
- The keys stay P-256. Check that every use of the sealing, root and signing keys is ECDSA or ECDH on P-256, the operations the Secure Enclave supports.
- Debug b 8000 uilds keep the T111 behaviour (T111 — Accept a key the keychain made exportable in a debug build of bep, and scope the custody rule to release builds #2785): an exportable key with a warning, because a debug build cannot hold the entitlement.
- Generate each role's key with
- Bundle and entitlement (
.github/workflows/release.yml,scripts/stage-release.sh, the installer):- Ship
bep.app/Contents/MacOS/bep, with the profile atbep.app/Contents/embedded.provisionprofile. Info.plistsetsCFBundleIdentifier=dev.minimal.bep.- Sign with
--options runtime --timestamp --entitlements bep.entitlementsand the identifierdev.minimal.bep, then notarize. - The entitlements are
com.apple.application-identifier=3G47C5HY64.dev.minimal.bep,com.apple.developer.team-identifier=3G47C5HY64, andkeychain-access-groups= [3G47C5HY64.dev.minimal.bep]. resolve_bep_binaryfinds the inner binary.release.ymlis frozen, so that edit needs owner sign-off, as feat(release): ship a signed, notarized bep beside minvmd on macOS #2792 did.
- Ship
- Migration:
- Keys in the login keychain cannot move. The first start of a release
bepwith this change has no keys in the data-protection keychain. Decide whether it generates them, or whether the operator runsbep --replace-key. - Document that Secure Enclave keys do not survive a device migration or reset, and that values sealed to them must be sealed again.
- Keys in the login keychain cannot move. The first start of a release
- Proof (closes Prove non-exportable key custody on a real keychain (BEP, Gatehouse §6.10) #2436 for macOS): run the Prove non-exportable key custody on a real keychain (BEP, Gatehouse §6.10) #2436 probe on the bundled release
bep. A key is created with no exportable refusal, andSecKeyCopyExternalRepresentationfails on it.
Not verified yet: the Secure Enclave path on a real Mac. A short Swift probe signed with a development provisioning profile can confirm it before the bundle work starts.
Out of scope: the Linux backend (OQ4), which stays on #2436.
Epic #1501. Spec: docs/specs/24-spec-box-egress-proxy/24-spec-box-egress-proxy.md (BEP-014, BEP-059 to BEP-061).
Activity
minimal-foundry commentedon Oct 31, 2026
Refused: body is not a rendered task or spike (no
<!-- plan:v1 ... -->marker and## Task/## Spikeon line 3).epic #1501
Updated 2026-10-31T19:01:32.590Z.
feat(bep): hold the proxy's keys in the Secure Enclave inside bep.app
feat(bep): hold the proxy's keys in the Secure Enclave inside bep.app (…
norrietaylor commentedon Nov 5, 2026
Proof passed on the bundled release
bep. This closes the issue.0.8.0-dev.381.g3c2b2a73, installed fromunstablewith itsinstall.sh.bep.appis Developer ID signed, notarized, hardened runtime, Team3G47C5HY64, identifierdev.minimal.bep.bep --replace-key sealing --identity <temp>/identity.jsonexits 0. The 2026-10-31 signed binary got "the keychain made the key exportable" from the same command.--replace-keyforsealing,rootandsigningagainst the realidentity.jsoneach exit 0.A release build runs the same
custody()check on every key, and that check refuses any key whoseSecKeyCopyExternalRepresentationsucceeds. So exit 0 means the call failed on all three keys.bep_first_slice_end_to_endalso passes against these installed binaries, withMINVMD_BEP_BINunset, so the installedminvmdstarts the bundledbep.Generated by Claude Code