Skip to main content

aac-invoke-auth

Authenticate /invoke pushes from your paired AAC sidecar.

When your agent runs behind an AAC sidecar, the sidecar verifies the cross-organizational authority chain and then POSTs the verified context to your agent's /invoke endpoint. The X-AAC-* headers on that push are your agent's entire view of the verified chain — so your agent must be able to tell a genuine sidecar push from a forged one. This package is that check: the sidecar HMAC-signs every push with a pairing secret shared with exactly one agent, and your agent verifies the signature before trusting anything.

The verification core is standard-library only (hmac, hashlib) and framework-agnostic. FastAPI mounting surfaces ship behind an extra:

pip install aac-invoke-auth[fastapi]

Quick start (FastAPI)

Generate the pairing secret once and share the file with your sidecar (the sidecar's sidecar.agent_invoke_auth.secret_file points at the same file; one secret per sidecar–agent pair, never shared across pairs):

openssl rand -hex 32 > /etc/aac/invoke-auth/invoke-auth.secret

Point your agent at it and mount the middleware:

export AAC_INVOKE_AUTH_SECRET_FILE=/etc/aac/invoke-auth/invoke-auth.secret
from fastapi import FastAPI
from aac_invoke_auth.fastapi import InvokeAuthGuard, InvokeAuthMiddleware

app = FastAPI()
app.add_middleware(
    InvokeAuthMiddleware,
    guard=InvokeAuthGuard.from_env(),
    protected_paths=("/invoke",),   # required, exact-match
)

That's the whole integration. Unsigned, tampered, replayed-stale, or wrong-secret pushes get a 401 with a generic detail and never reach your business logic; your handlers read request.json() unchanged.

Prefer route-scoped protection? The guard is also a plain FastAPI dependency:

from fastapi import Depends

guard = InvokeAuthGuard.from_env()

@app.post("/invoke", dependencies=[Depends(guard)])
async def invoke(request: Request): ...

Both surfaces call the same verifier — pick whichever fits your app.

Fail-fast startup, by design

InvokeAuthGuard.from_env() refuses to start when AAC_INVOKE_AUTH_SECRET_FILE is unset. A missing secret is a security downgrade; it should fail your deployment loudly at boot, not degrade into a log line nobody reads.

The single escape hatch — for extraordinary cases only, such as tenant test/pilot environments or debugging a suspected signing mismatch — is setting

export AAC_INVOKE_AUTH_ALLOW_UNAUTHENTICATED=true

explicitly (only the exact value true; a typo still fails the boot). An opted-out agent accepts every push unverified and logs a prominent warning at startup so the posture is visible in your logs. Never run this in production: the sidecar side has a symmetric dev_mode interlock, and both exist to make "unauthenticated" impossible to reach by accident.

Testing your agent

aac_invoke_auth.testing ships with the package:

from aac_invoke_auth.testing import signing_test_client

client = signing_test_client(app)          # wraps FastAPI's TestClient
response = client.post("/invoke", headers=aac_headers, json=payload)

post() calls to protected paths are signed exactly the way the paired sidecar signs them (secret read from AAC_INVOKE_AUTH_SECRET_FILE); everything else passes through. So your test suite exercises the real production verification path instead of opting out of it.

Wire format

AAC1-HMAC-SHA256 over method, path, timestamp, a SHA-256 body digest, and every X-AAC-* header (derived by rule, so header insertion/removal after signing fails verification). Freshness window ±30s. The normative canonicalization text lives in the AAC Engineering Specification §III.2.4a; frozen known-answer vectors live in this package's test suite — a change that breaks a vector is a wire-format break, not a refactor.

Ports of this middleware for other stacks (Express, Spring, Go net/http) follow the same model; the core stays standard-library-only in every language precisely to keep those ports mechanical.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aac_invoke_auth-0.1.1.tar.gz (27.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aac_invoke_auth-0.1.1-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file aac_invoke_auth-0.1.1.tar.gz.

File metadata

  • Download URL: aac_invoke_auth-0.1.1.tar.gz
  • Upload date:
  • Size: 27.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for aac_invoke_auth-0.1.1.tar.gz
Algorithm Hash digest
SHA256 80a007197e4b0af4ae292be20017c915a933aa89cd8343573baaaed010c5f16b
MD5 d53d2d951075944c5a795ba2518d3bbe
BLAKE2b-256 6b226cc0b733bb28e1e32cec364fdf790e211a817ddfb672dade6c7a121727ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for aac_invoke_auth-0.1.1.tar.gz:

Publisher: release-invoke-auth.yml on CascadeAuth/aac-prototype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aac_invoke_auth-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for aac_invoke_auth-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a92a520ef6b3e3fab009ec524291c600f6fcf23f9d3d8ddef7e98afce233d925
MD5 d0560dcf63fff7baa5bfef8799ef81d3
BLAKE2b-256 41c6d90d80132edd4bef17ed1db56c8019d2444c9fe824b17b0177470dc79cfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for aac_invoke_auth-0.1.1-py3-none-any.whl:

Publisher: release-invoke-auth.yml on CascadeAuth/aac-prototype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

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