Solace Agent Mesh is an event-driven framework that creates distributed ecosystems of collaborative AI agents. At the heart of this collaboration is inter-agent communication - a powerful mechanism that enables agents to discover, communicate with, and delegate tasks to each other while maintaining strict security and access control boundaries.
In this post, we’ll explore how inter-agent communication works in Solace Agent Mesh, the role of the A2A protocol, and how you can use allow_list and deny_list configurations to control agent collaboration patterns.
What is Inter-Agent Communication?
Inter-agent communication is the mechanism that allows agents within the mesh to collaborate by delegating tasks to specialized peer agents. Rather than building monolithic agents that try to do everything, you can create focused, specialized agents that work together to solve complex problems.
For example, imagine you have:
- A Data Analyst Agent specialized in querying databases
- A Report Generator Agent that creates formatted reports
- An Email Agent that handles notifications
An orchestrator agent can receive a user request like “analyze last quarter’s sales and email me a report,” then delegate the data analysis to the Data Analyst Agent, pass those results to the Report Generator Agent, and finally use the Email Agent to send the completed report.
Solace Event Broker and Smart Topics
All inter-agent communication flows through the Solace Event Broker, which serves as the central messaging fabric. The broker uses a hierarchical topic structure to route A2A protocol messages between components with precision and efficiency.
Topic-Based Routing
The A2A protocol leverages Solace’s powerful topic-based pub/sub architecture. Each type of communication uses a specific topic pattern:
| Purpose | Topic Pattern |
|---|---|
| Agent Discovery | {namespace}/a2a/v1/discovery/agentcards` |
| Task Requests | {namespace}/a2a/v1/agent/request/{target_agent_name} |
| Status Updates | {namespace}/a2a/v1/gateway/status/{gateway_id}/{task_id} |
| Final Responses | {namespace}/a2a/v1/gateway/response/{gateway_id}/{task_id} |
| Peer Delegation | {namespace}/a2a/v1/agent/status/{delegating_agent_name}/{sub_task_id} |
This hierarchical structure provides several benefits from a decoupled architecture since agents dont need to know each other’s network and geographical location, dynamic routing based on smart topic subscription, and scalability offered by an event-driven architecture:
Configuring Inter-Agent Communication
The inter_agent_communication configuration section in your agent’s YAML file controls which peer agents an agent can discover and communicate with. This is a critical security and access control mechanism.
Configuration Structure
Here’s the basic structure:
inter_agent_communication:
allow_list: ["*"] # Patterns of agents to ALLOW
deny_list: [] # Patterns of agents to DENY
request_timeout_seconds: 30 # Timeout for peer requests
Configuration Parameters
allow_list: A list of agent name patterns (supports wildcards) that this agent is permitted to discover and delegate tasks to. Default is["*"](all agents allowed).deny_list: A list of agent name patterns to explicitly block, even if they match patterns in the allow_list. Default is[](empty list).request_timeout_seconds: The timeout in seconds for peer agent requests. If a delegated agent doesn’t respond within this time, the requesting agent will be notified of the timeout.
Pattern Matching with Wildcards
Both allow_list and deny_list support wildcard pattern matching using the fnmatch syntax:
*matches zero or more characters?matches exactly one character[abc]matches any character in the brackets[!abc]matches any character NOT in the brackets
This allows for flexible and powerful filtering rules.
How Allow and Deny Lists Work Together
Understanding the precedence rules is crucial for configuring inter-agent communication correctly.
Evaluation Logic
The system evaluates agent access in two steps:
- Allow List Check: First, the system checks if the agent name matches ANY pattern in the
allow_list. If there’s a match, the agent is initially allowed. - Deny List Check: If the agent was allowed in step 1, the system then checks if the agent name matches ANY pattern in the
deny_list. If there’s a match, the agent is denied.
Critical Rule:
deny_listalways takes precedence overallow_list!
Practical Examples
Let’s explore various configuration scenarios to understand how this works in practice.
Example 1: Allow All Agents (Default Behavior)
inter_agent_communication:
allow_list: ["*"]
deny_list: []
request_timeout_seconds: 30
Result: This agent can communicate with all discovered agents in the mesh.
Use Case: Ideal for orchestrator agents that need to coordinate across the entire mesh.
Example 2: Allow All Except Specific Agents
inter_agent_communication:
allow_list: ["*"]
deny_list: ["AdminAgent", "BillingAgent"]
request_timeout_seconds: 30
Result: This agent can communicate with all agents EXCEPT “AdminAgent” and “BillingAgent”.
Use Case: General-purpose agents that should avoid administrative or sensitive systems.
Example 3: Allow Only Specific Agents
inter_agent_communication:
allow_list: ["DataAgent", "AnalysisAgent", "ReportAgent"]
deny_list: []
request_timeout_seconds: 30
Result: This agent can ONLY communicate with “DataAgent”, “AnalysisAgent”, and “ReportAgent”.
Use Case: Specialized agents with tightly controlled collaboration patterns, such as workflow-specific agents.
Example 4: Wildcard Patterns with Exceptions
inter_agent_communication:
allow_list: ["Data*"]
deny_list: ["DataAdmin", "DataArchive"]
request_timeout_seconds: 30
Result: This agent can communicate with all agents whose names start with “Data” (e.g., “DataQuery”, “DataTransform”, “DataValidator”) EXCEPT “DataAdmin” and “DataArchive”.
Use Case: Domain-specific collaboration where you want to allow access to a family of related agents while blocking sensitive subsets.
Example 5: Understanding Deny List Precedence
inter_agent_communication:
allow_list: ["*"]
deny_list: ["CriticalAgent"]
request_timeout_seconds: 30
Question: Can this agent communicate with “CriticalAgent”?
Answer: No. Even though ["*"] in the allow_list matches all agents (including “CriticalAgent”), the deny_list takes precedence and blocks “CriticalAgent” specifically.
This demonstrates the key principle: deny_list always wins.
Example 6: Multiple Wildcard Patterns
inter_agent_communication:
allow_list: ["Query*", "Analysis*", "Report*"]
deny_list: ["*Admin", "*Test"]
request_timeout_seconds: 60
Result: This agent can communicate with agents matching “Query*”, “Analysis*”, or “Report*” patterns, but NOT with any agents ending in “Admin” or “Test”.
Examples:
“QueryEngine” - Allowed (matches “Query*”, doesn’t match deny patterns)
“AnalysisProcessor” - Allowed (matches “Analysis*”)
“QueryAdmin” - Denied (matches “Query*” BUT also matches “*Admin”)
“ReportTest” - Denied (matches “Report*” BUT also matches “*Test”)
Use Case: Complex enterprise environments with naming conventions that distinguish production agents from administrative or testing agents.
Example 7: Disable All Inter-Agent Communication
inter_agent_communication:
allow_list: []
deny_list: []
request_timeout_seconds: 30
Result: This agent cannot communicate with ANY peer agents. An empty allow_list means no agents pass the first check.
Use Case: Isolated agents that only respond to gateway requests and never delegate to other agents, such as simple lookup agents or data retrieval agents.
Example 8: Environment-Based Patterns
inter_agent_communication:
allow_list: ["prod-*"]
deny_list: ["*-deprecated"]
request_timeout_seconds: 30
Result: This agent can only communicate with agents whose names start with “prod-” (production agents), excluding any that end with “-deprecated”.
Use Case: Production agents that should only interact with other production-grade agents, avoiding experimental or deprecated services.
Agent Discovery and Inter-Agent Communication
Inter-agent communication works hand-in-hand with the agent discovery mechanism. Here’s how they interact:
Agent Discovery Process
- Agent Card Publishing: Each agent periodically publishes an “Agent Card” (following the A2A protocol schema describing its capabilities, skills, and identity) to the discovery topic:
{namespace}/a2a/v1/discovery/agentcards - Subscription and Filtering: Other agents subscribe to this discovery topic. When they receive an agent card, they apply their
inter_agent_communicationrules:
- Check if the agent name matches the
allow_list - Check if the agent name matches the
deny_list - Only if allowed, register the agent in their local peer registry
- Dynamic Availability: If an allowed agent stops publishing its card (due to shutdown or failure), it will eventually be removed from the peer registry based on health check timeouts
Enabling/Disabling Discovery
You can control whether an agent participates in discovery:
agent_discovery:
enabled: true
health_check_ttl_seconds: 60
health_check_interval_seconds: 30
inter_agent_communication:
allow_list: ["*"]
deny_list: []
request_timeout_seconds: 30
enabled: true: The agent subscribes to discovery messages and can communicate with peers (subject to allow/deny rules)enabled: false: The agent ignores discovery messages and won’t be able to delegate to peers
Best Practices for Inter-Agent Communication Configuration
1. Use the Principle of Least Privilege
Start with restrictive configurations and explicitly allow only the agents that need to communicate:
inter_agent_communication:
allow_list: [“DataAgent”, “AnalysisAgent”]
deny_list: []
This is more secure than allowing everything and trying to block specific agents.
2. Leverage Naming Conventions
Establish clear naming conventions for your agents and use wildcards effectively:
# All agents follow pattern: {environment}-{domain}-{function}
inter_agent_communication:
allow_list: [“prod-analytics-*”, “prod-data-*”]
deny_list: [“*-admin”, “*-deprecated”]
3. Use Deny Lists for Security Boundaries
Even with wildcard allow patterns, use deny lists to establish security boundaries:
inter_agent_communication:
allow_list: [“*”]
deny_list: [“FinancialAgent”, “HRAgent”, “AdminAgent”]
4. Document Your Communication Patterns
Add comments to your configuration files explaining the communication rules:
inter_agent_communication:
# This orchestrator needs to coordinate across all data processing agents
# but should not access administrative or billing systems
allow_list: [“*”]
deny_list: [“Admin*”, “Billing*”, “HR*”]
request_timeout_seconds: 60 # Longer timeout for complex data operations
5. Test Communication Patterns
After configuring inter-agent communication, verify that agents can communicate as expected by checking logs and monitoring agent discovery events.
Pro Tip: Leverage the hierarchical view offered by the Solace Agent Mesh WebUI Gateway!
Multi-Tier Agent Architecture Example
Let’s say we have an e-commerce analytics platform with the following agents
- OrchestratorAgent: Central coordinator
- DataQueryAgent: Queries databases
- DataTransformAgent: Transforms and cleans data
- AnalyticsEngine: Performs statistical analysis
- ChartingAgent: Creates charts and graphs
- ReportGeneratorAgent: Assembles final reports
- NotificationAgent: Sends email notifications
- AdminAgent: System administration tasks
Configuration Strategy
OrchestratorAgent Configuration:
inter_agent_communication:
# Can delegate to all agents except admin
allow_list: [“*”]
deny_list: [“AdminAgent”]
request_timeout_seconds: 60
DataQueryAgent Configuration:
inter_agent_communication:
# Only communicates with DataTransformAgent for data pipelines
allow_list: [“DataTransformAgent”]
deny_list: []
request_timeout_seconds: 30
AnalyticsEngine Configuration:
inter_agent_communication:
# Needs data and can trigger visualizations
allow_list: [“Data*”, “ChartingAgent”]
deny_list: [“AdminAgent”]
request_timeout_seconds: 90
ReportGeneratorAgent Configuration:
inter_agent_communication:
# Aggregates results from analytics and visualization
allow_list: [“AnalyticsEngine”, “ChartingAgent”, “NotificationAgent”]
deny_list: []
request_timeout_seconds: 45
AdminAgent Configuration:
inter_agent_communication:
# Can communicate with all agents for monitoring
allow_list: [“*”]
deny_list: []
request_timeout_seconds: 30
NotificationAgent Configuration:
inter_agent_communication:
# Isolated agent - only receives delegation, never initiates
allow_list: []
deny_list: []
request_timeout_seconds: 15
This architecture creates clear boundaries and controlled communication patterns, ensuring agents only interact with the peers they need while maintaining security and preventing unintended cross-communication.
Last Words of Wisdom
Remember the key principles:
- Deny lists take precedence - use them to establish security boundaries
- Start restrictive - explicitly allow what’s needed rather than blocking what’s not
- Use wildcards wisely - leverage naming conventions for maintainable configurations
- Document your patterns - make communication rules clear for your team
- Make use of the Solace Agent Mesh WebUI Agent Visualizer!
With these tools and best practices, you can build sophisticated multi-agent systems that are both powerful and secure.
For more information about Solace Agent Mesh, visit the official Agent Mesh GitHub repository