8000 Hold the BEP keys in the Secure Enclave, with bep bundled under a provisioning profile · Issue #2812 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

Hold the BEP keys in the Secure Enclave, with bep bundled under a provisioning profile #2812

Closed

Description

@norrietaylor

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

  1. Keys in the Secure Enclave (crates/bep/src/keys.rs, keys::keychain):
    • Generate each role's key with kSecAttrTokenIDSecureEnclave, kSecUseDataProtectionKeychain, kSecAttrIsPermanent, and access control kSecAttrAccessibleWhenUnlockedThisDeviceOnly.
    • 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.
  2. Bundle and entitlement (.github/workflows/release.yml, scripts/stage-release.sh, the installer):
    • Ship bep.app/Contents/MacOS/bep, with the profile at bep.app/Contents/embedded.provisionprofile.
    • Info.plist sets CFBundleIdentifier = dev.minimal.bep.
    • Sign with --options runtime --timestamp --entitlements bep.entitlements and the identifier dev.minimal.bep, then notarize.
    • The entitlements are com.apple.application-identifier = 3G47C5HY64.dev.minimal.bep, com.apple.developer.team-identifier = 3G47C5HY64, and keychain-access-groups = [3G47C5HY64.dev.minimal.bep].
    • resolve_bep_binary finds the inner binary.
    • release.yml is frozen, so that edit needs owner sign-off, as feat(release): ship a signed, notarized bep beside minvmd on macOS #2792 did.
  3. Migration:
    • Keys in the login keychain cannot move. The first start of a release bep with this change has no keys in the data-protection keychain. Decide whether it generates them, or whether the operator runs bep --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.
  4. 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, and SecKeyCopyExternalRepresentation fails 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

  1. minimal-foundry commented on Oct 31, 2026

    @minimal-foundry
    Contributor

    Refused: body is not a rendered task or spike (no <!-- plan:v1 ... --> marker and ## Task/## Spike on line 3).

    epic #1501

    Updated 2026-10-31T19:01:32.590Z.

  2. norrietaylor commented on Nov 5, 2026

    @norrietaylor
    MemberAuthor

    Proof passed on the bundled release bep. This closes the issue.

    • Build: 0.8.0-dev.381.g3c2b2a73, installed from unstable with its install.sh. bep.app is Developer ID signed, notarized, hardened runtime, Team 3G47C5HY64, identifier dev.minimal.bep.
    • Host: macOS 26, arm64.
    • The Prove non-exportable key custody on a real keychain (BEP, Gatehouse §6.10) #2436 probe: bep --replace-key sealing --identity <temp>/identity.json exits 0. The 2026-10-31 signed binary got "the keychain made the key exportable" from the same command.
    • --replace-key for sealing, root and signing against the real identity.json each exit 0.

    A release build runs the same custody() check on every key, and that check refuses any key whose SecKeyCopyExternalRepresentation succeeds. So exit 0 means the call failed on all three keys.

    bep_first_slice_end_to_end also passes against these installed binaries, with MINVMD_BEP_BIN unset, so the installed minvmd starts the bundled bep.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0