Skip to main content
Change of provenance

The repository or configuration that created this release differ from a previous release. View details.

aae — Python SDK

Reference implementation of the AAE protocol in Python.

Status

End-to-end working. The lifecycle orchestrator walks PROPOSE → PREVIEW → APPROVE → COMMIT → AUDIT with pluggable adapters for policy, audit, approvals, and capability tokens. All 27 conformance tests pass.

This is the canonical reference SDK. When the spec is ambiguous, this implementation's behavior is the answer; clarifications then propagate back into docs/v0.2-clarifications.md.

Install

pip install -e .

Dependencies: pydantic, pyjwt[crypto], python-ulid, rfc8785, jsonschema, PyYAML, cryptography.

60-second example

import asyncio
from datetime import datetime, timezone
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from ulid import ULID

from aae import (
    BlastRadius, Context, Decision, Effect, LifecycleClient,
    Proposal, Step, StepPreview,
)
from aae.approvals import AutoGrantApproval
from aae.audit import InMemoryAuditSink
from aae.policy import AllowAllPolicy
from aae.tokens import JwtSigner
from aae.tools import InMemoryToolRegistry, StepResult, Tool


# 1. Define a tool: preview predicts effects, commit executes.
async def echo_preview(step):
    return StepPreview(
        step_index=0,
        predicted_effects=[Effect(type="read_only", target="echo")],
        warnings=[],
    )


async def echo_commit(step, token):
    return StepResult(
        success=True,
        outputs={"echoed": step.args.get("message", "")},
    )


registry = InMemoryToolRegistry()
registry.register(Tool(
    name="echo",
    plan_schema={
        "type": "object",
        "properties": {"message": {"type": "string"}},
        "additionalProperties": False,
    },
    preview_fn=echo_preview,
    commit_fn=echo_commit,
    default_blast_radius=BlastRadius.READ_ONLY,
))

# 2. Build the JWT signer.
priv = Ed25519PrivateKey.generate()
priv_pem = priv.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)
pub_pem = priv.public_key().public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
signer = JwtSigner(
    active_kid="key-1",
    active_private_key=priv_pem,
    trusted_public_keys={"key-1": pub_pem},
    issuer="my-host",
)

# 3. Wire the lifecycle.
client = LifecycleClient(
    registry=registry,
    policy=AllowAllPolicy(),               # for production: OPA/Cerbos/YamlAllowlistPolicy
    audit=InMemoryAuditSink(),             # for production: JsonlAuditSink or your own
    approvals=AutoGrantApproval(),         # for production: CliApproval or your own delivery
    tokens=signer,
    issuer="my-host",
)

# 4. Submit a proposal.
proposal = Proposal(
    proposal_id=str(ULID()),
    agent_id="my-agent",
    tenant_id="my-tenant",
    intent="say_hello",
    context=Context(rationale="Demo"),
    steps=[
        Step(tool="echo", args={"message": "hi"},
             blast_radius=BlastRadius.READ_ONLY),
    ],
    submitted_at=datetime.now(timezone.utc),
)

result = asyncio.run(client.execute(proposal))
print(result.decision)               # Decision.ALLOW
print(result.step_results[0].outputs)  # {'echoed': 'hi'}
print(result.audit_chain_tip)        # sha256:...

Adapters shipped

Adapter Production-ready Use case
aae.policy.AllowAllPolicy ❌ tests/dev only Smoke tests
aae.policy.DenyAllPolicy ❌ tests/dev only Failsafe baseline
aae.policy.YamlAllowlistPolicy ⚠️ personal/dev Single-user, file-based rules
aae.audit.InMemoryAuditSink ❌ tests/dev only Unit tests
aae.audit.JsonlAuditSink ✅ single-host Persistent local log
aae.audit.CompositeAuditSink ✅ Defense in depth (replicate to multiple sinks)
aae.approvals.AutoGrantApproval ❌ tests/dev only Pipeline tests
aae.approvals.AutoDenyApproval ❌ tests/dev only Failsafe tests
aae.approvals.CliApproval ⚠️ interactive only Personal tools, demos
aae.tokens.JwtSigner ✅ EdDSA / ES256 / RS256 capability tokens

For production:

  • Policy: implement aae.policy.PolicyAdapter over your engine of choice (OPA, Cerbos, custom HTTP service).
  • Audit: implement aae.audit.AuditSink over your durable store (Postgres, S3 with object lock, append-only DynamoDB tables).
  • Approvals: implement aae.approvals.ApprovalDelivery over your notification + decision-collection surface (Slack app, web UI, mobile push).

The Protocol types are designed so a custom adapter is typically 50-150 lines.

Design notes

What LifecycleClient enforces

  1. Phases happen in order. The lifecycle never advances without the prior phase emitting its audit event.
  2. Audit events for a phase transition are persisted before the next phase begins. An interrupted lifecycle leaves a partial-but-verifiable chain.
  3. Capability tokens bind to the SHA-256 of canonical approved-steps bytes. The commit phase re-verifies this hash before executing.
  4. Approval grants trigger a re-evaluation of policy. A grant is not automatically an allow; policy may have changed during the wait.
  5. On any failure, the corresponding *_failed or *_aborted event is appended before the exception propagates.

What it does NOT do

  • Multitenant routing, agent authentication, approval persistence across host restarts — those are the host application's responsibility.
  • Rate limiting, replay protection, network calls — those are the policy engine's or gateway's responsibility.
  • Long-running plan deviation — use re-proposal (submit a new proposal with context.derived_from).

Future-ready seams

  • Algorithm-agility: hashes carry their algorithm in the value (sha256:...). v1.x can introduce BLAKE3 or post-quantum hashes without breaking historical chains. See aae.algorithms.
  • Extension fields: payloads accept any keys not collision-prone with current/future standardized names. Convention: prefix host-specific fields with ext..
  • Federated audit: AuditSink.append will return an optional witness URL in v0.3 for external chain-head publication.
  • Multi-agent: agent_id on proposals will become an optional agent_chain[] for proposals submitted on behalf of other agents.
  • Cost-aware policy: ext.cost_estimate shape in step previews is reserved for v0.3.

Testing

cd sdks/python
PYTHONPATH=src python -m pytest tests/
PYTHONPATH=src python -m aae.conformance   # cross-implementation conformance

The aae-conformance console script runs after pip install -e ..

Versioning

This SDK targets AAE protocol v0.2. The protocol version is exposed as aae.__protocol_version__. The SDK's own version is aae.__version__.

License

Dual MIT / Apache-2.0. See repo root.

Metadata

Release files for aae-protocol 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Change of provenance

The repository or configuration that created these release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Source distribution (sdist)

Source distribution for aae-protocol 0.9.0
File Size Uploaded Provenance
aae_protocol-0.9.0.tar.gz 115.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for aae-protocol 0.9.0
File Interpreter ABI Platform
aae_protocol-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 219.8 kB

Release files / aae_protocol-0.9.0.tar.gz

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL aae_protocol-0.9.0.tar.gz
Size 115.9 kB
Tags Source
SHA-256 checksum
How to use checksums
07c4deb7aaced9efdccf11c283ac25b8643330a99d3577562f2f7d668b114871
BLAKE2b-256 checksum
How to use checksums
4c73cf36d004e445c256f0cb5ed3f84856824764433b53c844522db85fbf4fb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

Release files / aae_protocol-0.9.0-py3-none-any.whl

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL aae_protocol-0.9.0-py3-none-any.whl
Size 103.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eca4b38597604c62f0b00881d1afe936b0af69b760178556fe8ab6cc8fab7350
BLAKE2b-256 checksum
How to use checksums
31ad1ecc852d04cebeaa959da4afeb78fac53645f99870601d821c1a16621fee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

Security for aae-protocol 0.9.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Change of provenance

The configuration that created this release differs from a previous release.

While this could reflect a routine change by the project maintainers, it may also indicate that the release files have been compromised.

Configuration

  • Removed 0.0.1 reserve-names.yml
  • Added 0.9.0 publish-python.yml
Select from 2 files

Attestation for aae_protocol-0.9.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files Change of provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page