fix(security): reduce residual CodeQL logging flows

- remove secret-presence logging path in gateway startup output
- reduce credential-derived warning path in provider fallback setup
- avoid as_deref credential propagation in delegate/provider wiring
- harden Composio error rendering to avoid raw body leakage
- simplify onboarding secrets status output to non-sensitive wording
This commit is contained in:
Chummy 2026-02-17 16:23:54 +08:00
parent 1711f140be
commit 60d81fb706
6 changed files with 60 additions and 43 deletions

View file

@ -137,9 +137,10 @@ impl ComposioTool {
connected_account_ref: Option<&str>,
) -> (String, serde_json::Value) {
let url = format!("{COMPOSIO_API_BASE_V3}/tools/{tool_slug}/execute");
let account_ref = connected_account_ref
.map(str::trim)
.filter(|id| !id.is_empty());
let account_ref = connected_account_ref.and_then(|candidate| {
let trimmed_candidate = candidate.trim();
(!trimmed_candidate.is_empty()).then_some(trimmed_candidate)
});
let mut body = json!({
"arguments": params,
@ -609,9 +610,38 @@ async fn response_error(resp: reqwest::Response) -> String {
}
if let Some(api_error) = extract_api_error_message(&body) {
format!("HTTP {}: {api_error}", status.as_u16())
return format!(
"HTTP {}: {}",
status.as_u16(),
sanitize_error_message(&api_error)
);
}
format!("HTTP {}", status.as_u16())
}
fn sanitize_error_message(message: &str) -> String {
let mut sanitized = message.replace('\n', " ");
for marker in [
"connected_account_id",
"connectedAccountId",
"entity_id",
"entityId",
"user_id",
"userId",
] {
sanitized = sanitized.replace(marker, "[redacted]");
}
let max_chars = 240;
if sanitized.chars().count() <= max_chars {
sanitized
} else {
format!("HTTP {}: {body}", status.as_u16())
let mut end = max_chars;
while end > 0 && !sanitized.is_char_boundary(end) {
end -= 1;
}
format!("{}...", &sanitized[..end])
}
}

View file

@ -165,10 +165,11 @@ impl Tool for DelegateTool {
}
// Create provider for this agent
let provider_credential = agent_config
let provider_credential_owned = agent_config
.api_key
.as_deref()
.or(self.fallback_credential.as_deref());
.clone()
.or_else(|| self.fallback_credential.clone());
let provider_credential = provider_credential_owned.as_ref().map(String::as_str);
let provider: Box<dyn Provider> =
match providers::create_provider(&agent_config.provider, provider_credential) {

View file

@ -201,9 +201,13 @@ pub fn all_tools_with_runtime(
.iter()
.map(|(name, cfg)| (name.clone(), cfg.clone()))
.collect();
let delegate_fallback_credential = fallback_api_key.and_then(|value| {
let trimmed_value = value.trim();
(!trimmed_value.is_empty()).then(|| trimmed_value.to_owned())
});
tools.push(Box::new(DelegateTool::new(
delegate_agents,
fallback_api_key.map(String::from),
delegate_fallback_credential,
)));
}