hosystem Engagements

ho-04.3 — Sign the dev binary; verify Keychain biometry end-to-end

created 2026-07-02
status complete
type ho-document
project sharibako
ho 04.3
kamae 5
shape ri
agent-tasks
  • Ho-04.3-AT-01.md

Add codesign to scripts/install.sh using the practitioner's existing Developer ID Application certificate. Sign with hardened runtime, empty entitlements (biometry-gated Keychain access doesn't require specific entitlements — only a stable signing identity). Verify end-to-end that sharibako key generate on the signed binary prompts Touch ID, writes to Keychain, and sharibako key export --private --i-know-this-is-plaintext re-prompts and retrieves.

Ri- . Small, surgical, well-understood. The practitioner has signed CLIs before via the M4Bmaker pipeline; this ho reuses that discipline for sharibako with product-specific entitlements.

Out of scope:

Resolves:


Problem

sharibako key generate on macOS hits errSecMissingEntitlement (-34018) when writing a Keychain item with SecAccessControl .userPresence. This is Apple's security model: unsigned binaries have no stable signing identity, and Keychain refuses biometry-gated access to items whose owner can't be established. The Swift code path in AT-01 is correct; the binary just lacks a signing identity.

All AT-01 and AT-02 dogfooding uses the --age-key <path> bypass instead. That's fine for the file-based verbs but leaves the Keychain path unverified in production shape.

Solution

Sign the release binary during install.sh with the practitioner's Developer ID Application cert (Developer ID Application: ANDREW TODD MARCUS (3N8F759K8D)). Empty entitlements plist (biometry doesn't need special entitlements — only a stable identity). Hardened runtime (--options runtime) both for security posture and to keep the door open to Phase 6 notarization without rework.

On non-macOS platforms, install.sh skips signing with a warning and installs the raw binary (the --age-key file path remains the primary Linux flow).

Changes

Signing invocation:

codesign \
    --sign "Developer ID Application: ANDREW TODD MARCUS (3N8F759K8D)" \
    --entitlements sharibako.entitlements \
    --options runtime \
    --timestamp \
    --force \
    .build/release/sharibako

Then a pass immediately after:

codesign --verify --verbose .build/release/sharibako
spctl --assess --type execute --verbose .build/release/sharibako

Both should exit 0. spctl may print "rejected" if the binary isn't notarized — that's expected for local signing and doesn't block Keychain access. The codesign --verify check is what matters.

Results

Done means:

Not required:

Deferred to execution:


What actually shipped (reconcile, 2026-07-03)

The drafted Solution — sign the raw binary with an empty entitlements plist, on the premise that "biometry doesn't need special entitlements, only a stable identity" — did not work. It resolved the "Deferred to execution" question ("whether the entitlements file needs additions beyond empty") in the direction the ho left open: it needs more than empty, and more than a bare signature.

What scripts/install.sh actually does:

This is a materially different mechanism from the drafted one, but it lands the same deliverable — a signed install whose Keychain path works with Touch ID. The Problem section (the -34018 / errSecMissingEntitlement blocker) and the Out-of-scope boundaries (no notarization, no DMG, no Swift changes) all held.

Reflect

Signing shipped and is verified end-to-end. The verification came for free while closing ho-04.5: on 2026-07-03, sharibako run --scope diary against the signed install prompted Touch ID, read the age key from the Keychain, and decrypted every secret — the exact biometry-gated Keychain path this ho exists to prove. errSecMissingEntitlement (-34018) is gone; the raw-binary debug build instead fails with errSecItemNotFound (-25300) because it isn't in the access group, which is the expected and correct behaviour (captured in project memory as the gate).


Authored: 2026-07-02. Executed, reconciled, and closed: 2026-07-03.

Rendered from the corpus, verbatim · source on GitHub →

ingested: sharibako @ a97b22af9b61 · ho-system @ 79e96b801a13 · the glossary · the colophon