Skip to main content

max / goingson

build-keychain: unique keychain + search-list per run Fix the 2026-07-21 Bento audit finding (C3): a fixed keychain path and one shared search-list state file let two concurrent macOS builds on the same Mac collide — the second's `security delete-keychain` wiped the first's keychain mid-codesign, and both stomped one search-list file so teardown restored a polluted list. Default BUILD_KEYCHAIN to a mktemp-unique path (stable across a process's bk_setup/bk_teardown, distinct per run) and derive the state file from it. Override still honored for a pinned standalone setup/teardown. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-24 00:31 UTC
Commit: 0a960fff4f5f530e652ccec7a0fa30005609d50b
Parent: e0bb57f
1 file changed, +18 insertions, -6 deletions
@@ -25,6 +25,9 @@
25 25 # # teardown runs on exit
26 26 #
27 27 # --- Usage (standalone, for inspection/debugging) ---
28 + # # setup + teardown run as SEPARATE processes, so pin the keychain path so
29 + # # both agree (the default is unique per process — see BUILD_KEYCHAIN below):
30 + # export BUILD_KEYCHAIN="${TMPDIR:-/tmp}/bento-build.debug.keychain-db"
28 31 # ./dist/build-keychain.sh setup # leaves the keychain in place
29 32 # ./dist/build-keychain.sh identity # print the Developer ID identity it holds
30 33 # ./dist/build-keychain.sh teardown # remove it + restore the search list
@@ -52,12 +55,21 @@ set -euo pipefail
52 55 # A FULL PATH, not a bare name. Over SSH `security create-keychain` with a bare
53 56 # name tries ~/Library/Keychains/ and fails "SecKeychainCreate ... Permission
54 57 # denied"; a full path in $TMPDIR works headlessly (the CI-standard approach).
55 - # Override with BUILD_KEYCHAIN if you need a different location.
56 - : "${BUILD_KEYCHAIN:=${TMPDIR:-/tmp}/bento-build.keychain-db}"
57 -
58 - # Path used to stash the original keychain search list across setup/teardown so a
59 - # standalone teardown (separate process) can still restore it.
60 - _BK_STATE_FILE="${TMPDIR:-/tmp}/.bento-build-keychain.searchlist"
58 + #
59 + # UNIQUE PER RUN. A fixed path (`bento-build.keychain-db`) let two macOS builds
60 + # on the same Mac collide: the second's `security delete-keychain` (bk_setup
61 + # below) wiped the first's keychain mid-codesign, and both stomped one shared
62 + # search-list state file, so teardown restored a polluted list. `mktemp -u`
63 + # mints an unused name once, at source time, so it is stable across this
64 + # process's bk_setup + bk_teardown yet distinct from any concurrent run.
65 + # Override with BUILD_KEYCHAIN to pin a location (e.g. to pair a standalone
66 + # `setup` and `teardown` that run as separate processes).
67 + : "${BUILD_KEYCHAIN:=$(mktemp -u "${TMPDIR:-/tmp}/bento-build.XXXXXX").keychain-db}"
68 +
69 + # The original keychain search list is stashed here across setup/teardown.
70 + # Derived from BUILD_KEYCHAIN so it is unique-and-paired with it: a concurrent
71 + # run saves/restores its own list rather than sharing one file.
72 + _BK_STATE_FILE="${BUILD_KEYCHAIN%.keychain-db}.searchlist"
61 73
62 74 _bk_require_env() {
63 75 local missing=0