Core Concepts¶
Understanding the core concepts behind CapiscIO A2A Security will help you use it effectively and make informed configuration decisions.
Unilateral Protection: The Key Difference¶
The core insight: You can't control other agents' security practices, but you can control what YOUR agent accepts and calls.
graph LR
A[Untrusted Agent] -->|Malicious Request| B[Your Agent]
B -->|Always Validates| C{Security Layer}
C -->|Blocks| D[❌ Rejected]
C -->|Allows| E[✅ Processed]
B -->|Calls Other Agent| F{Validates Target}
F -->|Invalid| G[❌ Don't Call]
F -->|Valid| H[✅ Safe to Call]
Why This Matters:
- ❌ You can't control if other agents are compromised
- ❌ You can't force peers to implement security
- ❌ You can't trust that agents follow the protocol correctly
- ✅ But you CAN protect yourself unilaterally
CapiscIO A2A Security ensures:
- All incoming requests are validated before processing
- All outgoing calls are only to validated, safe agents
- Your agent never processes malicious input
- Your agent never calls unsafe endpoints
No peer cooperation required. No permission needed. Just protection.
Security Architecture¶
graph TB
A[Incoming Request] --> B{CapiscIOSecurityExecutor}
B --> C[Downstream Validation]
C --> D[Message Validator]
C --> E[Protocol Validator]
C --> F[Rate Limiter]
C --> G[Signature Validator]
D --> H{All Pass?}
E --> H
F --> H
G --> H
H -->|Yes| I[Your Agent Executor]
H -->|No: Block Mode| J[Reject Request]
H -->|No: Monitor Mode| K[Log + Allow]
I --> L{Calling Other Agent?}
L -->|Yes| M[Upstream Validation]
M --> N[Agent Card Validator]
M --> O[Certificate Validator]
M --> P[URL Security Validator]
N --> Q{Valid?}
O --> Q
P --> Q
Q -->|Yes| R[Make Call]
Q -->|No| S[Handle Error]
Validation Layers¶
1. Downstream Protection (Incoming)¶
Validates requests before they reach your agent.
Validators:
- Message Validator: Schema and structure
-
Why it matters: A missing
message_idcan break your task tracking. Emptypartsarrays crash parsers. We've seen agents brought down by null sender IDs. -
Protocol Validator: A2A protocol compliance
-
Why it matters: Invalid protocol versions cause silent failures. Wrong message types in state transitions create stuck tasks. Header mismatches leak metadata.
-
Signature Validator: JWT/JWS verification (optional)
-
Why it matters: Without signature verification, any agent can impersonate trusted peers. One compromised agent becomes a gateway to your entire agent network.
-
Rate Limiter: Token bucket algorithm
- Why it matters: A single misbehaving agent can send 10,000 requests in seconds, overwhelming your resources and blocking legitimate agents.
Purpose: Protect your agent from: - Malformed messages that crash your code - Protocol violations that create undefined behavior - Excessive requests that exhaust your resources - Spoofed identities claiming to be trusted agents
2. Upstream Protection (Outgoing)¶
Validates agents before you call them.
Validators:
- Agent Card Validator: Discovery metadata
-
Why it matters: An agent card with missing capabilities means you'll call endpoints that don't exist. Invalid provider info means you can't verify identity. Broken discovery = wasted calls and failed tasks.
-
Certificate Validator: TLS/SSL certificates
-
Why it matters: Expired certificates mean man-in-the-middle attacks succeed. Self-signed certs can't be verified. Hostname mismatches expose you to DNS hijacking. We've seen entire agent networks compromised through one expired cert.
-
URL Security Validator: SSRF prevention
-
Why it matters: An attacker sends you
http://localhost/admin/delete-everything. Without validation, your agent makes that call with YOUR credentials. SSRF is how cloud metadata services get compromised. -
Semver Validator: Version compatibility
- Why it matters: Calling an agent with breaking API changes means silent failures or data corruption. Version mismatches are the #1 cause of integration failures in production.
Purpose: Protect your agent from: - Misconfigured agents that waste your calls - Expired certificates that expose your traffic - SSRF attacks that compromise internal services - Version incompatibilities that break integrations
Validation Results¶
Every validation returns a ValidationResult with three score dimensions:
from capiscio_a2a_security.types import ValidationResult, ValidationIssue, ValidationSeverity
result = ValidationResult(
success=True, # Overall pass/fail
compliance=ComplianceScore(total=95, ...),
trust=TrustScore(total=90, ...),
availability=AvailabilityScore(total=None, ...),
issues=[ # List of issues found
ValidationIssue(
severity=ValidationSeverity.WARNING,
code="DEPRECATED_FIELD",
message="Field 'old_param' is deprecated",
path="message.old_param"
)
],
metadata={"validator": "message"} # Additional context
)
Severity Levels¶
| Severity | Impact | Typical Action |
|---|---|---|
| ERROR | Validation fails | Block request (block mode) |
| WARNING | Validation passes | Log for monitoring |
| INFO | No issues | Normal operation |
Scoring System¶
Validation now uses three score dimensions:
- Compliance (0-100): Protocol specification adherence
- Trust (0-100): Security and authenticity signals
- Availability (0-100): Operational readiness (optional)
Each dimension has its own breakdown and rating enum. Example:
result.compliance.total # 0-100
result.trust.total # 0-100
result.availability.total # 0-100 or None
result.compliance.rating # ComplianceRating enum
result.trust.rating # TrustRating enum
result.availability.rating # AvailabilityRating enum
Migration Note:
- Old:
result.score(deprecated) - New:
result.compliance.total,result.trust.total,result.availability.total
Configuration Presets¶
Development Preset¶
Characteristics: - ❌ Signatures not required - ❌ Rate limiting disabled - 📝 Fail mode: log only - ✅ Schema validation enabled
Use when: Local development, debugging, rapid iteration
Production Preset (Default)¶
Characteristics: - ⚪ Signatures optional (verify if present) - ✅ Rate limiting enabled (60/min) - 🚫 Fail mode: block - ✅ All validations enabled
Use when: Production deployment, staging environments
Strict Preset¶
Characteristics: - ✅ Signatures required - ✅ Rate limiting enabled (60/min) - ✅ Upstream agent testing enabled - 🚫 Fail mode: block - ✅ Maximum security settings
Use when: High-security environments, financial transactions, sensitive data
From Environment¶
Loads configuration from environment variables:
# Downstream config
export CAPISCIO_VALIDATE_SCHEMA=true
export CAPISCIO_VERIFY_SIGNATURES=true
export CAPISCIO_REQUIRE_SIGNATURES=false
export CAPISCIO_RATE_LIMITING=true
export CAPISCIO_RATE_LIMIT_RPM=100
# Upstream config
export CAPISCIO_VALIDATE_UPSTREAM=true
export CAPISCIO_CACHE_VALIDATION=true
# General
export CAPISCIO_FAIL_MODE=block
export CAPISCIO_TIMEOUT_MS=5000
Use when: 12-factor apps, containerized deployments, CI/CD pipelines
Fail Modes¶
How the executor responds to validation failures:
Block Mode (Default)¶
Behavior: - ✅ Validation passes → Request proceeds - ❌ Validation fails → Request rejected with error
Use when: Production, security is critical
Monitor Mode¶
Behavior: - ✅ Validation passes → Request proceeds - ❌ Validation fails → Request proceeds with warning log
Use when: Testing security in production, gradual rollout, collecting data
Log Mode¶
Behavior: - ✅ Validation passes → Request proceeds (logged) - ❌ Validation fails → Request proceeds (logged)
Use when: Development, debugging, initial integration
Caching¶
Validation results are cached to improve performance:
config = SecurityConfig.production()
config.upstream.cache_validation = True
config.upstream.cache_timeout = 3600 # 1 hour in seconds
What's Cached: - Agent card validation results - Certificate validation results - JWKS key fetches - URL security checks
Cache Key: Combines validator type + target identifier
TTL (Time To Live): Configurable, default 1 hour
Invalidation: Automatic after TTL expires
Rate Limiting¶
Token bucket algorithm prevents abuse:
config = SecurityConfig.production()
config.downstream.enable_rate_limiting = True
config.downstream.rate_limit_requests_per_minute = 60
How It Works:
- Each agent gets a "bucket" of tokens
- Each request consumes 1 token
- Tokens refill at configured rate (e.g., 60/minute = 1/second)
- Empty bucket = rate limit exceeded
Identifier: Based on agent URL or sender ID
Bucket Size: Equal to requests per minute (burst capacity)
Integration Patterns¶
1. Minimal (One-Liner)¶
Pros: - ✅ Fastest integration - ✅ Sensible defaults - ✅ One line of code
Cons: - ❌ Limited customization - ❌ Uses production preset only
Best for: Getting started, simple use cases
2. Explicit Configuration¶
from capiscio_a2a_security import CapiscIOSecurityExecutor, SecurityConfig
config = SecurityConfig.production()
config.downstream.rate_limit_requests_per_minute = 100
config.fail_mode = "monitor"
agent = CapiscIOSecurityExecutor(
delegate=MyAgentExecutor(),
config=config
)
Pros: - ✅ Full control - ✅ Explicit and readable - ✅ Easy to test
Cons: - ❌ More verbose - ❌ Requires configuration knowledge
Best for: Production deployments, custom requirements
3. Decorator Pattern¶
from capiscio_a2a_security import secure_agent, SecurityConfig
@secure_agent(config=SecurityConfig.production())
class MyAgentExecutor(AgentExecutor):
async def execute(self, context, event_queue):
# Your agent logic
pass
Pros: - ✅ Pythonic - ✅ Clear intent - ✅ Class-level application
Cons: - ❌ Less flexible (applies to all instances) - ❌ Harder to test with different configs
Best for: Framework integration, clean code architecture
Performance Considerations¶
Caching Impact¶
# First call: Full validation (~10-50ms depending on validators)
result1 = validator.validate_agent_card("https://agent.example.com")
# Subsequent calls: Cached (<1ms)
result2 = validator.validate_agent_card("https://agent.example.com")
Async vs Sync¶
# Sync validation (fast, no I/O)
result = validator.validate_message(message) # ~1-5ms
# Async validation (I/O operations)
result = await validator.validate_url_certificate(url) # ~50-200ms
Design Decision: Expensive operations (cert checks, HTTP calls) are: - Optional (can be disabled) - Async (don't block) - Cached (results reused)
Optimization Tips¶
- Enable caching for upstream validation
- Tune rate limits to your needs
- Use production preset (balanced settings)
- Disable unused validators if not needed
config = SecurityConfig.production()
# Disable signature verification if not using signatures
config.downstream.verify_signatures = False
# Disable upstream testing if only receiving requests
config.upstream.test_endpoints = False
Security Model¶
Threat Model¶
Protects Against:
- ✅ Schema violations (malformed messages)
- ✅ Protocol violations (invalid state transitions)
- ✅ SSRF attacks (malicious URLs)
- ✅ Rate limit abuse (DoS attacks)
- ✅ Expired certificates (stale connections)
- ✅ Version incompatibilities (breaking changes)
Does NOT Protect Against:
- ❌ Logic bugs in your agent code
- ❌ Business logic vulnerabilities
- ❌ Infrastructure attacks (DDoS at network layer)
- ❌ Compromised dependencies
Defense in Depth¶
CapiscIO A2A Security is one layer of security:
graph TB
A[Network Security<br/>Firewall] --> B[TLS/HTTPS Encryption]
B --> C[Authentication/Authorization]
C --> D[CapiscIO A2A Security<br/>⭐ Protocol Validation]
D --> E[Your Agent Logic]
E --> F[Data Validation]
style D fill:#4db6ac,stroke:#00695c,stroke-width:3px,color:#fff
Recommendation: Use CapiscIO A2A Security in addition to other security measures, not as a replacement.
Next Steps¶
Now that you understand the core concepts:
- Configure for your needs
- Learn about the scoring system
- See real examples in the Quick Start Guide