fix(integrations): strip inference path from backend URL (#2075)#2101
Conversation
`effective_backend_api_url` returned `api_base_from_env()` verbatim, so a misconfigured `BACKEND_URL=https://.../openai/v1/chat/completions` baked into the build flowed straight into every integration call as a prefix, yielding 404 URLs like `…/openai/v1/chat/completions/agent-integrations/composio/connections` (Sentry OPENHUMAN-TAURI-H6, -HN). Route the env value through `normalize_backend_api_base_url` and recover a scheme-less override by retrying with `https://` before path stripping. Refs tinyhumansai#2075
Defense-in-depth for issue tinyhumansai#2075 / Sentry OPENHUMAN-TAURI-H6, -HN. Every prod call site already routes `backend_url` through `effective_backend_api_url`, but a future caller that forgets that step would silently re-introduce the 404 cascade. Re-run `normalize_backend_api_base_url` inside the constructor so the field invariant (no inference path) holds locally, and `warn!` once when the input had to be fixed so the regression is observable. Refs tinyhumansai#2075
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughConfig-level normalization now strips inference-style paths from env-derived backend URLs and is exposed crate-wide; integration client construction also sanitizes backend URLs to ensure stored bases are host-rooted. Tests added for both normalization and client sanitization behaviors. ChangesBackend URL Sanitization for Integration Clients
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/openhuman/integrations/client.rs`:
- Around line 54-59: The warning currently logs raw URL values via
tracing::warn!(input = %trimmed, cleaned = %cleaned, ...) which can leak
credentials or tokens; instead sanitize or omit those values before logging
(e.g., build sanitized_trimmed and sanitized_cleaned by parsing the URL and
removing userinfo, query, and fragment or replacing them with "[REDACTED]" using
the Url crate), then call tracing::warn! with the sanitized variables (or log
only host/path or a boolean flag) so the tracing::warn invocation no longer
contains raw sensitive URL strings.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dbff64ff-f88c-40aa-8292-00d7312a3bc4
📒 Files selected for processing (3)
src/api/config.rssrc/openhuman/integrations/client.rssrc/openhuman/integrations/client_tests.rs
CodeRabbit flagged a credential-leak risk in the `warn!` emitted by `sanitize_backend_url`: a misconfigured `BACKEND_URL` carrying `https://user:secret@host/...` would leak the userinfo into logs. Route both `input` and `cleaned` through the existing `redact_url_for_log` helper (promoted to `pub(crate)`) so host/path survive for debugging while username/password are scrubbed.
M3gA-Mind
left a comment
There was a problem hiding this comment.
Fix is correct and complete. Three-layer defense is the right approach: normalize the env-fallback branch (root cause), harden the normalizer for scheme-less inputs, and add a constructor guard with a redacted warn log. All Sentry scenarios are covered by the regression tests. CI green, CodeRabbit's redaction concern addressed. Merging.
Summary
/openai/v1/chat/completions) fromBACKEND_URLenv / compile-time fallback before it becomes any integration call's prefix.api.tinyhumans.ai/...) innormalize_backend_api_base_urlso a misbaked env still normalizes.backend_urlinsideIntegrationClient::newandwarn!on first fix-up — defense-in-depth + runtime detector.Problem
Sentry
OPENHUMAN-TAURI-H6(103 events) andOPENHUMAN-TAURI-HN(50 events) — 153 affected users could never load or manage Composio integrations:effective_backend_api_url's override branch already normalized vianormalize_backend_api_base_url, but the env / compile-time branch returned the raw value, so a misconfiguredBACKEND_URL=https://api.tinyhumans.ai/openai/v1/chat/completions(the cited prod misbake) flowed straight into every integration request as the prefix.list_connections,delete_connection, and every otherIntegrationClientoperation 404'd.Solution
Three-layer fix:
src/api/config.rs—effective_backend_api_url: routeapi_base_from_env()throughnormalize_backend_api_base_urlbefore returning, closing the env-fallback bypass.normalize_backend_api_base_url: promoted topub(crate); on parse failure (scheme-less input) retries withhttps://prefix so the path can still be stripped. Empty input round-trips unchanged so callers' "no backend" sentinel is not overwritten.src/openhuman/integrations/client.rs—IntegrationClient::new: re-runsnormalize_backend_api_base_urlon the constructor argument andwarn!s once when input had to be fixed. Holds the local invariant ("backend_urlhas no inference path") even if a future caller forgets the resolver, and emits the diagnostic the issue asked for.The Sentry HN case (
openrouter.ai/...) is additionally caught by the pre-existinglooks_like_local_ai_endpointheuristic (path-end match works on any host); the new sanitize layer guarantees correct behavior even if the heuristic is bypassed.Submission Checklist
IntegrationClient::newinvariant).N/A: behaviour-only change(bug fix, no new/removed/renamed feature row).## Related—N/A: behaviour-only change.N/A: bug fix in URL normalization, no release-cut surface touched.Closes #NNNin the## Relatedsection.Impact
IntegrationClient::new(once per construction). Negligible.warn!so the regression is observable.Related
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
Validation Run
pnpm --filter openhuman-app format:check— N/A: no app/ changespnpm typecheck— N/A: no app/ changesValidation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
Duplicate / Superseded PR Handling
Summary by CodeRabbit