Sandbox
Get an agent identity, end to end
Five calls: register an agent, exchange its key for a short-lived certificate, confirm the certificate is still good, then revoke it and watch it disappear from the list. No account, no signup — the sandbox is open, and every call below is one you can paste into a terminal right now.
Nothing here is a real identity. The sandbox signs with a throwaway CA generated in memory at startup, so certificates stop verifying when it restarts and every key and report is forgotten at the same moment. Production issuance is a different key entirely, on register.trustatria.com, and needs an account.
- 1
Pin the sandbox CA
Everything the sandbox signs chains to this certificate. A proxy pins it once and then trusts nothing else — which is why a certificate from any other issuer is refused at the handshake rather than at the policy check.
requestcurl -s https://sandbox.trustatria.com/ca -o sandbox-ca.pemsandbox-ca.pem-----BEGIN CERTIFICATE----- MIIBkTCCATegAwIBAgIUJ8k... -----END CERTIFICATE-----Regenerated whenever the sandbox restarts. Pin it again after one, or certificates minted since will not verify against your copy.
Try GET /ca in the console - 2
Register the agent
Open — no credential, because this is the call an agent makes before it has one. The API key comes back exactly once; the sandbox keeps only a hash of it.
Try POST /register in the consolerequestcurl -s -X POST https://sandbox.trustatria.com/register \ -H 'content-type: application/json' \ -d '{"agent_id": "demo-bot"}'response{ "agent_id": "demo-bot", "key_id": "cb2142b586c8854f", "api_key": "atria_cb2142b586c8854f_fe6fafa42987...45f452" } - 3
Exchange the key for a certificate
The one call in this walkthrough that takes a credential. Send a PEM certificate signing request to keep the private key yours — that is what a real agent does. Omit it and the sandbox generates the key pair for you, a demo convenience and nothing to copy into production.
requestcurl -s -X POST https://sandbox.trustatria.com/session \ -H "authorization: Bearer $API_KEY" \ -H 'content-type: application/json' \ -d '{"ttl_seconds": 900}'response{ "agent_id": "demo-bot", "serial": "67037dbca6524bed12ce984b80343588", "certificate_pem": "-----BEGIN CERTIFICATE-----\n...", "private_key_pem": "-----BEGIN PRIVATE KEY-----\n...", "not_after": "2026-08-24T01:19:14.494811942Z" }Unknown key, deactivated key and malformed key all answer the same 401 INVALID_API_KEY — the endpoint must not sort guessed key ids into real and not-real.
Try POST /session in the console - 4
Check the certificate is still good
Holding a certificate is only half of an identity. The other half is that it has not been revoked since it was issued, which is what the signed revocation list answers. A proxy pulls this on a schedule and re-checks it on every request — not once at the handshake, because a long-lived connection must not keep working on a certificate that has since been withdrawn.
Try GET /crl in the consolerequestcurl -s https://sandbox.trustatria.com/crl -o sandbox.crl openssl crl -inform DER -in sandbox.crl -noout -text | head -20responseCertificate Revocation List (CRL): Version 2 (0x1) Signature Algorithm: ecdsa-with-SHA256 Issuer: CN = Atria CA, O = Trust Atria Last Update: Aug 24 01:04:02 2026 GMT Next Update: Aug 24 02:04:02 2026 GMT CRL extensions: X509v3 CRL Number: 1 No Revoked Certificates. - 5
Revoke it, and watch the list change
The sandbox exposes the operator side too, so you can see the other end of the loop. This deactivates the agent’s API keys, revokes its outstanding certificates and republishes the list under the next number in one call.
requestcurl -s -X POST https://sandbox.trustatria.com/admin/revoke \ -H 'content-type: application/json' \ -d '{"agent_id": "demo-bot", "reason": "key_compromise"}' curl -s https://sandbox.trustatria.com/crl -o sandbox.crl # now lists serial 67037dbc...response{ "agent_id": "demo-bot", "certificates_revoked": 1, "api_keys_deactivated": 1, "crl_number": 2 }The certificate from step 3 is now refused everywhere that pulls this list, before its own expiry — and its API key can no longer mint a replacement.
Try POST /admin/revoke in the console
The other half
Enforcement, and where it runs
The five steps above get an agent an identity. Enforcement is the other half, and it is not something a sandbox can show you from a browser: the agent has to present its certificate over mTLS, so the proxy has to run somewhere that can terminate TLS with a client certificate.
If you are deploying it in front of a real backend, that is apt install atria-proxy — five steps on a Debian or Ubuntu host, nothing to compile.
To watch the whole flow on your own machine instead — allowed call, denied call, audit log, all of it — run the stack from source: four processes and a demo agent.
cargo build --workspace
atria-ca server-cert --out-dir ./tls # a development server identity
mock-cloud & # the cloud, same code as the sandbox
mock-target & # the customer's backend
curl -s http://127.0.0.1:8443/ca -o ca.pem
ATRIA_CA_CERT=./ca.pem \
ATRIA_TLS_CERT=./tls/server-cert.pem ATRIA_TLS_KEY=./tls/server-key.pem \
ATRIA_POLICY_FILE=./policies.yaml \
ATRIA_CRL_URL=http://127.0.0.1:8443/crl \
ATRIA_ADMIN_ADDR=127.0.0.1:8081 \
atria-proxy &
ATRIA_ADMIN_URL=http://127.0.0.1:8081 \
demo-client --server-ca ./tls/server-ca.pemThe demo agent then makes the two calls worth seeing: one the policy allows, which reaches the backend, and one it does not, which comes back 403 with a reason code and nothing else — which rule matched goes to the audit log, never to the caller.