feat(config): macOS Keychain credential storage#8
Open
rupjae wants to merge 3 commits into
Open
Conversation
Passwords stored as plaintext in config.toml is a security concern, especially since the file is written with default permissions (0644). This patch adds macOS Keychain integration so credentials never touch disk, and hardens file permissions as a defense-in-depth measure. - Add keychain.ts: store/retrieve passwords via macOS `security` CLI - Config loader resolves password = "keychain" from Keychain at runtime - saveConfig now writes config dir as 0700 and config file as 0600 - Schema validation updated to mention keychain option - Template default changed to password = "keychain" On non-macOS platforms, behavior is unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
wgs4
referenced
this pull request
in wgs4/email-mcp
Mar 9, 2026
Fixes critical bug where APPEND targeted a ghost "Sent" folder instead of the account's actual INBOX.Sent (with \Sent special-use attribute). Also addresses 8 additional issues from code review. Bug fixes: - #0: Fix resolveSentFolder to properly detect SPECIAL-USE \Sent, reorder fallback names (INBOX.Sent first), throw on unresolvable - #1: Add mailbox lock around IMAP APPEND operations - #2: Add Content-Transfer-Encoding: 8bit header - #3: Normalize body line endings to CRLF per RFC 5322 - #4: Generate fallback Message-ID when nodemailer returns none - #5: Replace unsafe type casts with runtime guards - #6: RFC 2047 encode non-ASCII subject lines - #7: Auto-create Sent folder on TRYCREATE with single retry - #8: Add sendDraft APPEND test coverage (3 new tests) Co-Authored-By: Claude Opus 4.6 <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.
Summary
Ran a security audit on this project before deploying it (as one does when handing over email credentials). The code is clean, well-structured, no telemetry, no phoning home, solid input validation. Genuinely impressed.
One thing jumped out though: passwords sitting in plaintext in
config.tomlwith 0644 permissions. Any process on the machine can read them. On macOS, we have Keychain for exactly this.This PR adds:
keychain.ts: macOS Keychain integration via thesecurityCLI. Store/retrieve passwords without touching disk.password = "keychain", the loader resolves the real password from Keychain at runtime. Credentials never land in the TOML file.saveConfignow writes the config dir as0700and config file as0600, even for users who still use plaintext passwords.On non-macOS platforms, behavior is completely unchanged. Existing plaintext passwords still work, just with better file permissions now.
Usage
How we found it
We audited the full codebase before deploying. Read every file, checked all network calls, reviewed dependencies, traced credential flow. The audit came back CAUTION (not SAFE) solely because of the plaintext password issue. Everything else was solid.
We also noticed that Copilot contributed 24 commits with 18,285 lines added (vs Colin's 66 commits). No shade, the code quality is genuinely good regardless of who (or what) wrote it. But we figured if Copilot is going to mass-produce 47 tools, a human should probably circle back and make sure the credentials aren't just vibing in a world-readable file. Consider this that circle-back.
Test plan
🤖 Generated with Claude Code