This example demonstrates cross-domain federation using SPIFFE trust bundles, enabling agents from different organizations or cloud environments to communicate securely.
In this scenario:
- Organization A (
hvs.solutions) operates agents in GCP - Organization B (
partner.example.com) operates agents in AWS - Agents need to communicate across organizational boundaries
- Each organization maintains its own SPIRE server and trust domain
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ Organization A (GCP) │ │ Organization B (AWS) │
│ Trust Domain: hvs.solutions │ │ Trust Domain: partner.ex... │
├─────────────────────────────────┤ ├─────────────────────────────────┤
│ │ │ │
│ ┌──────────────────────┐ │ │ ┌──────────────────────┐ │
│ │ SPIRE Server A │◄──────┼─────┼─►│ SPIRE Server B │ │
│ │ (Trust Bundle │ │ │ │ (Trust Bundle │ │
│ │ Exchange) │ │ │ │ Exchange) │ │
│ └──────────┬───────────┘ │ │ └──────────┬───────────┘ │
│ │ │ │ │ │
│ ┌──────────▼───────────┐ │ │ ┌──────────▼───────────┐ │
│ │ SPIRE Agent A │ │ │ │ SPIRE Agent B │ │
│ └──────────┬───────────┘ │ │ └──────────┬───────────┘ │
│ │ │ │ │ │
│ ┌──────────▼───────────┐ │ │ ┌──────────▼───────────┐ │
│ │ Data Processor │ │ │ │ Analytics Agent │ │
│ │ SPIFFE ID: │◄──────┼─────┼─►│ SPIFFE ID: │ │
│ │ spiffe://hvs... │ │ │ │ spiffe://partner... │ │
│ └──────────────────────┘ │ │ └──────────────────────┘ │
│ │ │ │
└─────────────────────────────────┘ └─────────────────────────────────┘
Each SPIRE server must be configured to federate with the other:
SPIRE Server A (hvs.solutions):
server {
trust_domain = "hvs.solutions"
# ... other config ...
}
# Federation with partner.example.com
plugins {
BundlePublisher "https_web" {
plugin_data {
address = "0.0.0.0:8443"
acme {
domain_name = "spire-server.hvs.solutions"
email = "admin@hvs.solutions"
}
}
}
}SPIRE Server B (partner.example.com):
server {
trust_domain = "partner.example.com"
# ... other config ...
}
# Federation with hvs.solutions
plugins {
BundlePublisher "https_web" {
plugin_data {
address = "0.0.0.0:8443"
acme {
domain_name = "spire-server.partner.example.com"
email = "admin@partner.example.com"
}
}
}
}On SPIRE Server A:
# Fetch partner's trust bundle
spire-server bundle show -format spiffe \
-trustDomain partner.example.com \
-endpointURL https://spire-server.partner.example.com:8443
# Set the federated bundle
spire-server bundle set \
-format spiffe \
-id spiffe://partner.example.com \
-path partner-bundle.pemOn SPIRE Server B:
# Fetch HVS's trust bundle
spire-server bundle show -format spiffe \
-trustDomain hvs.solutions \
-endpointURL https://spire-server.hvs.solutions:8443
# Set the federated bundle
spire-server bundle set \
-format spiffe \
-id spiffe://hvs.solutions \
-path hvs-bundle.pemData Processor Agent (Organization A):
# config/data-processor.yaml
agent:
name: "data-processor"
trust_domain: "hvs.solutions"
description: "Processes data from federated sources"
capabilities:
- name: "process_data"
description: "Process data and return results"
input_modes: ["application/json"]
output_modes: ["application/json"]
identity:
provider: "spiffe"
spiffe_endpoint: "unix:///run/spire/sockets/agent.sock"
allowed_trust_domains:
- "hvs.solutions" # Own domain
- "partner.example.com" # Federated domain
authorization:
provider: "opa"
opa_endpoint: "http://localhost:8181"
policy_path: "hvs/authz"
default_action: "deny"Analytics Agent (Organization B):
# config/analytics-agent.yaml
agent:
name: "analytics-agent"
trust_domain: "partner.example.com"
description: "Performs analytics on data"
capabilities:
- name: "analyze"
description: "Analyze data using ML models"
input_modes: ["application/json"]
output_modes: ["application/json"]
identity:
provider: "spiffe"
spiffe_endpoint: "unix:///run/spire/sockets/agent.sock"
allowed_trust_domains:
- "partner.example.com" # Own domain
- "hvs.solutions" # Federated domain
authorization:
provider: "opa"
opa_endpoint: "http://localhost:8181"
policy_path: "partner/authz"
default_action: "deny"Organization A Policy (hvs/authz.rego):
package hvs.authz
import rego.v1
default allow := false
# Allow internal communication within hvs.solutions
allow if {
startswith(input.caller_spiffe_id, "spiffe://hvs.solutions/")
startswith(input.callee_spiffe_id, "spiffe://hvs.solutions/")
}
# Allow partner.example.com analytics agent to call our processor
allow if {
input.caller_spiffe_id == "spiffe://partner.example.com/agent/analytics-agent/prod"
input.callee_spiffe_id == "spiffe://hvs.solutions/agent/data-processor/prod"
input.action == "process_data"
}
# Log all cross-domain requests
cross_domain_request if {
caller_domain := split(input.caller_spiffe_id, "/")[2]
callee_domain := split(input.callee_spiffe_id, "/")[2]
caller_domain != callee_domain
}Organization B Policy (partner/authz.rego):
package partner.authz
import rego.v1
default allow := false
# Allow internal communication within partner.example.com
allow if {
startswith(input.caller_spiffe_id, "spiffe://partner.example.com/")
startswith(input.callee_spiffe_id, "spiffe://partner.example.com/")
}
# Allow our analytics agent to call hvs.solutions processor
allow if {
input.caller_spiffe_id == "spiffe://partner.example.com/agent/analytics-agent/prod"
startswith(input.callee_spiffe_id, "spiffe://hvs.solutions/")
input.action in ["process_data", "query_data"]
}Data Processor Agent:
from agentweave import SecureAgent, capability, requires_peer
from agentweave.types import TaskResult
class DataProcessorAgent(SecureAgent):
"""Processes data from any trusted domain."""
@capability("process_data")
@requires_peer("spiffe://*/agent/*") # Accept from any federated domain
async def process_data(self, data: dict) -> TaskResult:
"""
Process data from federated agent.
Authorization is enforced by OPA policy, which restricts
which specific agents can call this capability.
"""
# Get caller's SPIFFE ID from request context
caller_id = self.current_request_context.caller_spiffe_id
caller_domain = caller_id.split("/")[2]
self.logger.info(f"Processing data from federated domain: {caller_domain}")
processed = {
"original_data": data,
"processed_by": self.spiffe_id,
"caller": caller_id,
"timestamp": self.current_time()
}
return TaskResult(
status="completed",
artifacts=[{
"type": "processed_data",
"data": processed
}]
)Analytics Agent:
from agentweave import SecureAgent, capability
from agentweave.types import TaskResult
class AnalyticsAgent(SecureAgent):
"""Performs analytics using federated data sources."""
@capability("analyze")
async def analyze(self, query: dict) -> TaskResult:
"""Run analysis across federated data sources."""
# Call data processor in different trust domain
processor_result = await self.call_agent(
target="spiffe://hvs.solutions/agent/data-processor/prod",
task_type="process_data",
payload={
"query": query,
"requester": self.spiffe_id
}
)
# Perform analytics on processed data
processed_data = processor_result.artifacts[0]["data"]
analytics = {
"data_source": "hvs.solutions",
"analysis": self._run_analytics(processed_data),
"metadata": {
"cross_domain": True,
"trust_domains": ["hvs.solutions", "partner.example.com"]
}
}
return TaskResult(
status="completed",
artifacts=[{
"type": "analytics_report",
"data": analytics
}]
)For simplified cross-cloud networking, combine SPIFFE identity with Tailscale connectivity:
# Tailscale ACL (tailscale.com admin console)
{
"acls": [
{
"action": "accept",
"src": ["tag:hvs-agents"],
"dst": ["tag:partner-agents:8443"]
},
{
"action": "accept",
"src": ["tag:partner-agents"],
"dst": ["tag:hvs-agents:8443"]
}
],
"tagOwners": {
"tag:hvs-agents": ["admin@hvs.solutions"],
"tag:partner-agents": ["admin@partner.example.com"]
}
}Agents automatically discover each other via MagicDNS:
data-processor.hvs-agents.ts.netanalytics-agent.partner-agents.ts.net
Important: Tailscale provides network connectivity only. SPIFFE still provides cryptographic identity and mTLS encryption.
- Trust Bundle Rotation: Automate trust bundle updates using SPIRE's federation API
- Policy Review: Cross-domain policies should be reviewed by both organizations
- Audit Logging: Enable audit logs for all federated calls
- Rate Limiting: Implement rate limits for cross-domain requests
- Monitoring: Set up alerts for unusual cross-domain traffic patterns
# Test from Organization A to Organization B
hvs-agent call \
--from spiffe://hvs.solutions/agent/data-processor/prod \
--to spiffe://partner.example.com/agent/analytics-agent/prod \
--task analyze \
--payload '{"query": "test"}'
# Verify trust bundle is valid
spire-server bundle show -trustDomain partner.example.com
# Check OPA policy evaluation
hvs-agent authz check \
--caller spiffe://partner.example.com/agent/analytics-agent/prod \
--callee spiffe://hvs.solutions/agent/data-processor/prod \
--action process_data# Refresh trust bundle
spire-server bundle refresh -id spiffe://partner.example.com
# Verify bundle contents
openssl x509 -in partner-bundle.pem -text -noout- Check that both domains are in
allowed_trust_domains - Verify SPIRE agents can access updated trust bundles
- Ensure firewall rules allow traffic on port 8443
- Review OPA policy logs:
docker logs opa - Test policy in OPA Playground
- Verify SPIFFE IDs match policy exactly