fix(composio): trim API key in ComposioTool constructor (#2323) (#2338)

Co-authored-by: sanil-23 <sanil@alphahuman.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
sanil-23
2026-05-20 18:42:01 +05:30
committed by GitHub
co-authored by sanil-23 Claude
parent f24dbc6653
commit 997be4eef2
2 changed files with 50 additions and 1 deletions
+15 -1
View File
@@ -41,8 +41,22 @@ impl ComposioTool {
default_entity_id: Option<&str>,
security: Arc<SecurityPolicy>,
) -> Self {
let trimmed = api_key.trim();
if trimmed.len() != api_key.len() {
// The key carried leading/trailing whitespace that would otherwise
// reach Composio's `x-api-key` header verbatim and trip the
// server-side "Invalid API key format" 401 (Sentry TAURI-RUST-D3).
// We trim here so the request succeeds; logging the length delta
// (never the key itself) helps trace which credential source
// produced a dirty value without leaking the secret.
tracing::debug!(
original_len = api_key.len(),
trimmed_len = trimmed.len(),
"[composio] trimmed leading/trailing whitespace from api_key"
);
}
Self {
api_key: api_key.to_string(),
api_key: trimmed.to_string(),
default_entity_id: normalize_entity_id(default_entity_id.unwrap_or("default")),
security,
}
@@ -574,3 +574,38 @@ fn connected_account_accepts_camelcase_created_at() {
.unwrap();
assert_eq!(raw.created_at.as_deref(), Some("2026-05-15T00:00:00Z"));
}
// ── API key trimming (issue #2323) ────────────────────────
//
// Composio v3 rejects API keys with leading/trailing whitespace as
// "Invalid API key format" (Sentry TAURI-RUST-D3). The constructor must
// strip surrounding whitespace defensively, but MUST preserve internal
// whitespace so legitimate keys containing spaces are not corrupted.
#[test]
fn composio_tool_trims_surrounding_whitespace_in_api_key() {
let tool = ComposioTool::new(" key123 ", None, test_security());
assert_eq!(tool.api_key, "key123");
}
#[test]
fn composio_tool_trims_trailing_newline_in_api_key() {
// The real-world Sentry case: secret store payloads frequently carry a
// trailing newline (clipboard paste, file read). It must be stripped.
let tool = ComposioTool::new("key123\n", None, test_security());
assert_eq!(tool.api_key, "key123");
}
#[test]
fn composio_tool_preserves_internal_whitespace_in_api_key() {
// Pins the trim-scope: a future refactor must NOT widen this to
// `replace(' ', "")` or similar — only surrounding whitespace is stripped.
let tool = ComposioTool::new("k1 k2", None, test_security());
assert_eq!(tool.api_key, "k1 k2");
}
#[test]
fn composio_tool_accepts_empty_api_key_without_panic() {
let tool = ComposioTool::new("", None, test_security());
assert_eq!(tool.api_key, "");
}