feat: make TLS certificate verification configurable#1893
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements a new configuration setting, insecure_skip_tls_verify, and a corresponding environment variable, DEEPSEEK_INSECURE_SKIP_TLS_VERIFY, to allow users to bypass TLS certificate verification for outbound HTTPS requests. This change affects multiple modules, including the CLI update mechanism, skill management, MCP connections, and various network-dependent tools. The review feedback identifies several locations where the skip_verify flag is not properly propagated to internal function calls, specifically regarding mirror-based updates and skill registry synchronization. Furthermore, the reviewer suggests centralizing the environment variable parsing logic to eliminate redundancy and ensure consistent boolean evaluation across the codebase.
| fn fetch_latest_release(skip_verify: bool) -> Result<Release> { | ||
| if let Some(base_url) = release_base_url_from_env() { | ||
| let version = update_version_from_env().unwrap_or_else(|| env!("CARGO_PKG_VERSION").into()); | ||
| return Ok(release_from_mirror_base_url( |
| let (network, _max_size, registry_url, _skip_verify) = installer_settings(app); | ||
| let registry = run_async(async move { install::fetch_registry(&network, ®istry_url).await }); |
There was a problem hiding this comment.
| if let Ok(value) = std::env::var("DEEPSEEK_INSECURE_SKIP_TLS_VERIFY") { | ||
| let val = value.trim().to_ascii_lowercase(); | ||
| config.insecure_skip_tls_verify = | ||
| Some(matches!(val.as_str(), "1" | "true" | "yes" | "on")); | ||
| } |
There was a problem hiding this comment.
804815d to
f60c0fd
Compare
|
Thanks for the review. Here is the status of each comment:
All fixes have been squashed into the latest commit. |
|
Independent review (security-focused, post-greptile fixes) Secure by default — confirmed. Gaps worth addressing:
v0.8.48 conflict (PR #2256). Non-trivial in |
…s, and compilation fixes - Add always-visible TUI warning banner when insecure_skip_tls_verify is active, addressing the 'warning is too quiet' concern - Extract warn_if_insecure_tls() method and add 3 tests covering Some(true)/Some(false)/None paths with tracing subscriber capture - Add insecure_skip_tls_verify field to EngineConfig and wire it through ui.rs, main.rs, and runtime_threads.rs constructors - Fix pre-existing compilation errors: merge_config missing the field, apply_env_overrides called as method (free function), missing skip_verify argument in skill_install integration tests
…s, and compilation fixes - Add always-visible TUI warning banner when insecure_skip_tls_verify is active, addressing the 'warning is too quiet' concern - Extract warn_if_insecure_tls() method and add 3 tests covering Some(true)/Some(false)/None paths with tracing subscriber capture - Add insecure_skip_tls_verify field to EngineConfig and wire it through ui.rs, main.rs, and runtime_threads.rs constructors - Fix pre-existing compilation errors: merge_config missing the field, apply_env_overrides called as method (free function), missing skip_verify argument in skill_install integration tests
fc8ef07 to
cfe1944
Compare
…s, and compilation fixes - Add always-visible TUI warning banner when insecure_skip_tls_verify is active, addressing the 'warning is too quiet' concern - Extract warn_if_insecure_tls() method and add 3 tests covering Some(true)/Some(false)/None paths with tracing subscriber capture - Add insecure_skip_tls_verify field to EngineConfig and wire it through ui.rs, main.rs, and runtime_threads.rs constructors - Fix pre-existing compilation errors: merge_config missing the field, apply_env_overrides called as method (free function), missing skip_verify argument in skill_install integration tests
cfe1944 to
06c12a9
Compare
06c12a9 to
2ce873f
Compare
…s, and compilation fixes - Add always-visible TUI warning banner when insecure_skip_tls_verify is active, addressing the 'warning is too quiet' concern - Extract warn_if_insecure_tls() method and add 3 tests covering Some(true)/Some(false)/None paths with tracing subscriber capture - Add insecure_skip_tls_verify field to EngineConfig and wire it through ui.rs, main.rs, and runtime_threads.rs constructors - Fix pre-existing compilation errors: merge_config missing the field, apply_env_overrides called as method (free function), missing skip_verify argument in skill_install integration tests
|
All review comments have been addressed. Here's a summary of what was done: P1 — FinanceTool & ImageAnalyzeTool ignore
|
|
Thanks for working through the TLS override path. I am keeping this open because GitHub currently reports conflicts, and this is security-sensitive enough that it needs a clean rebase plus full first-party verification before it lands. The direction is plausible for self-signed/internal endpoints, but please keep the default safe, keep the warnings explicit, and rerun the focused coverage after rebasing: |
|
Thanks @wavezhang. The TLS override direction is useful for internal/self-signed endpoints, but I’m not comfortable merging this branch as-is while it conflicts with current One concrete blocker remains in the current head: the TLS banner layout still leaves |
|
Thanks @wavezhang, this is a useful direction for self-signed/internal endpoints, and I appreciate the follow-up fixes. I’m going to keep this on hold rather than merge the current branch because it now conflicts with current main and the branch-wide TLS bypass affects every outbound HTTPS surface, including updater, web/tools, hooks, skills, MCP, and sandbox traffic. That is security-sensitive enough that it needs a clean rebase and first-party verification before landing. One concrete blocker also remains in the current head: the TUI banner layout still leaves last_composer_area/content on the preview chunk instead of the composer chunk. If you continue this PR, please rebase on latest main, adapt the banner to the current header_area/body_chunks layout, and rerun: cargo test -p codewhale-config insecure_skip_tls_verify --locked We may harvest a narrower provider-scoped version first; if so, I’ll make sure the harvested PR credits your work here. |
|
Thanks for the TLS configurability work. This is a real-world need, but it sits in a sensitive part of the trust model, so the UX has to make the tradeoff clear instead of hiding it behind a quiet flag. I am leaving it unmerged in this pass because the branch is dirty against main. A good next version would rebase cleanly and make the opt-in nature very explicit in config/docs/doctor output, so users understand when certificate verification has been relaxed and why. |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
e685996 to
186883e
Compare
Updated — Conflicts resolved + doctor output addedMerge Conflicts ResolvedRebased onto
Doctor output now warns when TLS verification is disabledWhen Build status
What's left
|
33a4b04 to
2fdd3bd
Compare
2fdd3bd to
e4deb86
Compare
|
@greptile-apps Fixed in commit e4deb86. Both |
|
Confirmed — both paths now use Tip: You can customize Greptile's behavior for this repo with |
e4deb86 to
05c37b3
Compare
| McpCommand::Connect { server } => { | ||
| let mut pool = McpPool::from_config_path(&config_path)?; | ||
| let mut pool = McpPool::from_config_path(&config_path)? | ||
| .with_skip_tls_verify(config.insecure_skip_tls_verify.unwrap_or(false)); |
There was a problem hiding this comment.
MCP subcommands ignore
DEEPSEEK_INSECURE_SKIP_TLS_VERIFY env override
All three MCP subcommands (Connect, Tools, Validate) read config.insecure_skip_tls_verify.unwrap_or(false) directly from the raw TOML field. This bypasses the env-var resolution performed by insecure_skip_tls_verify_for_provider(). A user who sets DEEPSEEK_INSECURE_SKIP_TLS_VERIFY=true in the environment without touching the config file will find that mcp connect, mcp tools, and mcp validate all still perform full certificate verification and may fail to reach the same MCP servers that work fine inside a normal session. The same raw-field access recurs on lines 4283 and 4394.
Rewrite of insecure_skip_tls_verify as provider-level setting only. No global flag — each [providers.<name>] can independently opt in. Changes: - ProviderConfigToml/ProviderConfig: add insecure_skip_tls_verify field - Config::deepseek_insecure_skip_tls_verify() reads from active provider - DeepSeekClient::build_http_client() accepts skip_verify param - deepseek doctor outputs TLS status (human+JSON) - config.example.toml: document per-provider setting - 8 new tests covering deserialization, defaults, merge, HTTP client build Addresses PR Hmbown#1893 review feedback: per-provider scope, no global toggling of updater/tools/MCP/sandbox TLS.
05c37b3 to
71b456c
Compare
Rewrite of insecure_skip_tls_verify as provider-level setting only. No global flag — each [providers.<name>] can independently opt in. Changes: - ProviderConfigToml/ProviderConfig: add insecure_skip_tls_verify field - Config::deepseek_insecure_skip_tls_verify() reads from active provider - DeepSeekClient::build_http_client() accepts skip_verify param - deepseek doctor outputs TLS status (human+JSON) - config.example.toml: document per-provider setting - 8 new tests covering deserialization, defaults, merge, HTTP client build Addresses PR Hmbown#1893 review feedback: per-provider scope, no global toggling of updater/tools/MCP/sandbox TLS.
71b456c to
01832ad
Compare
|
@Hmbown Rebased onto latest main (v0.8.49) and rewritten as a provider-scoped version per your feedback:
Per-provider usage: [providers.ollama]
base_url = "https://localhost:11434/v1"
insecure_skip_tls_verify = true
|
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
|
Thanks @wavezhang — the latest provider-scoped shape is much closer to the trust boundary I’d want for this. Keeping For the v0.9.0 stewardship branch I’m still leaving this open rather than harvesting it today because GitHub currently reports the PR as conflicting/dirty against current main, and TLS verification is security-sensitive enough that I want the final branch to be clean and first-party verified before it lands. A safe next pass would be a fresh rebase against current cargo test -p codewhale-config insecure_skip_tls_verify --locked
cargo test -p codewhale-tui insecure_skip_tls_verify --locked
cargo test -p codewhale-tui build_http_client --locked
cargo check -p codewhale-tui --all-features --lockedAlso worth preserving in docs: custom CA via |
|
Harvested the narrow provider-scoped TLS configurability slice into #2834, with @wavezhang credited in the PR body, changelog, and commit co-author metadata. Thank you for pushing this forward. I left this source PR open because the branch is still stale/conflicting and the broader shape is too risky for v0.9.0 as-is. The maintainer PR intentionally keeps the setting disabled by default, scopes it to the active LLM provider client only, keeps SSL_CERT_FILE as the preferred custom-CA path, and does not add any global TLS bypass for updater/tools/MCP/sandbox/web surfaces. |
Harvests provider-scoped TLS skip-verify from #1893 by @wavezhang. Disabled by default, active-provider-only, doctor-reported, and keeps SSL_CERT_FILE as the preferred custom CA path.
c236586 to
0975f9a
Compare
0975f9a to
02932f1
Compare
✅ Rebased & Tests PassingThis PR has been rebased onto the latest What was done
Test Results# Test 1: cargo test -p codewhale-config insecure_skip_tls_verify --locked
→ 87 tests passed ✅
# Test 2: cargo test -p codewhale-tui insecure_skip_tls_verify --locked
→ 6/6 passed ✅
- insecure_skip_tls_verify_defaults_to_false
- insecure_skip_tls_verify_toml_deserializes_true
- insecure_skip_tls_verify_toml_explicit_false
- insecure_skip_tls_verify_toml_missing_defaults_false
- merge_provider_config_insecure_skip_tls_verify_falls_back
- merge_provider_config_insecure_skip_tls_verify_override_wins
# Test 3: cargo test -p codewhale-tui build_http_client --locked
→ 2/2 passed ✅
- build_http_client_with_skip_verify_false
- build_http_client_with_skip_verify_true
# Test 4: cargo check -p codewhale-tui --all-features --locked
→ Compilation successful ✅Clean Commit History
Ready for review! 🚀 |
Rewrite: per-provider TLS toggle (no global switch)
Rebased and rewritten as a provider-scoped version per review feedback. No global
insecure_skip_tls_verify— each[providers.<name>]independently opts in, and it only affects the LLM API client.Design
false— TLS verified unless explicitly opted outlogging::warnemitted when TLS is disabled for the active providerdeepseek doctorshows TLS status in both human and--jsonmodesUsage
Tests
cargo build✅cargo test -p codewhale-tui -- insecure_skip_verify build_http_client→ 8/8 ✅cargo test -p codewhale-tui -- status_item→ 7/7 ✅Greptile Summary
This PR adds a per-provider
insecure_skip_tls_verifyflag to the[providers.<name>]TOML table, letting users accept self-signed or invalid TLS certificates on a provider-by-provider basis without any global bypass switch. The feature is correctly defaulted tofalse, emits alogging::warnwhen active, and is surfaced in both the human-readable and--jsondoctoroutput.ProviderConfigTomlandProviderConfiggain aninsecure_skip_tls_verify: Option<bool>field;build_http_clientpasses the resolved value toreqwest'sdanger_accept_invalid_certs.Config::deepseek_insecure_skip_tls_verify()resolves the flag for the active provider; it is consumed inclient.rsand in bothrun_doctor/run_doctor_jsoninmain.rs.merge_provider_config(TUI-side) correctly propagates the new field; a subset of providers inconfig.example.tomlreceived the commented-out example line.Confidence Score: 5/5
Safe to merge; the core TLS toggle wires correctly end-to-end and defaults to secure behaviour.
The implementation correctly threads skip_verify through build_http_client, emits a log warning when TLS is disabled, surfaces the setting in both doctor output modes, and merges the field properly in the TUI-side merge_provider_config. The only new issues found in this review pass are naming style and a documentation gap in the example file — nothing that affects runtime correctness.
The merge_project_provider_config function in crates/config/src/lib.rs (already flagged in a prior review thread) still silently drops the new field for project-level configs — worth confirming that is addressed before merge.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[config.toml\nproviders.X.insecure_skip_tls_verify] --> B[ProviderConfigToml] B --> C{merge_project_provider_config\ncrates/config} C -- "model, path_suffix only\n⚠ insecure_skip_tls_verify dropped" --> D[Merged ProviderConfigToml] D --> E[Config::deepseek_insecure_skip_tls_verify\ncrates/tui/src/config.rs] E --> F{skip_verify?} F -- true --> G[logging::warn emitted] F -- true --> H[reqwest::Client::builder\n.danger_accept_invalid_certs true] F -- false --> H2[reqwest::Client::builder\n.danger_accept_invalid_certs false] E --> I[run_doctor / run_doctor_json\nmain.rs] H --> J[DeepSeekClient] H2 --> JComments Outside Diff (1)
crates/config/src/lib.rs, line 1527-1534 (link)merge_project_provider_configsilently dropsinsecure_skip_tls_verifyset in a project-level config file. Onlymodelandpath_suffixare propagated, so a.codewhale/config.tomlentry like[providers.ollama] insecure_skip_tls_verify = truewill always be ignored — the effective config retains the user-level value (None/false) even when the project explicitly opts in.Reviews (14): Last reviewed commit: "feat: per-provider TLS toggle (rebased)" | Re-trigger Greptile