Skip to content

vitonique/a2a-secure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

259 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A2A Secure

Cryptographically signed communication for AI agents.

License: MIT Python 3.10+ Tests Schema v2.6 Google A2A Zero Dependencies

Google A2A tells agents how to talk. A2A Secure makes sure every message is authentic.

Live Demo · Documentation · Roadmap


The Gap

The Google A2A protocol defines how AI agents discover and communicate. It says nothing about securing that conversation. Red Hat, Semgrep, and multiple academic papers have documented the same gap.

Feature Google A2A A2A Secure
Authentication Bearer token Ed25519 signatures
Transport Security TLS only Ed25519 signatures + TLS
Key rotation Manual Automatic (24h TTL)
Replay protection None 60s window + trace ID
Key compromise blast radius Full system Current session only
Self-healing on key change No Automatic /introduce

A2A Secure is a drop-in security extension. Same JSON-RPC 2.0 interface, with cryptographic signatures added. Starting with A2A — MCP support planned.

Features

Feature Description
Ed25519 Signing Every message signed; receiver verifies cryptographically
Cold/Hot Key Architecture Offline cold key delegates to rotating hot key (24h TTL)
Self-Healing Trust Key rotation triggers automatic re-introduction — zero downtime
Google A2A Compatible JSON-RPC 2.0 proxy adapter (/.well-known/agent.json + POST /a2a)
Trust Registry Local-first key management, TOFU+pin, append-only audit log
Replay Protection 60s timestamp window + trace ID deduplication
Retry + Dead Letters Exponential backoff; failed messages stored for debugging
Zero Dependencies Pure Python 3.10+, no external services required

Quick Start

Prerequisites

pip install cryptography eth-account PyJWT

Set the keystore passphrase for encrypted-at-rest hot key storage:

export A2A_KEYSTORE_PASSPHRASE="your-secure-passphrase"
# Add to systemd EnvironmentFile for production

1. Generate Identity

Identity keys are created automatically when the server starts for the first time. The cold key (Ed25519) is stored in ~/.config/a2a/keys/cold_ed25519.json and the hot key rotates every 24 hours. Hot keys are encrypted at rest using AES-256-GCM (requires A2A_KEYSTORE_PASSPHRASE).

No manual key generation step is needed — proceed to Step 2.

2. Initialize Trust Registry

python3 tools/trustreg.py init

3. Add Partner's Key

python3 tools/trustreg.py add-key \
  --id partner-name \
  --type ed25519 \
  --pub <partner-public-key-hex> \
  --tier verified \
  --use a2a

4. Start Server

python3 server.py
# Listening on :8080, strict mode ON

5. Send First Message

python3 send.py "Hello from the other side!"
# Signed with Ed25519, delivered over TLS

Both agents now have mutual authentication. From zero to authenticated A2A in under 10 minutes.

Architecture

Message Flow

Agent A                              Agent B
   |                                    |
   |-- signed -------------------->| 1. Verify Ed25519 signature
   |   (Ed25519)                   | 2. Check Trust Registry
   |                                | 3. Verify + process
   |<------------- signed reply ---| 4. Sign response
   |                                    |

Cold/Hot Key Architecture

Cold Key (offline, never rotates)         Trust Registry
   |                                         |
   +-- delegation chain --> Hot Key          +-- keys.json (known agents)
       (Ed25519 signed)    (24h TTL)         +-- pins.json (TOFU pinning)
                            |                +-- audit.log (append-only)
                            +-- signs messages
                            +-- rotates automatically

Self-Healing Trust

When a hot key rotates, peers don't recognize the new key. The protocol recovers automatically:

Agent A --- message -------> Agent B
                              | 403: unknown key
Agent A <-- /introduce ------+
            (delegation chain: cold key vouches for new hot key)
Agent A --- retry ----------> Agent B
                              | 200: delivered

Zero downtime. Zero human intervention. The cold key never changes, so trust persists across rotations.

Google A2A Compatibility

A2A Secure runs as a transparent proxy. Existing Google A2A clients work unchanged:

PORT 8080 (single process, path-based routing)
+---------------------------------------------+
| A2A Secure              |  Google A2A        |
| (encrypted, signed)     |  (JSON-RPC 2.0)   |
|                         |                    |
| GET  /                  | GET  /.well-known/ |
| POST /                  |      agent.json    |
| POST /introduce         | POST /a2a          |
| GET  /health            |   message/send     |
| POST /messages          |   tasks/get        |
| GET  /messages/<id>     |   tasks/cancel     |
+---------------------------------------------+

The Agent Card at /.well-known/agent.json advertises an optional urn:a2a-secure:v2.6 extension. Google A2A clients can include A2A Secure signatures in message.metadata for authenticated communication.

Local Validation

Run a two-node smoke test locally (no cloud infrastructure required):

python tools/local_harness.py run

This starts two isolated nodes (Alice on :8081, Bob on :8082), runs 13 cross-node smoke checks covering card fetch, health, agent card, signed /introduce key exchange, signed POST / message delivery, /messages auth gates (store and fetch), bidirectional Google A2A message/send, and 404 handling, then tears down. All state is confined to a temp workspace.

See docs/LOCAL_VALIDATION.md for the full workflow.

Interactive demo: agentseal.dev

API Reference

A2A Secure Endpoints

Method Path Description
GET / Agent card (name, version, public key)
GET /health Health check
POST / Receive signed + encrypted message
POST /introduce Self-healing key exchange
POST /messages Store encrypted blob
GET /messages/<id> Fetch blob (delete-on-read)

Google A2A Endpoints

Method Path Description
GET /.well-known/agent.json Agent Card
POST /a2a JSON-RPC 2.0 (message/send, tasks/get, tasks/cancel)

Message Format (v2.6)

{
  "message": "Hello",
  "sender": "Zen",
  "schema_version": "2.6",
  "trace_id": "zen-20260208-0900-hello",
  "sig": "base64-ed25519-signature",
  "identity": {
    "hot_pub_b64": "base64-ed25519-pubkey"
  }
}

Documentation

Document Description
SCHEMA.md Message schema v2.6
IDENTITY_SPEC.md Identity and signing specification
TRUST_REGISTRY_SPEC.md Trust Registry: data model, policy, threat model
EIP712_DELEGATION_SPEC.md Cold wallet → hot key delegation
HARDENING_SPEC.md Rate limiting + replay protection
ROADMAP.dev.md Development roadmap

Project Structure

a2a-secure/
├── server.py              # HTTP server (path routing, strict mode)
├── send.py                # CLI client (sign, encrypt, retry)
├── identity.py            # Ed25519 key management + rotation
├── config.py              # Config loader (a2a_config.json)
├── google_a2a.py          # Google A2A JSON-RPC adapter
├── trust.py               # Trust registry operations + intro cards
├── hardening.py           # Replay protection, rate limiting, idempotency
├── wake.py                # Instant wake integration
├── schema.py              # Schema versioning + trace ID generation
├── tools/
│   └── trustreg.py        # Trust Registry CLI
├── tests/                 # 413 unit tests (26 files)
├── docs/                  # Specifications
├── pyproject.toml         # Project metadata + tool config
├── Makefile               # make test / make lint / make clean
└── requirements.txt

Security

  • Strict mode rejects unsigned messages (default on)
  • Ed25519 signatures on every message
  • Cold/hot key separation — compromise of hot key does not compromise identity
  • 24h automatic key rotation with self-healing trust
  • Replay protection — 60s window + trace ID deduplication
  • Trust Registry with append-only audit log
  • Public key cryptography — Ed25519 signing, no symmetric key exchange
  • Rate limiting on all endpoints

Roadmap

  • Ed25519 signed messaging
  • Bidirectional signed A2A
  • Trust Registry CLI
  • Cold wallet delegation (EIP-712)
  • Hardening: rate limit + replay protection
  • Google A2A Proxy Adapter (Phase 1)
  • Google A2A Phase 2: outbound client, message/stream (SSE)
  • MCP (Model Context Protocol) security extension
  • a2a-secure pip package
  • Web of trust (key endorsements)

License

MIT


Built by AI agents who needed to talk securely.

About

End-to-end encrypted communication for AI agents. The security layer that Google A2A forgot.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors