Interop Testing¶
A runbook for checking that an AAuth agent, resource or person server works against the others, for people and for AI agents running the steps for them. The servers come from the AAuth sandbox in aauth-go; its sandbox guide is the reference for every option used here.
Pick What You Are Testing¶
| You are testing | Start the sandbox with | Then |
|---|---|---|
| An agent (a client of your own) | the Compose file in this repository | enroll at https://ap.aauth.test/enroll, call the Petstore or https://resource.aauth.test |
| A resource (a server of your own) | --upstream name=http://your-server, see Front your own server |
run the collection or an agent against https://name.aauth.test |
| A person server, agent provider or access server | --remote ps=https://your-server, see Test another implementation |
run the collection; the sandbox's other roles call yours |
The two reference agents are this repository's Postman collections (one request per step, so you can read each message) and omniagent (an AI agent that signs requests itself; see its AAuth guide).
Run the Reference Setup¶
docker compose up -d --build --wait # part 1: the sandbox
docker compose --profile test run --rm newman # 21 requests, 98 assertions
docker compose --profile petstore up -d --build --wait # part 2: adds the Petstore
docker compose --profile petstore run --rm newman-petstore # 10 requests, 47 assertions
Part 1 needs only an aauth-go checkout. Part 2 also needs a petstore checkout; skip it to test with the sandbox's own resources.
A passing run reports 0 failed. This is the baseline: if it fails, fix the setup before testing anything of your own.
Two checks that the baseline is healthy:
docker compose --profile petstore ps # sandbox and petstore: healthy
docker compose exec sandbox aauth-sandbox trace --state /state | head # the message trace
Test an Agent of Your Own¶
Inside the Compose network, the roles answer at their names, so an agent container needs no hosts entries. Run it on the same network and trust the sandbox CA from the shared state volume (/state/ca.pem):
- Enroll at the agent provider:
POST https://ap.aauth.test/enrollwith your public key. The response is an agent token. - Call
https://petstore.aauth.test/v2/pet/findByStatus?status=available, signed (RFC 9421) withSignature-Keycarrying the agent token. Expect 200. - Call
POST https://petstore.aauth.test/v2/store/order. Expect 401 withAAuth-Requirement: requirement=person-token, then, after you obtain a person token, 401 withrequirement=auth-tokenand a resource token. - Send the resource token to
https://ps.aauth.test/token. Expect 202 with aLocationand an interaction code while the person approves, then 200 with the auth token. The sandbox approves on its own unless started with--consent manual. - Repeat the order with the auth token. Expect 200.
The trace shows each message, so compare yours with the Postman run, step by step.
Test with an AI Agent¶
omniagent is a ready-made agent for this:
ANTHROPIC_API_KEY=... docker compose --profile omniagent run --rm -T omniagent \
--prompt "Call the place-order tool now with petId 2 and quantity 1. I have already confirmed; do not ask."
Expect Enrolled as aauth:[email protected], then Approval needed. Open … and the order result. Notes for agents running this:
- Check pet ids first:
GET /v2/pet/findByStatus?status=available. A sold pet is gone until the Petstore restarts; recreate the sandbox with it (docker compose --profile petstore up -d --wait --force-recreate sandbox petstore), see Troubleshooting. - The model decides what to call. If it asks for confirmation or searches by a tag that matches nothing, state the tool and arguments, as above. That is the model, not AAuth.
- Judge success from the trace, not from the model's wording: the order request shows 200 and the person-server
/tokenexchange shows 202 then 200.
See a Run in the Walkthrough¶
make demo (Newman) or make demo-omniagent (omniagent) runs the Petstore order flow and writes demo/live.html, the AAuth walkthrough with the run's messages beside each step. It is the quickest way to compare your agent's messages with the protocol's: recreate the sandbox and the Petstore, run your agent against them, then turn the sandbox's trace into the page:
docker compose --profile petstore up -d --wait --force-recreate sandbox petstore
# ...run your agent...
make demo-page
A step marked "Not seen" is one your run did not perform; an exchange marked "Not a step in the document" is one it made that the protocol does not describe. "Weak match" means only the participants and method agreed. A match means the message looked like the step, not that it was valid.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
bind: address already in use on 8099 or 443 |
Another program uses the host port | SIGNER_PORT=18099 SANDBOX_HTTPS_PORT=18443 docker compose up -d --wait; containers are unaffected |
connection refused to ap.aauth.test:443 from a container |
The sandbox listens on loopback only (an overriding command without --listen-any-interface) |
Use this repository's compose.yaml, or add --listen 0.0.0.0:443 --listen-any-interface |
421 Misdirected Request from the signing helper |
The helper answers only loopback names | Add --signer-host <service-name> for the name your client uses |
x509: certificate signed by unknown authority |
The client does not trust the sandbox CA | Point it at /state/ca.pem, or export it with aauth-sandbox ca export |
| Order fails after a previous run | The pet was sold | Recreate the sandbox and the Petstore together: docker compose --profile petstore up -d --wait --force-recreate sandbox petstore |
invalid_resource_token ("no key … in JWKS of https://petstore.aauth.test") after restarting the Petstore |
The Petstore creates a new signing key at each start, and the person server keeps the key it saw | Recreate the sandbox together with the Petstore, as above |
| Old CA after rebuilding | The state volume held a CA from an older sandbox | docker compose down -v, then start again, and trust the new CA |