Problem
gh-gate currently stores the GitHub App private key via biokc, a small Swift helper that gates Keychain reads behind Touch ID. This improves UX and avoids plain file storage, but the private key itself is still a generic Keychain secret. Touch ID is enforced by the helper before release, not by a Secure Enclave-backed cryptographic key.
The desired property is stronger at-rest protection: the GitHub App PEM should only be recoverable through a non-exportable Secure Enclave key that requires local user presence.
Goal
Replace or augment biokc with a storage path where:
- the GitHub App private key is encrypted at rest
- the decrypting key is non-exportable and Secure Enclave-backed
- retrieval requires Touch ID/passcode user presence
gh-gate grant can still obtain the PEM briefly to sign GitHub App JWTs
- migration from the current Keychain/
biokc setup is explicit and reversible
Candidate approach
Use age + age-plugin-se:
- generate a Secure Enclave-backed age identity
- encrypt the GitHub App PEM to that recipient
- store:
~/.config/gh-gate/se-identity.txt
~/.config/gh-gate/private-key.pem.age
- update
gh-gate to decrypt via age when minting a token
- add a one-shot migration command from the existing
biokc storage
Suggested access policy: any-biometry-or-passcode, unless stricter Touch ID-only semantics are preferred later.
Notes
This does not make GitHub App signing happen inside Secure Enclave. GitHub App auth still requires an RS256 JWT signed with the App private key, so gh-gate will still need the plaintext PEM briefly in process memory.
The improvement is at-rest protection and removal of bespoke biometric Keychain helper code.
Problem
gh-gatecurrently stores the GitHub App private key viabiokc, a small Swift helper that gates Keychain reads behind Touch ID. This improves UX and avoids plain file storage, but the private key itself is still a generic Keychain secret. Touch ID is enforced by the helper before release, not by a Secure Enclave-backed cryptographic key.The desired property is stronger at-rest protection: the GitHub App PEM should only be recoverable through a non-exportable Secure Enclave key that requires local user presence.
Goal
Replace or augment
biokcwith a storage path where:gh-gate grantcan still obtain the PEM briefly to sign GitHub App JWTsbiokcsetup is explicit and reversibleCandidate approach
Use
age+age-plugin-se:~/.config/gh-gate/se-identity.txt~/.config/gh-gate/private-key.pem.agegh-gateto decrypt viaagewhen minting a tokenbiokcstorageSuggested access policy:
any-biometry-or-passcode, unless stricter Touch ID-only semantics are preferred later.Notes
This does not make GitHub App signing happen inside Secure Enclave. GitHub App auth still requires an
RS256JWT signed with the App private key, sogh-gatewill still need the plaintext PEM briefly in process memory.The improvement is at-rest protection and removal of bespoke biometric Keychain helper code.