Skip to content

Commit 447a8a0

Browse files
authored
feat: SimpleGuard Enforcement Strategy (v0.3.0) (#5)
* feat: implement SimpleGuard enforcement strategy (v0.3.0) * fix: add missing dependencies and type annotations for CI * fix: address PR review comments (security, docs, cleanup)
1 parent 23fc7ee commit 447a8a0

14 files changed

Lines changed: 941 additions & 157 deletions

File tree

CHANGELOG.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,27 @@ pip install capiscio-sdk==0.1.0
9090

9191
## [Unreleased]
9292

93-
### Planned for v0.2.0
94-
- Signature verification (crypto validation)
95-
- Agent card validation
96-
- Upstream agent testing
97-
- Integration tests
98-
- End-to-end tests
99-
- Performance benchmarks
93+
## [0.3.0] - 2025-11-22
94+
95+
### Added
96+
- **SimpleGuard Security Strategy**:
97+
- **Identity**: Ed25519 JWS signature verification (`X-Capiscio-JWS` header).
98+
- **Integrity**: SHA-256 Body Hash verification (`bh` claim) to prevent payload tampering.
99+
- **Freshness**: Replay protection using `exp` (expiration) and `iat` (issued at) claims with a 60-second window.
100+
- **Zero Config**: Secure by default with minimal setup.
101+
- **FastAPI Integration**:
102+
- `CapiscioMiddleware`: Automatic request validation and identity injection into `request.state.agent_id`.
103+
- `Server-Timing` header support for telemetry (verification time).
104+
- **Telemetry**:
105+
- Added `dur` (duration) metric to `Server-Timing` header for monitoring security overhead.
106+
- **Documentation**:
107+
- Updated `README.md` with "Enforcement First" strategy.
108+
- Updated `SECURITY.md` with threat model and verification steps.
109+
- Added `examples/secure_ping_pong` demo.
110+
111+
### Changed
112+
- **Breaking Change**: Shifted from "Validation" focus to "Enforcement" focus.
113+
- Updated `pyproject.toml` dependencies to include `cryptography` and `pyjwt`.
100114

101115
### Planned for v1.0.0
102116
- Full A2A v1.0 compliance

README.md

Lines changed: 47 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,182 +1,82 @@
11
# CapiscIO SDK (Python)
22

3-
**Runtime security middleware for A2A (Agent-to-Agent) protocol agents**
3+
**Enforcement-First Security for A2A Agents.**
44

55
[![PyPI version](https://badge.fury.io/py/capiscio-sdk.svg)](https://badge.fury.io/py/capiscio-sdk)
66
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
77
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
88

9-
## What is CapiscIO SDK?
9+
**CapiscIO** is the "Customs Officer" for your AI Agent. It provides military-grade Identity and Integrity enforcement for the [Agent-to-Agent (A2A) Protocol](https://github.com/google/A2A) with **zero configuration**.
1010

11-
CapiscIO SDK provides **always-on runtime protection** for agents using the [A2A (Agent-to-Agent) protocol](https://github.com/google/A2A). It wraps your agent executor to validate incoming requests, verify signatures, and protect against malicious actors—all without requiring peer cooperation.
11+
## 🚀 The 60-Second Upgrade
1212

13-
### Key Features
14-
15-
-**Message validation** - Schema and protocol compliance checking
16-
-**Signature verification** - JWS/JWKS cryptographic validation (RFC 7515)
17-
-**Upstream protection** - Validate agents you call
18-
-**Downstream protection** - Validate agents calling you
19-
-**Rate limiting** - Token bucket algorithm
20-
-**Caching** - Performance-optimized validation results
21-
-**Three integration patterns** - Minimal, explicit, or decorator
22-
23-
## Installation
24-
25-
```bash
26-
pip install capiscio-sdk
27-
```
28-
29-
## Quick Start
30-
31-
32-
### Pattern 1: Minimal (One-liner with Preset)
13+
Turn any FastAPI application into a Verified A2A Agent in 3 lines of code.
3314

3415
```python
35-
from capiscio_sdk import secure, SecurityConfig
36-
from a2a.server.request_handlers import DefaultRequestHandler
37-
from a2a.server.tasks import InMemoryTaskStore
38-
39-
# Wrap your agent with security (production defaults)
40-
agent = secure(MyAgentExecutor(), SecurityConfig.production())
41-
42-
# Use in A2A request handler
43-
handler = DefaultRequestHandler(
44-
agent_executor=agent,
45-
task_store=InMemoryTaskStore()
46-
)
47-
48-
# Access validation results (three-dimensional scoring)
49-
result = await agent.validate_agent_card(card_url)
50-
print(result.compliance.total, result.trust.total, result.availability.total)
51-
```
16+
from fastapi import FastAPI
17+
from capiscio_sdk.simple_guard import SimpleGuard
18+
from capiscio_sdk.integrations.fastapi import CapiscioMiddleware
5219

53-
### Pattern 2: Granular Control
20+
# 1. Initialize Guard (Auto-generates keys in dev_mode)
21+
guard = SimpleGuard(dev_mode=True)
5422

55-
```python
56-
from capiscio_sdk import CapiscIOSecurityExecutor, SecurityConfig
57-
58-
# Start with a preset, customize what matters to you
59-
config = SecurityConfig.production()
60-
config.downstream.rate_limit_requests_per_minute = 100 # Higher rate limit
61-
config.downstream.require_signatures = True # Enforce signatures
62-
config.upstream.test_endpoints = True # Test before calling
63-
config.fail_mode = "monitor" # Log but don't block yet
64-
65-
secure_agent = CapiscIOSecurityExecutor(
66-
delegate=MyAgentExecutor(),
67-
config=config
68-
)
69-
```
23+
app = FastAPI()
7024

71-
### Pattern 3: Environment-Driven (12-Factor App)
25+
# 2. Add Enforcement Middleware
26+
app.add_middleware(CapiscioMiddleware, guard=guard)
7227

73-
```python
74-
from capiscio_sdk import secure_agent, SecurityConfig
75-
from a2a import AgentExecutor, RequestContext, EventQueue
76-
77-
@secure_agent(config=SecurityConfig.from_env())
78-
class MyAgentExecutor(AgentExecutor):
79-
async def execute(self, context: RequestContext, event_queue: EventQueue):
80-
# Your agent logic - config loaded from env vars
81-
pass
82-
83-
# Already secured - use directly!
84-
handler = DefaultRequestHandler(agent_executor=MyAgentExecutor())
28+
@app.post("/agent/task")
29+
async def handle_task(request: Request):
30+
# 🔒 Only reachable if Identity + Integrity are verified
31+
caller = request.state.agent_id
32+
return {"status": "accepted", "verified_caller": caller}
8533
```
8634

87-
**All 16 configuration options documented in the [Configuration Guide](https://docs.capisc.io/sdk-python/guides/configuration/).**
88-
89-
## Why CapiscIO?
90-
91-
### The Problem
35+
## 🛡️ What You Get (Out of the Box)
9236

93-
When building A2A agents, you face security risks from:
94-
- **Malicious downstream agents** sending invalid/malicious requests
95-
- **Broken upstream dependencies** with invalid agent cards
96-
- **Protocol violations** causing runtime failures
97-
- **Missing signatures** with no authenticity verification
37+
1. **Zero-Config Identity**:
38+
* Auto-generates **Ed25519** keys and `agent-card.json` on first run.
39+
* No manual key management required for development.
9840

99-
### The Solution
41+
2. **Payload Integrity**:
42+
* Enforces **SHA-256 Body Hash (`bh`)** verification.
43+
* Blocks tampered payloads instantly (returns `403 Forbidden`).
10044

101-
CapiscIO wraps your agent executor and provides:
45+
3. **Replay Protection**:
46+
* Enforces strict **60-second** token expiration (`exp`).
47+
* Prevents replay attacks and ensures freshness.
10248

103-
1. **Downstream Protection** - Validates all incoming requests
104-
2. **Upstream Protection** - Validates agents you call
105-
3. **Always-On** - Works without peer cooperation
106-
4. **Performance** - Caching and parallel validation
107-
5. **Three-Dimensional Scoring** - Compliance, trust, and availability insights
49+
4. **Performance Telemetry**:
50+
* Adds `<1ms` overhead.
51+
* Includes `Server-Timing` headers for transparent monitoring.
10852

109-
## Configuration
110-
111-
### Presets
112-
113-
```python
114-
# Development - Permissive, verbose logging
115-
SecurityConfig.development()
53+
## Installation
11654

117-
# Production - Balanced (default)
118-
SecurityConfig.production()
55+
```bash
56+
pip install capiscio-sdk
57+
```
11958

120-
# Strict - Maximum security
121-
SecurityConfig.strict()
59+
## How It Works
12260

123-
# From environment variables
124-
SecurityConfig.from_env()
125-
```
61+
### 1. The Handshake
62+
CapiscIO enforces the **A2A Trust Protocol**:
63+
* **Sender**: Signs the request body (JWS + Body Hash).
64+
* **Receiver**: Verifies the signature and re-hashes the body to ensure integrity.
12665

127-
### Custom Configuration
66+
### 2. The "Customs Officer"
67+
The `SimpleGuard` acts as a local authority. It manages your agent's "Passport" (Agent Card) and verifies the "Visas" (Tokens) of incoming requests.
12868

129-
```python
130-
from capiscio_sdk import SecurityConfig, DownstreamConfig, UpstreamConfig
131-
132-
config = SecurityConfig(
133-
downstream=DownstreamConfig(
134-
validate_schema=True,
135-
verify_signatures=True,
136-
require_signatures=False,
137-
enable_rate_limiting=True,
138-
rate_limit_requests_per_minute=100
139-
),
140-
upstream=UpstreamConfig(
141-
validate_agent_cards=True,
142-
verify_signatures=True,
143-
cache_validation=True,
144-
cache_timeout=3600 # seconds
145-
),
146-
fail_mode="block", # "block" | "monitor" | "log"
147-
timeout_ms=5000
148-
)
69+
### 3. Telemetry
70+
Every response includes a `Server-Timing` header showing exactly how fast the verification was:
71+
```http
72+
Server-Timing: capiscio-auth;dur=0.618;desc="CapiscIO Verification"
14973
```
15074

15175
## Documentation
15276

153-
- [Quickstart Guide](docs/quickstart.md)
154-
- [Configuration Reference](docs/configuration.md)
155-
- [API Documentation](docs/api-reference.md)
156-
- [Examples](examples/)
157-
158-
## Roadmap
159-
160-
- **V1.0** (Q4 2025) - Core middleware (this package)
161-
- **V2.0** (Q2 2026) - Extension protocol (validation feedback)
162-
- **V3.0** (Q3 2026) - Platform integration (trust network)
163-
- **V4.0** (Q4 2026) - Enterprise features (policies, audit logs)
164-
165-
## Contributing
166-
167-
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
77+
- [Official Documentation](https://docs.capisc.io)
78+
- [A2A Protocol Spec](https://github.com/google/A2A)
16879

16980
## License
17081

17182
Apache License 2.0 - see [LICENSE](LICENSE) for details.
172-
173-
## About A2A
174-
175-
The [Agent-to-Agent (A2A) protocol](https://github.com/google/A2A) is an open standard for agent interoperability, supported by Google and 50+ partners including Salesforce, ServiceNow, SAP, Intuit, and more. CapiscIO provides the security layer for production A2A deployments.
176-
177-
## Support
178-
179-
- **Issues:** [GitHub Issues](https://github.com/capiscio/capiscio-sdk-python/issues)
180-
- **Discussions:** [GitHub Discussions](https://github.com/capiscio/capiscio-sdk-python/discussions)
181-
- **Documentation:** [docs.capisc.io](https://docs.capisc.io)
182-
- **Website:** [capisc.io](https://capisc.io)

SECURITY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
| Version | Supported |
66
| ------- | ------------------ |
7-
| 0.1.x | :white_check_mark: |
7+
| 0.2.x | :white_check_mark: |
8+
| 0.1.x | :x: |
89

910
## Reporting a Vulnerability
1011

capiscio_sdk/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
# Core exports
1414
from .executor import CapiscioSecurityExecutor, secure, secure_agent
15+
from .simple_guard import SimpleGuard
1516
from .config import SecurityConfig, DownstreamConfig, UpstreamConfig
1617
from .errors import (
1718
CapiscioSecurityError,
@@ -25,6 +26,7 @@
2526
__all__ = [
2627
"__version__",
2728
"CapiscioSecurityExecutor",
29+
"SimpleGuard",
2830
"secure",
2931
"secure_agent",
3032
"SecurityConfig",

capiscio_sdk/errors.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,13 @@ class CapiscioTimeoutError(CapiscioSecurityError):
6767
"""Operation timed out."""
6868

6969
pass
70+
71+
72+
class ConfigurationError(CapiscioSecurityError):
73+
"""Missing keys or invalid paths (SimpleGuard)."""
74+
pass
75+
76+
77+
class VerificationError(CapiscioSecurityError):
78+
"""Invalid signature, expired token, or untrusted key (SimpleGuard)."""
79+
pass
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""FastAPI integration for Capiscio SimpleGuard."""
2+
from typing import Callable, Awaitable, Any, Dict
3+
try:
4+
from starlette.middleware.base import BaseHTTPMiddleware
5+
from starlette.requests import Request
6+
from starlette.responses import JSONResponse, Response
7+
from starlette.types import ASGIApp
8+
except ImportError:
9+
raise ImportError("FastAPI/Starlette is required for this integration. Install with 'pip install fastapi'.")
10+
11+
from ..simple_guard import SimpleGuard
12+
from ..errors import VerificationError
13+
import time
14+
15+
class CapiscioMiddleware(BaseHTTPMiddleware):
16+
"""
17+
Middleware to enforce A2A identity verification on incoming requests.
18+
"""
19+
def __init__(self, app: ASGIApp, guard: SimpleGuard) -> None:
20+
super().__init__(app)
21+
self.guard = guard
22+
23+
async def dispatch(
24+
self,
25+
request: Request,
26+
call_next: Callable[[Request], Awaitable[Response]]
27+
) -> Response:
28+
# Allow health checks or public endpoints if needed
29+
# For now, we assume everything under /agent/ needs protection
30+
# But let's just check for the header.
31+
32+
if request.method == "OPTIONS":
33+
return await call_next(request)
34+
35+
auth_header = request.headers.get("X-Capiscio-JWS")
36+
37+
# If no header, we might let it pass but mark as unverified?
38+
# The mandate says: "Returns 401 (missing) or 403 (invalid)."
39+
if not auth_header:
40+
return JSONResponse(
41+
{"error": "Missing X-Capiscio-JWS header. This endpoint is protected by CapiscIO."},
42+
status_code=401
43+
)
44+
45+
start_time = time.perf_counter()
46+
try:
47+
# Read the body for integrity check
48+
body_bytes = await request.body()
49+
50+
# Verify the JWS with body
51+
payload = self.guard.verify_inbound(auth_header, body=body_bytes)
52+
53+
# Reset the receive channel so downstream can read the body
54+
async def receive() -> Dict[str, Any]:
55+
return {"type": "http.request", "body": body_bytes, "more_body": False}
56+
request._receive = receive
57+
58+
# Inject claims into request.state
59+
request.state.agent = payload
60+
request.state.agent_id = payload.get("iss")
61+
62+
except VerificationError as e:
63+
return JSONResponse({"error": f"Access Denied: {str(e)}"}, status_code=403)
64+
65+
verification_duration = (time.perf_counter() - start_time) * 1000
66+
67+
response = await call_next(request)
68+
69+
# Add Server-Timing header (standard for performance metrics)
70+
# Syntax: metric_name;dur=123.4;desc="Description"
71+
response.headers["Server-Timing"] = f"capiscio-auth;dur={verification_duration:.3f};desc=\"CapiscIO Verification\""
72+
73+
return response

0 commit comments

Comments
 (0)