A small, code-signed macOS command-line tool for reading and writing Keychain items through Security.framework.
Status: early prototype. The four core operations work. The code talks to Security.framework and Core Foundation directly right now, which is a deliberate spike. A safe wrapper over those APIs is the next step, and the interface may still change.
macOS ships the security CLI, but an item it creates can't be read back by a script without a Touch ID or password prompt, because the script isn't in the item's access-control list. rune-keychain is a signed binary, so it can be added to an item's trusted-application ACL and then read that item without prompting. It exists to replace the security calls in my dotfiles secrets setup, where reading a secret currently means a Touch ID tap or a typed password every time. The aim is to keep secrets encrypted on disk and let a trusted, signed binary decrypt them on demand, with no prompt in the way.
This is plumbing. One invocation does one thing: get, set, delete, or check a single item.
- macOS
- A code-signing identity (self-signed is fine for local use)
- go-task for the build and sign workflow
Every build re-signs, since the signature is tied to the binary's hash.
cp .env.example .env # set SIGNING_IDENTITY
task build # cargo build --release + codesignService and account name the item. The subcommand picks the operation.
# read a password to stdout
rune-keychain --service my-service --account my-account get
# store one (pipe it in so the secret stays out of shell history)
printf '%s' "$SECRET" | rune-keychain -s my-service -a my-account set --stdin
# check existence (exit code only)
rune-keychain -s my-service -a my-account exists
# remove it
rune-keychain -s my-service -a my-account delete--sync targets the iCloud keychain and --keychain <path> targets a specific keychain file. On set, --trust <path> adds a binary to the item's trusted-application ACL, and --create-only fails if the item already exists.
Working today: get, set, delete, and exists, with trusted-app ACLs and iCloud sync on set.
It's early, so the list is long. The near-term direction:
- A safe wrapper over the Core Foundation and Security.framework calls, so the rest of the code stops handling raw pointers. This is the main reason the project paused.
- Access-control constraints on stored items via
SecAccessControl: Touch ID, passcode, Apple Watch, and an application password for the cases a signed ACL can't cover. - More operations:
listto enumerate a service's items,inspectto dump an item's metadata and trust list, andmigrateto move an item between the local and iCloud keychains. - Editing the trusted-application ACL on an existing item (
--trust-add/--trust-remove), instead of only setting it at creation. - Pulling the keychain layer into its own crate once the patterns settle, so other tools can build on it. The first is a Touch ID pinentry for GPG: pinentry-touchid has been dormant for years and the pinentry-mac it builds on was archived in 2021, so a maintained replacement is worth having.
MIT. See LICENSE.