feat: OS-keychain secret storage — keys never sit in config files - #16
Open
amos-aios wants to merge 1 commit into
Open
feat: OS-keychain secret storage — keys never sit in config files#16amos-aios wants to merge 1 commit into
amos-aios wants to merge 1 commit into
Conversation
PLAT-04 (密钥仅存 OS 钥匙串): api_key gains a third indirection form 'keychain:ACCOUNT', resolved at config-parse time from the operating system's credential store (macOS Keychain / Windows Credential Manager / Linux Secret Service) — the file holds only the account name, and the plaintext key reaches nothing on disk. Headless hosts fail loudly with the storing command in the error; no silent plaintext fallback. 'mofa-engine keychain-set/get/delete --account …' manages entries (value via stdin keeps keys out of shell history). Tests run against a persistent in-process stand-in (keyring's own mock is EntryOnly, which cannot round-trip); verified against the real macOS Keychain: store → get → delete → system search confirms removal. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Provider credentials can now live in the OS keychain instead of config files — closing the "密钥仅存 OS 钥匙串" hard constraint from studio's PRD (PLAT-04).
api_keygains a third indirection form alongside${VAR}/env:VAR:The file holds only the account name; the plaintext key reaches nothing on disk, and the rest of the engine only ever sees the real key in memory.
Backed by the
keyringcrate: macOS Keychain, Windows Credential Manager, Linux Secret Service. Hosts without a credential store fail loudly (with the storing command named in the error) — never a silent plaintext fallback.New CLI subcommands:
mofa-engine keychain-set / keychain-get / keychain-delete --account …(--valueoptional; reading one line from stdin keeps keys out of shell history).secrets::available()probes the store (write+delete) for diagnostics.Testing
5 new tests: full store/load/overwrite/delete round trip, idempotent delete + missing-entry loads, empty-account rejection, availability probe, and the config-resolve chain (
keychain:ACCOUNT→ value, near-miss literals pass through untouched, missing entry errors name the fix command). Tests run against a persistent in-process stand-in — keyring's bundled mock is EntryOnly (password lives inside each Entry), so it cannot round-trip; the stand-in mirrors a real keychain's cross-entry persistence. Verified against the real macOS Keychain:keychain-set → keychain-get → keychain-delete → security find-generic-passwordconfirms removal.Full workspace suite green (192 in engine-core).
🤖 Generated with Claude Code