fix(desktop): accept self-signed certs from configured external goosed host#8400
Conversation
…d host The certificate-error and setCertificateVerifyProc handlers only accepted self-signed certificates from localhost, making remote connection to an external goosed server impossible over HTTPS with its self-signed cert. Add isTrustedHost() that also trusts the user-configured externalGoosed host, so remote backends work without requiring a valid CA-signed cert. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b491b7b621
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The original PR (aaif-goose#8400) correctly identified that remote external goosed connections over HTTPS fail because the certificate handlers reject all non-localhost hosts. However, simply allowing the external host through without pinning left TLS validation permanently disabled for that host. This commit builds on the PR's isTrustedHost() approach but adds Trust-On-First-Use (TOFU) certificate pinning: - On the first TLS handshake with a trusted host (local or external), the certificate fingerprint is captured and pinned. - All subsequent connections are validated against that pinned fingerprint, preventing MITM attacks after the initial connection. - The trusted external hostname is cached in memory (updated when a chat is created) to avoid synchronous filesystem reads on every TLS handshake. - The pinned fingerprint resets when a new chat/backend is created so each backend gets its own TOFU handshake. For locally-spawned goosed, the fingerprint from stdout takes precedence (set after startGoosed returns), matching the existing behavior. Signed-off-by: jh-block <jhugo@block.xyz>
…ends Add an optional 'Certificate Fingerprint' field to the external backend settings UI. When provided, the fingerprint is pinned directly on connection (skipping TOFU). This lets users who know their server's cert fingerprint get deterministic pinning without trusting the first handshake. Accepts both colon-separated hex (AA:BB:CC:...) and sha256/base64 formats, matching the existing normalizeFingerprint() logic. Signed-off-by: jh-block <jhugo@block.xyz>
Add GOOSE_TLS_CERT_PATH and GOOSE_TLS_KEY_PATH config options. When both are set, goosed loads the PEM files instead of generating a self-signed certificate. The SHA-256 fingerprint is still computed and printed to stdout for client-side pinning. Combined with the client-side fingerprint setting added in the previous commit, this enables a fully deterministic TLS setup for remote backends: the operator deploys a known cert and the client pins its fingerprint, eliminating the TOFU trust window entirely. If only one of the two paths is set, goosed exits with a clear error. Signed-off-by: jh-block <jhugo@block.xyz>
|
I made some changes to tighten this up a bit. With the local backend we pin the fingerprint to what goosed outputs when it starts up. With remote backends we can't automatically know the fingerprint of the cert that was generated before connecting, but we now allow the user to specify the fingerprint if known (and I added support on the goosed side for providing a cert + key, so the fingerprint can be known), and if not specified, we do TOFU (pin the fingerprint upon first connect) as a basic protection against MITM during the session. |
Signed-off-by: jh-block <jhugo@block.xyz>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b392c54a07
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…Proc Use callback(-2) (hard failure) instead of callback(-3) (defer to Chromium default) when a pinned fingerprint doesn't match. With -3, a CA-valid but fingerprint-mismatched cert (e.g. corporate proxy) would still be accepted, bypassing both TOFU and explicit pinning. Signed-off-by: jh-block <jhugo@block.xyz>
…l-placeholder * origin/main: (64 commits) fix: expand tool calls by default when Response Style is Detailed (aaif-goose#8478) fix: create logs dir before writing llm request log (aaif-goose#8522) fix: enable token usage tracking and configurable stream timeout for Ollama provider (aaif-goose#8493) fix tauri-plugin-dialog version constraint to match other plugins (aaif-goose#8542) call goose serve from tauri frontend via goose-acp client (aaif-goose#8549) failed the script when bundle:default fails and cleanup "alpha" (aaif-goose#8580) pass globally unique conversation identifier as sessionId in databricks api call (aaif-goose#8576) fix: use sqlx chrono decode for thread timestamps instead of manual parsing (aaif-goose#8575) docs: remove stale gemini-acp references (aaif-goose#8572) show individual untracked files in git changes widget (aaif-goose#8574) fix: update publishing flow to include new sdk dir (aaif-goose#8573) fix: remove double border on content in chat (aaif-goose#8545) chore(goose2): `just goose2 <command>` with the addition of `just goose2 kill` (aaif-goose#8570) Lifei/oltp data (aaif-goose#8458) Sidebar polish: search copy, dividers, project reorder, fix DnD (aaif-goose#8568) remove the workflow_dispatch check (aaif-goose#8563) fix: one more rename (aaif-goose#8562) fix(desktop): accept self-signed certs from configured external goosed host (aaif-goose#8400) alexhancock/npm-bumps (aaif-goose#8557) Remove npm publish from release for now (aaif-goose#8558) ...
|
nice, thanks for the improvement, do you know when it will release ? |
…ture Conflict resolutions: - configuration.rs: kept both mcp_only (fork) and tls_cert_path/tls_key_path (upstream aaif-goose#8400) - commands/agent.rs: kept fork's AppState::new(tls, settings) signature + added boot_marker calls from upstream aaif-goose#8656 - state.rs: adopted upstream's OnceLock lazy-init for inference_runtime (aaif-goose#8656) + retained settings: Arc<Settings> from fork
Summary
certificate-errorandsetCertificateVerifyProchandlers inmain.tsonly accepted self-signed certificates fromlocalhost, rejecting all other hostsisTrustedHost()that also trusts the user-configuredexternalGoosedhost, so remote backends work with self-signed certsTest plan
GOOSE_SERVER__SECRET_KEYhttps://<remote-host>:<port>with the secret keyfixes #8376