anonrouterdocs
SDKs

anonrouter-verify

The command both SDK packages install. It prints one JSON document and exits nonzero unless the assurance you asked for was established, so it can gate a deploy rather than only inform one.

Get it from the GitHub release

anonrouter-verify comes with either SDK package, and neither package is on npm or PyPI yet. Install the tarball or wheel from v0.1.0 — see the SDK overview — and the command lands on your PATH.

Installing either SDK package installs anonrouter-verify. It answers one question from a terminal — did this route establish the assurance I require? — and answers it with an exit code, so it can gate a deploy or a CI job rather than only inform one.

Both languages ship the same command. A cross-language parity gate runs both real executables over the same inputs and requires the JSON they print and the codes they exit with to be identical, so it does not matter which one you have.

Three subcommands

# Hop 1 only: is this data plane the reviewed build, in a TDX CVM, bound to a
# fresh nonce and this origin? Credential-free.
anonrouter-verify gateway --origin https://api.anonrouter.ai

# Both hops, cross-bound to a route. Needs an API key for hop 2.
anonrouter-verify route --origin https://api.anonrouter.ai \
  --control-origin https://control.anonrouter.ai \
  --provider venice --model venice-uncensored

# What can this machine establish at all? Contacts nothing unless --origin is given.
anonrouter-verify doctor --origin https://api.anonrouter.ai

`gateway` needs no credential

Hop 1 is credential-free by design: a client should be able to verify the plane before it trusts that endpoint with anything. You can run it against a deployment you have no account on.

Exit codes

CodeMeaning
0the requested assurance was established
1it was not — including "we could not look"
2the command or its inputs were wrong

That third code exists so a typo cannot be mistaken for a verification failure, and the second covers unavailable as well as untrusted: a deployment that does not expose attestation has not passed anything.

anonrouter-verify gateway --origin https://api.anonrouter.ai --dcap \
  --require hardware_verified
echo $?   # 0 met, 1 not met, 2 the command itself was wrong

Gating a deploy

--require sets the minimum state that exits 0. The default is cryptographically_checked.

#!/usr/bin/env bash
set -euo pipefail

anonrouter-verify gateway \
  --origin https://api.anonrouter.ai \
  --dcap --require hardware_verified --compact

echo "plane established; proceeding with deploy"

With set -e, a plane that stopped matching the reviewed pin stops the deploy. See the five states for what each level of --require actually proves.

Reaching hardware_verified

--dcap chains the quote's signature to Intel's roots using the reviewed engine. It is required to reach hardware_verified; without it the honest ceiling is cryptographically_checked, and the command refuses --require hardware_verified rather than quietly returning a weaker result.

anonrouter-verify doctor            # is an engine installed? which one? what digest?

doctor reports what this machine can establish — the engine, its digest, the host target, and whether a pin ships for the origin — before you depend on it in CI.

FlagWhat it is for
--dcapchain the quote to Intel's roots with the reviewed engine
--dcap-binary <path>use this engine explicitly instead of discovering one
--dcap-sha256 <hex>refuse to run an engine whose SHA-256 differs
--collateral <file>supply Intel collateral instead of fetching it
--no-collateral-fetchrefuse to fetch collateral (needs --collateral)

Pinning the policy yourself

Without --policy, the command holds the plane to the pin the package ships for that origin. Supply your own to pin a release you reviewed yourself, or to verify a plane the package ships no pin for.

anonrouter-verify gateway --origin https://your-cvm.example \
  --policy ./reviewed-policy.json --dcap --require hardware_verified

--allow-candidate accepts a shipped pin whose status is candidate — a reviewed but pre-release plane whose measurements are expected to move. It is off by default, so a default invocation can never quietly pass against a plane the operator has not released.

`v0.1.0`'s shipped pin is older than the running plane

The content plane has been released since v0.1.0 was tagged, so the pin the package ships names the previous build. Against production today that means exit 1 on compose_hash_pinned and release_pinned — a stale pin failing closed, which is the behaviour you want, but not a passing gate. Until a refreshed pin ships, supply --policy with a policy you reviewed against the compose_hash and release_id in the live /v1/gateway/attestation document.

Credentials and output

  • The API key for route is read only from an environment variable, never from argv, where it would be visible in the process table. Change which variable with --api-key-env.
  • The command prints one JSON document on stdout (--compact for one line) and diagnostics on stderr, so a caller can branch on the exit code and still read why.
  • It never prints a key, a ticket, request content, or the raw evidence body. The gateway document alone is tens of kilobytes of internal build detail; the command reports a verdict over it rather than dumping it.
anonrouter-verify gateway --origin https://api.anonrouter.ai --compact \
  | jq '{schema, state: .gateway.state, reason: .gateway.reason}'

Every document carries a schema field (anonrouter-verify/1), so a consumer can detect a format change rather than silently misparse one.

Full options

anonrouter-verify --help
OptionDefault
--origin <url>required for gateway / route
--control-origin <url>--origin; production uses https://control.anonrouter.ai
--require <state>cryptographically_checked
--api-key-env <NAME>ANONROUTER_API_KEY
--timeout <ms>30000
--no-tls-checkoff — TLS observation is on by default
--compactoff

`--control-origin` does not split verification from content

It only moves the content-free, API-key operations to the identity origin. Both attestation hops and any request content stay on --origin. The SDK deliberately offers no way to verify one inference origin while sending content to another — a verdict about a plane that did not carry your prompt proves nothing about the one that did.

On this page