Skip to content

Add TOML config file support (~/.keyclaw/config.toml)#62

Open
GuthL wants to merge 13 commits intomainfrom
feature/toml-config-file
Open

Add TOML config file support (~/.keyclaw/config.toml)#62
GuthL wants to merge 13 commits intomainfrom
feature/toml-config-file

Conversation

@GuthL
Copy link
Owner

@GuthL GuthL commented Mar 9, 2026

Summary

  • Adds ~/.keyclaw/config.toml as an alternative to env vars for steady-state configuration
  • Flat TOML keys mirror env var names without the KEYCLAW_ prefix (e.g., proxy_addr, log_level, entropy_threshold)
  • Precedence: env var > config file > hardcoded default
  • Missing config file silently falls back to env+defaults (not an error)
  • Parse errors log a warning and fall back to env+defaults
  • keyclaw doctor gains a config-file check that validates the file

Closes #55

Example config

log_level = "debug"
notice_mode = "minimal"
entropy_threshold = 4.0
codex_hosts = "api.openai.com,chat.openai.com"

Test plan

  • Config file values are read and applied
  • Env vars override config file values
  • Missing config file uses defaults
  • validate_config_file() returns key count, None, or error
  • Doctor check reports config file status
  • Full test suite passes (186 tests, 0 failures)

🤖 Generated with Claude Code

GuthL added 12 commits March 8, 2026 13:16
docs/ was in .gitignore but tests/production_readiness_docs.rs reads
docs/plans/ files at runtime, causing CI to fail with NotFound on
every clean checkout.
Add entropy-based secret detection as a complementary pass alongside
regex rules. Tokens with Shannon entropy >= 3.5 and length >= 20 are
flagged, catching base64-encoded API keys and similar machine-generated
secrets that regex patterns may miss. The entropy pass runs after regex
matching and skips overlapping matches and existing placeholders.
Replace the split+find offset calculation with a char_indices-based
manual tokenizer. The previous approach could misidentify byte offsets
when segments repeated or consecutive delimiters appeared. Also fix
module-level doc comments from /// to //!.
The test verifies that empty gitleaks rules produce no redaction.
With entropy detection now active, the high-entropy test secret
gets caught even without regex rules. Disable entropy for this
specific test to preserve its original intent.
Verifies that a high-entropy token not matched by any gitleaks
regex rule is still caught and redacted by the entropy analyzer.
Parse the `entropy` field from gitleaks rules and use it as a
minimum Shannon entropy threshold for regex matches. 130 bundled
rules define this field — matches with entropy below the threshold
are now discarded as likely false positives.

Closes #54
The per-rule entropy threshold on generic-api-key (≥3.5) filtered out
the low-entropy test UUIDs (entropy ~2.42). Replace with realistic
UUIDs (entropy ~3.9) and fix all rustfmt violations.
Load settings from ~/.keyclaw/config.toml with env var > config file >
hardcoded default precedence. Add doctor check for config file validity
and validate_config_file() public API.
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5385cff42b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +260 to +261
Some("user") | None => true,
Some(_) => false,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact non-user message content before forwarding

Restricting rewrite_message_content_fields to role == "user" means assistant/developer/system entries in messages/input are no longer scanned. In multi-turn chat flows, clients resend prior assistant turns; if an earlier response contained a reinjected secret, that secret is now forwarded upstream unredacted on subsequent requests, which breaks the proxy’s core secret-protection behavior.

Useful? React with 👍 / 👎.


fn load_config_file() -> Option<FileMap> {
let path = config_file_path();
let content = std::fs::read_to_string(&path).ok()?;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Report unreadable config files instead of silently skipping

Using read_to_string(...).ok()? treats every read failure as if the config file were absent, so permission/I/O errors silently fall back to env/defaults with no warning. That makes production misconfiguration hard to detect because only TOML parse failures are logged; non-NotFound read errors should be surfaced or warned.

Useful? React with 👍 / 👎.

@GuthL GuthL force-pushed the feature/toml-config-file branch from 5385cff to cd910c5 Compare March 9, 2026 21:36
@GuthL GuthL force-pushed the feature/toml-config-file branch 2 times, most recently from a3b46b2 to 51caafd Compare March 11, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant