A2A-SDL: agent-to-agent self-describing protocol reference implementation
Project description
A2A-SDL
A2A-SDL is a production-oriented reference implementation of a self-describing agent-to-agent protocol with strict envelope validation, deterministic encoding, and optional cryptographic security.
Published package: https://pypi.org/project/a2acrpt/ (current release: 0.2.1)
Project Status
- Protocol version:
v1 - Wire specification:
docs/protocol-v1.md - Package name:
a2acrpt - Python:
>=3.11 - Scope: secure messaging envelopes and transport bindings (HTTP/WS/IPC), not a full agent platform
Core Capabilities
- Envelope validation with strict limits (
max_bytes,max_depth,max_array_len, trace hop enforcement) - Canonical JSON encoding and optional canonical CBOR
- Schema descriptors (embedded or URI) with hash verification
- Security primitives: Ed25519 signatures, X25519 + ChaCha20-Poly1305 encryption
- Replay protection backends: in-memory, SQLite, Redis
- Secure policy enforcement (
enc+sig+replay, key trust maps, key rotation/revocation/expiry) - OIDC JWT identity checks with JWKS verification (
sec.identity.jwt) - Multi-tenant policy controls (tenant allowlist + per-agent tenant mapping)
- Runtime compatibility and migration policy enforcement (
cap.a2a_sdl.v, deprecation/version ranges) - HTTP/WS/IPC transport parity with structured protocol errors
- Optional admin observability endpoints (
/healthz,/readyz,/metrics,/metrics.json) - Optional JSONL metrics exporter for external collectors
- Tamper-evident audit log with optional external hash anchoring
- Session-aware edge gateway mode (
a2a gateway) with mandatory replay + session binding enforcement - DAG workflow orchestrator mode (
a2a workflow) for multi-step A2A executions - Canonical interoperability vector generation (
a2a vectors)
Protocol Spec And Conformance
- Normative wire contract:
docs/protocol-v1.md - Conformance runner:
a2a conformance - Interop vector generator:
a2a vectors --out-dir docs/interop-vectors --verify - Test categories:
- Golden vectors (valid flows)
- Negative vectors (expected validation failures)
- Session/trustsync handler coverage (
session.v1,trustsync.v1) - Failure mapping checks (
UNSUPPORTED_CT,UNSUPPORTED_ENCODING, etc.) - Transport load checks (concurrent roundtrip)
Run full local conformance:
a2a conformance --transport all --mode all --format text
Run a targeted CI-style profile:
a2a conformance --transport http --mode secure --skip-load --format json
Compatibility Matrix (CI)
Conformance is enforced in CI across:
- Python:
3.11,3.12 - Transports:
http,ipc,ws - Modes:
dev,secure
Current matrix target:
| Python | HTTP dev | HTTP secure | IPC dev | IPC secure | WS dev | WS secure |
|---|---|---|---|---|---|---|
| 3.11 | yes | yes | yes | yes | yes | yes |
| 3.12 | yes | yes | yes | yes | yes | yes |
Install
Recommended (isolated CLI install with uv):
uv tool install --upgrade "a2acrpt[full]"
uv tool update-shell
Alternatives:
pipx install "a2acrpt[full]"
pip install "a2acrpt[full]"
Optional extras:
a2acrpt[cbor]a2acrpt[schema]a2acrpt[http]a2acrpt[ws]a2acrpt[redis]
Quick Start
This flow does not require a repository checkout.
- Start a local server:
a2a serve --host 127.0.0.1 --port 8080 --deployment-mode dev --allow-insecure-http
- Create a minimal valid
task.v1payload:
cat > task.json <<'JSON'
{
"kind": "task.v1",
"goal": "Return a short confirmation message",
"inputs": {},
"constraints": {
"time_budget_s": 30,
"compute_budget": "low",
"safety": {}
},
"deliverables": [
{"type": "text", "description": "One-line confirmation"}
],
"acceptance": ["Respond with a valid A2A envelope"],
"context": {}
}
JSON
- Send the request:
a2a send \
--url http://127.0.0.1:8080/a2a \
--ct task.v1 \
--payload-file task.json
Expected result: a response envelope (typically state.v1 or error.v1) printed as JSON.
Production Baseline
Minimum safe baseline before internet exposure:
- Use
--deployment-mode prod - Enforce TLS (and mTLS if required)
- Enforce
--secure-required - Use durable replay storage (
--replay-db-fileor--replay-redis-url) - Load trusted signing/decryption keys and agent authorization maps
- Protect admin endpoints with
--admin-token
Example hardened server profile:
a2a serve \
--host 0.0.0.0 --port 8443 \
--deployment-mode prod \
--secure-required \
--tls-cert-file /etc/a2a/tls/server.crt \
--tls-key-file /etc/a2a/tls/server.key \
--tls-ca-file /etc/a2a/tls/ca.crt \
--tls-require-client-cert \
--replay-redis-url redis://redis.internal:6379/0 \
--trusted-signing-keys-file trusted_signing_keys.json \
--decrypt-keys-file decrypt_keys.json \
--agent-kid-map-file agent_kid_map.json \
--admin-token '<strong-token>'
Sender-side HTTPS + mTLS:
a2a send \
--url https://a2a.example.com/a2a \
--ct task.v1 \
--payload-file task.json \
--tls-ca-file /etc/a2a/tls/ca.crt \
--tls-client-cert-file /etc/a2a/tls/client.crt \
--tls-client-key-file /etc/a2a/tls/client.key
Security and Trust Features
--secure-required: requires encrypted + signed + replay-protected inbound envelopes- Key lifecycle controls: required key per agent, rotation sets, revocation, key expiry
- OIDC identity enforcement:
--oidc-required --oidc-jwks-file ... - Tenant isolation controls:
--tenant-required --tenant-allow ... --agent-tenant-map-file ... - OIDC and tenant controls are layered on signed envelopes; configure trusted signing keys (
--trusted-signing-keys-fileor--key-registry-file) trustsync.v1: signed trust-registry discovery/proposal flowsession.v1: negotiated binding handshake with optional detached signature- Optional runtime migration policy:
--version-policy-file
Fine-grained tool authorization policy:
{
"allowed_tools_by_agent": {
"did:key:planner-a": ["math.add", "sys.ping"]
},
"required_scopes_by_tool": {
"math.add": "tool:math.add"
}
}
a2a serve --tool-policy-file tool_policy.json
Transport and Extensibility
- HTTP transport: reference implementation with retries/backoff and negotiation fallback
- WS transport: protocol-equivalent validation and error mapping
- IPC transport: local framed transport (
uint32_be) - Built-in handlers:
task.v1,toolcall.v1,negotiation.v1,trustsync.v1,session.v1 - Custom handlers:
--handler-spec <ct>=<module>:<callable>
Session-Aware Edge Gateway
a2a gateway runs an enforcement edge in front of upstream agents:
- Requires encrypted+signed+replay-protected inbound traffic
- Requires
sec.session.binding_idfor non-exempt content types - Handles
session.v1locally (establishes bindings), forwards data-plane requests upstream
Example:
a2a gateway \
--host 0.0.0.0 --port 9443 \
--upstream-url https://agent.internal/a2a \
--trusted-signing-keys-file trusted_signing_keys.json \
--decrypt-keys-file decrypt_keys.json \
--agent-kid-map-file agent_kid_map.json \
--tls-cert-file /etc/a2a/tls/gateway.crt \
--tls-key-file /etc/a2a/tls/gateway.key \
--replay-redis-url redis://redis.internal:6379/2
Workflow Orchestration
a2a workflow executes dependency-aware plans (DAG) over A2A HTTP endpoints with per-step retry/timeouts.
Minimal plan file:
{
"name": "incident-triage",
"steps": [
{
"id": "classify",
"ct": "task.v1",
"url": "http://127.0.0.1:8080/a2a",
"payload": {
"kind": "task.v1",
"goal": "Classify incident severity",
"inputs": {},
"constraints": {"time_budget_s": 20, "compute_budget": "low", "safety": {}},
"deliverables": [{"type": "text", "description": "severity"}],
"acceptance": ["Return severity"],
"context": {}
}
},
{
"id": "notify",
"depends_on": ["classify"],
"ct": "task.v1",
"url": "http://127.0.0.1:8080/a2a",
"payload": {
"kind": "task.v1",
"goal": "Prepare notification draft",
"inputs": {},
"constraints": {"time_budget_s": 20, "compute_budget": "low", "safety": {}},
"deliverables": [{"type": "text", "description": "message"}],
"acceptance": ["Return notification draft"],
"context": {}
}
}
]
}
Run:
a2a workflow --plan-file workflow.json --format text
Operations
- Observability endpoints:
/healthz,/readyz,/metrics - Machine-readable metrics endpoint:
/metrics.json - Periodic metrics snapshot export:
--metrics-export-file+--metrics-export-interval-s - Audit chain: append-only hash chain with optional Ed25519 receipts
- External audit anchoring:
--audit-anchor-url(+ optional fail-closed mode) - Operational checklist:
docs/operations-hardening.md
Interoperability Vectors
Generate canonical request/response vectors that other implementations can consume:
a2a vectors --out-dir docs/interop-vectors --verify
The generated artifacts include:
task.request.jsontask.response.jsonnegotiation.request.jsonnegotiation.response.json
Advanced
- Multi-buddy Codex swarm orchestration is available via
a2a swarmfor iterative protocol work. - Versioning policy details:
docs/versioning-policy.md
Test
python3 -m unittest discover -s tests -v
a2a conformance --transport all --mode all --format text
Release (Maintainers)
Trusted publishing is configured through GitHub Actions (publish-pypi.yml) to PyPI project a2acrpt.
Release flow:
- Bump version in
pyproject.toml - Merge to
main - Tag and push (for example
v0.2.1)
git tag v0.2.1
git push origin v0.2.1
Security Reporting
For potential vulnerabilities, use a private disclosure path (GitHub Security Advisory / private report) instead of a public issue.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file a2acrpt-0.2.1.tar.gz.
File metadata
- Download URL: a2acrpt-0.2.1.tar.gz
- Upload date:
- Size: 97.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69655659849b0c4b435e71712022fd0423d41946cbcecc999a37358bab37dc66
|
|
| MD5 |
1c9e3e4b03157c6a0825a1839a4fd8b2
|
|
| BLAKE2b-256 |
fd353b8215b14c9e4e8faf71272744baf7c808078b4f78b61483111dfbc56370
|
Provenance
The following attestation bundles were made for a2acrpt-0.2.1.tar.gz:
Publisher:
publish-pypi.yml on psspssr/crpt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
a2acrpt-0.2.1.tar.gz -
Subject digest:
69655659849b0c4b435e71712022fd0423d41946cbcecc999a37358bab37dc66 - Sigstore transparency entry: 957360026
- Sigstore integration time:
-
Permalink:
psspssr/crpt@bd3822365a0b49cd11bf41f7a13ab66796a2c3fe -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/psspssr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@bd3822365a0b49cd11bf41f7a13ab66796a2c3fe -
Trigger Event:
push
-
Statement type:
File details
Details for the file a2acrpt-0.2.1-py3-none-any.whl.
File metadata
- Download URL: a2acrpt-0.2.1-py3-none-any.whl
- Upload date:
- Size: 82.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ee469567123f41c0e8d57d4fded800b4e32baab11ff59a33cbaf7f60a73bbbd
|
|
| MD5 |
0013db93cd5df95c94a1a40f7961006e
|
|
| BLAKE2b-256 |
a11ab366dd1751edb62267caa8cd752bc11cc3971cd70ad05d837e4ea5690969
|
Provenance
The following attestation bundles were made for a2acrpt-0.2.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on psspssr/crpt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
a2acrpt-0.2.1-py3-none-any.whl -
Subject digest:
7ee469567123f41c0e8d57d4fded800b4e32baab11ff59a33cbaf7f60a73bbbd - Sigstore transparency entry: 957360038
- Sigstore integration time:
-
Permalink:
psspssr/crpt@bd3822365a0b49cd11bf41f7a13ab66796a2c3fe -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/psspssr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@bd3822365a0b49cd11bf41f7a13ab66796a2c3fe -
Trigger Event:
push
-
Statement type: