Set up Datadog metrics for prompt injection detection (#5385)
This commit is contained in:
committed by
GitHub
parent
c0032ef4e0
commit
786e7084b7
@@ -84,6 +84,8 @@ impl Agent {
|
|||||||
// Log user decision if this was a security alert
|
// Log user decision if this was a security alert
|
||||||
if let Some(finding_id) = get_security_finding_id_from_results(&request.id, inspection_results) {
|
if let Some(finding_id) = get_security_finding_id_from_results(&request.id, inspection_results) {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
|
counter.goose.prompt_injection_user_decisions = 1,
|
||||||
|
decision = ?confirmation.permission,
|
||||||
"🔒 User security decision: {:?} for finding ID: {}",
|
"🔒 User security decision: {:?} for finding ID: {}",
|
||||||
confirmation.permission,
|
confirmation.permission,
|
||||||
finding_id
|
finding_id
|
||||||
|
|||||||
@@ -47,12 +47,18 @@ impl SecurityManager {
|
|||||||
messages: &[Message],
|
messages: &[Message],
|
||||||
) -> Result<Vec<SecurityResult>> {
|
) -> Result<Vec<SecurityResult>> {
|
||||||
if !self.is_prompt_injection_detection_enabled() {
|
if !self.is_prompt_injection_detection_enabled() {
|
||||||
tracing::debug!("🔓 Security scanning disabled - returning empty results");
|
tracing::debug!(
|
||||||
|
gauge.goose.prompt_injection_scanner_enabled = 0,
|
||||||
|
"🔓 Security scanning disabled"
|
||||||
|
);
|
||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let scanner = self.scanner.get_or_init(|| {
|
let scanner = self.scanner.get_or_init(|| {
|
||||||
tracing::info!("Security scanner initialized and enabled");
|
tracing::info!(
|
||||||
|
gauge.goose.prompt_injection_scanner_enabled = 1,
|
||||||
|
"🔓 Security scanner initialized and enabled"
|
||||||
|
);
|
||||||
PromptInjectionScanner::new()
|
PromptInjectionScanner::new()
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,16 +71,8 @@ impl SecurityManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Analyze each tool request
|
// Analyze each tool request
|
||||||
for (i, tool_request) in tool_requests.iter().enumerate() {
|
for tool_request in tool_requests.iter() {
|
||||||
if let Ok(tool_call) = &tool_request.tool_call {
|
if let Ok(tool_call) = &tool_request.tool_call {
|
||||||
tracing::info!(
|
|
||||||
tool_name = %tool_call.name,
|
|
||||||
tool_index = i,
|
|
||||||
tool_request_id = %tool_request.id,
|
|
||||||
tool_args = ?tool_call.arguments,
|
|
||||||
"🔍 Starting security analysis for current tool call"
|
|
||||||
);
|
|
||||||
|
|
||||||
let analysis_result = scanner
|
let analysis_result = scanner
|
||||||
.analyze_tool_call_with_context(tool_call, messages)
|
.analyze_tool_call_with_context(tool_call, messages)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -82,39 +80,39 @@ impl SecurityManager {
|
|||||||
// Get threshold from config - only flag things above threshold
|
// Get threshold from config - only flag things above threshold
|
||||||
let config_threshold = scanner.get_threshold_from_config();
|
let config_threshold = scanner.get_threshold_from_config();
|
||||||
|
|
||||||
if analysis_result.is_malicious && analysis_result.confidence > config_threshold {
|
if analysis_result.is_malicious {
|
||||||
// Generate a globally unique finding ID for each security finding
|
let above_threshold = analysis_result.confidence > config_threshold;
|
||||||
let finding_id = format!("SEC-{}", Uuid::new_v4().simple());
|
let finding_id = format!("SEC-{}", Uuid::new_v4().simple());
|
||||||
|
|
||||||
tracing::warn!(
|
tracing::warn!(
|
||||||
|
counter.goose.prompt_injection_finding = 1,
|
||||||
|
gauge.goose.prompt_injection_confidence_score = analysis_result.confidence,
|
||||||
|
above_threshold = above_threshold,
|
||||||
tool_name = %tool_call.name,
|
tool_name = %tool_call.name,
|
||||||
tool_request_id = %tool_request.id,
|
tool_request_id = %tool_request.id,
|
||||||
confidence = analysis_result.confidence,
|
confidence = analysis_result.confidence,
|
||||||
explanation = %analysis_result.explanation,
|
explanation = %analysis_result.explanation,
|
||||||
finding_id = %finding_id,
|
finding_id = %finding_id,
|
||||||
threshold = config_threshold,
|
threshold = config_threshold,
|
||||||
"🔒 Current tool call flagged as malicious after security analysis (above threshold)"
|
"{}",
|
||||||
);
|
if above_threshold {
|
||||||
|
"🔒 Current tool call flagged as malicious after security analysis (above threshold)"
|
||||||
results.push(SecurityResult {
|
} else {
|
||||||
is_malicious: analysis_result.is_malicious,
|
"🔒 Security finding below threshold - logged but not blocking execution"
|
||||||
confidence: analysis_result.confidence,
|
}
|
||||||
explanation: analysis_result.explanation,
|
|
||||||
should_ask_user: true, // Always ask user for threats above threshold
|
|
||||||
finding_id,
|
|
||||||
tool_request_id: tool_request.id.clone(),
|
|
||||||
});
|
|
||||||
} else if analysis_result.is_malicious {
|
|
||||||
tracing::warn!(
|
|
||||||
tool_name = %tool_call.name,
|
|
||||||
tool_request_id = %tool_request.id,
|
|
||||||
confidence = analysis_result.confidence,
|
|
||||||
explanation = %analysis_result.explanation,
|
|
||||||
threshold = config_threshold,
|
|
||||||
"🔒 Security finding below threshold - logged but not blocking execution"
|
|
||||||
);
|
);
|
||||||
|
if above_threshold {
|
||||||
|
results.push(SecurityResult {
|
||||||
|
is_malicious: analysis_result.is_malicious,
|
||||||
|
confidence: analysis_result.confidence,
|
||||||
|
explanation: analysis_result.explanation,
|
||||||
|
should_ask_user: true, // Always ask user for threats above threshold
|
||||||
|
finding_id,
|
||||||
|
tool_request_id: tool_request.id.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!(
|
tracing::info!(
|
||||||
tool_name = %tool_call.name,
|
tool_name = %tool_call.name,
|
||||||
tool_request_id = %tool_request.id,
|
tool_request_id = %tool_request.id,
|
||||||
confidence = analysis_result.confidence,
|
confidence = analysis_result.confidence,
|
||||||
@@ -126,6 +124,7 @@ impl SecurityManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
|
counter.goose.prompt_injection_analysis_performed = 1,
|
||||||
"🔍 Security analysis complete - found {} security issues in current tool requests",
|
"🔍 Security analysis complete - found {} security issues in current tool requests",
|
||||||
results.len()
|
results.len()
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user