AI Agents - Hard-coded credentials in Tools or Configuration
Description
This query identifies AI agents that contain hard-coded credentials in their declared tools, triggers, MCP servers, skills, capabilities, or raw agent configuration. Storing credentials in clear text within agent logic creates a security risk because these secrets can be exposed to unintended users or attackers. If compromised, credentials could allow unauthorized access to external systems, APIs, or sensitive data. Recommended Action: Avoid embedding credentials directly in tools or configuration. Use secure alternatives such as Azure Key Vault with environment variables or enable secured input options for sensitive fields. Regularly audit agents for hard-coded secrets and rotate any exposed credentials immediately.
Query · kql
let suspicious_patterns = @"(AKIA[0-9A-Z]{16})|(AIza[0-9A-Za-z_\-]{35})|(xox[baprs]-[0-9a-zA-Z]{10,48})|(ghp_[A-Za-z0-9]{36,59})|(sk_(live|test)_[A-Za-z0-9]{24})|(SG\.[A-Za-z0-9]{22}\.[A-Za-z0-9]{43})|(\d{8}:[\w\-]{35})|(eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)|(Authorization\s*:\s*Basic\s+[A-Za-z0-9=:+]+)|([A-Za-z]+:\/\/[^\/\s""']+:[^\/\s""']+@[^\/\s""']+)";
let IdentityIdtoUPN = materialize (
IdentityInfo
| where isnotempty(AccountObjectId) and isnotempty(AccountUpn)
| summarize arg_max(Timestamp, AccountUpn) by AccountObjectId
| project AccountObjectId = tostring(AccountObjectId), AccountUpn);
AgentsInfo
| summarize arg_max(Timestamp, *) by AgentId
| where LifecycleStatus != "Deleted"
| extend ToolsStr = tostring(DeclaredTools), TriggersStr = tostring(Triggers), McpStr = tostring(McpServers), SkillsStr = tostring(Skills), CapsStr = tostring(Capabilities), RawStr = tostring(RawAgentInfo)
| where ToolsStr matches regex suspicious_patterns
or TriggersStr matches regex suspicious_patterns
or McpStr matches regex suspicious_patterns
or SkillsStr matches regex suspicious_patterns
or CapsStr matches regex suspicious_patterns
or RawStr matches regex suspicious_patterns
or Instructions matches regex suspicious_patterns
| extend OwnerId = tostring(Owners[0])
| join kind=leftouter IdentityIdtoUPN on $left.OwnerId == $right.AccountObjectId
| project-rename OwnerUpn = AccountUpn
| project-away OwnerId, AccountObjectId, RawStr
| project-reorder CreatedDateTime, AgentId, Name, Platform,Instructions, ToolsStr, TriggersStr, McpStr, SkillsStr,CapsStr, OwnerUpn