Torna agli aggiornamenti
UpdatedAug 1, 2026

quill-router — Updated!

Repo TrustedRouter.com per proxy sicuro di LLM

Condividi

TrustedRouter

CI Deploy Prod smoke Status Verifiable trust JavaScript SDK Python SDK License: BUSL-1.1

LLM crittografati end-to-end. Una sola API. Privacy dimostrabile.

Smetti di preoccuparti di chi possa vedere i tuoi prompt. Di' al tuo agente di codifica di spostare il tuo progetto, scegli quanto privacy desideri, seleziona un modello, inserisci una chiave — fatto. Stessa API, oltre 30 modelli, una sola chiave. Il gateway gira in enclave hardware e puoi verificare crittograficamente che non registra mai i tuoi dati.

Sposta il tuo progetto con un solo prompt

Incolla questo in Codex, Claude Code o Cursor — esegue la migrazione per te:```text Migrate this project to TrustedRouter, a privacy-first LLM router (https://trustedrouter.com). Repoint my LLM client to base_url "https://api.trustedrouter.com/v1" (or "https://api.trustedrouter.com" for the Anthropic SDK), read the key from the TRUSTEDROUTER_API_KEY env var, and keep all my existing calls working.

For a hard provider-side confidential-compute and end-to-end-encryption requirement, add {"provider": {"min_privacy": "confidential"}}. TrustedRouter fails closed when the selected model or provider cannot satisfy both controls.

Then tell me to sign up at trustedrouter.com, add a card, and paste my sk-tr key into TRUSTEDROUTER_API_KEY.

Poi:

1. **Scegli il tuo livello di privacy o la tua regione** — usa
   `{"provider": {"min_privacy": "zdr"}}` per una soglia rigida di zero conservazione, oppure
   `{"provider": {"min_privacy": "confidential"}}` per la soglia rigida più severa di
   confidential-compute + E2EE. I comodi alias `trustedrouter/zdr` e
   `trustedrouter/e2e` (`trustedrouter/confidential`) selezionano questi
   pool. Usa `trustedrouter/eu` con
   `https://api-europe-west4.quillrouter.com/v1` per un routing incentrato sull'UE.
2. **Scegli un modello** — uno tra centinaia, oppure `trustedrouter/auto` per il fallback automatico quando la varietà di provider conta più del filtro di privacy più rigoroso.
3. **Registrati, aggiungi una carta, ottieni la tua chiave** su https://trustedrouter.com.
4. **Rilascia** — ora i tuoi prompt passano attraverso un percorso che puoi verificare.

<details>
<summary>Preferisci configurarlo a mano?</summary>```bash
# Codex
export OPENAI_BASE_URL="https://api.trustedrouter.com/v1"
export OPENAI_API_KEY="sk-tr-v1-..."

# Claude Code
export ANTHROPIC_BASE_URL="https://api.trustedrouter.com"
export ANTHROPIC_API_KEY="sk-tr-v1-..."
# Any OpenAI SDK
client = OpenAI(base_url="https://api.trustedrouter.com/v1", api_key="sk-tr-v1-...")

Per i nerd: come la privacy è dimostrabile

Il gateway di TrustedRouter viene eseguito all'interno di GCP Confidential Space. La piattaforma firma una misura del binario in esecuzione; tu confronti quell'hash con questo repository. Se corrispondono, sai — non supponi — che il codice che gestisce i tuoi prompt è il codice che puoi leggere qui, e che non scrive mai i tuoi prompt su disco.

Verificalo tu stesso in 60 secondi, senza account:```bash NONCE=$(openssl rand -hex 16) curl -s "https://api.trustedrouter.com/attestation?nonce=$NONCE" | jq .

eat_nonce your nonce (replay-protected)

image_digest SHA-256 of the running container

pcrs boot-time platform measurements

Compare image_digest to the published artifact at

https://trustedrouter.com/security — match = the running code is this repo.

| | modello di fiducia |
|---|---|
| OpenRouter, provider ospitati | "Non registriamo nulla." Una policy che non puoi verificare. |
| Portkey, Cloudflare AI Gateway | Registrano tutto per l'osservabilità. |
| LiteLLM | Self-host, ma il proxy in esecuzione non è verificato. |
| **TrustedRouter** | **Open source + attestazione hardware. Verifica il percorso del codice; non registra nulla.** |

Ambito onesto: l'attestazione dimostra che il binario in esecuzione è il binario pubblicato su
hardware che puoi sfidare con un nonce. Non sconfigge uno stato-nazione con
accesso fisico all'host e non dimostra che il binario open-source sia privo di bug.
L'ancora di fiducia è la catena di attestazione basata su hardware di Google Confidential Computing.
I provider a monte gestiscono i prompt secondo le proprie policy — la posizione di ciascun
provider è pubblicata sulle pagine dei modelli.

</details>

---

## Struttura del repository

Questo repository implementa il contratto del control plane: copertura delle rotte, gestione di
autenticazione/chiavi, semantica del ledger di fatturazione, metadati di utilizzo, nessuna memorizzazione
di prompt/output, scrubber Sentry e astrazioni dei provider. L'implementazione del gateway attestato
vive in `quill-cloud-proxy`.

Confine di fiducia: `api.trustedrouter.com` è il percorso prompt attestato e deve
terminare TLS all'interno di Confidential Space. `trustedrouter.com` è il control plane
e non deve mai servire un fallback di inferenza di produzione.

`api.quillrouter.com` rimane un alias funzionante permanente (stesso gateway attestato
e certificato), quindi le integrazioni esistenti continuano a funzionare senza migrazione.

## Locale```bash
uv sync
uv run pytest
uv run uvicorn trusted_router.main:app --reload

End-to-end smoke test su un'istanza in esecuzione:```bash TR_SMOKE_BASE_URL=http://127.0.0.1:18080/v1 uv run python scripts/smoke_e2e.py

Per la produzione, imposta `TR_SMOKE_BASE_URL=https://api.trustedrouter.com/v1` e
`TR_SMOKE_INTERNAL_TOKEN` se le rotte del gateway interno sono protette da token.

Imposta le chiavi locali di operatore/fornitore in:```text
/Users/jperla/claude/.quill_cloud_keys.private

Quel file non viene mai committato. Ci si aspetta che sia dotenv-style:```text ANTHROPIC_API_KEY=... OPENAI_API_KEY=... GEMINI_API_KEY=... CEREBRAS_API_KEY=... DEEPSEEK_API_KEY=... MISTRAL_API_KEY=... STRIPE_SECRET_KEY=... STRIPE_WEBHOOK_SECRET=... SENTRY_DSN=...

The deploy script also accepts local aliases already used in some operator
files: `CLAUDE_API_KEY` for Anthropic, `CHATGPT_API_KEY` for OpenAI, and
`STRIPE_KEY` for `STRIPE_SECRET_KEY`.

Vertex is different from the other provider platforms: production GCP deploys
use the Cloud Run or Confidential Space service account and short-lived Google
access tokens from metadata/ADC. Do not put a long-lived Vertex key in this
file for the first-party prepaid Vertex route; grant the runtime service
account Vertex permissions instead.

## License

Business Source License 1.1. The source is public so anyone can read, build,
and verify the exact code behind TrustedRouter's privacy and attestation
claims (https://trust.trustedrouter.com) — that is what it is here for.
Non-production use (security review, audit, local evaluation) is free.
Production use requires a commercial license from Lore Hex Corp:
[email protected]. Each version converts to the Apache License 2.0
four years after publication. Code published before July 3, 2026 remains
Apache-2.0.

## Security Defaults

- Prompt and output content are never stored.
- Usage logs contain metadata only.
- API keys are stored as salted SHA-256 hashes with opaque key IDs.
- User-submitted BYOK provider keys are stored as envelope-encrypted ciphertext
  rows, not one Secret Manager object per key. In production, Cloud KMS wraps
  the per-key DEK; external `env://...` references remain supported for
  operator-managed keys.
- Gateway authorizations include a non-secret `byok_cache_key` for encrypted
  BYOK envelopes. Attested gateways use it for short TTL, memory-only decrypted
  key caching; BYOK rotation changes the key and delete stops returning the
  envelope.
- BYOK raw keys are one-time input only; public/control-plane responses expose
  a short first/last key hint and encrypted reference metadata, never plaintext.
- Production config fails closed without an internal gateway token, signed
  Stripe webhook secret, and a non-memory storage backend.
- Production control-plane apps do not register `/chat/completions`,
  `/messages`, `/responses`, or `/embeddings`; those belong on the attested API
  plane.
- Sentry is control-plane-only and scrubs request bodies, auth headers, API
  keys, BYOK keys, prompt messages, and output text. A client-side Sentry flood
  gate caps repeated issues per fingerprint and total events per process/window
  so a single noisy integration cannot consume the whole error budget again.
- No Sentry configuration belongs in the attested enclave.

## Broadcast Observability

Workspace owners can configure Broadcast destinations at
`/v1/broadcast/destinations` or in the console under Broadcast. Supported
destinations are PostHog and OTLP JSON webhooks. Broadcast is metadata-only by
default: model, provider, token counts, latency, cost, route type, region, and
custom trace metadata. Prompt/output content is exported only when a destination
explicitly enables `include_content`; those content-enabled encrypted
destinations are returned only to the attested gateway, not normal management
responses. Metadata-only deliveries are written to a persistent Broadcast
outbox first and drained asynchronously by `/internal/broadcast/drain`, so a
PostHog/webhook outage does not block inference or lose already-settled
metadata on process restart.

## Synthetic Monitoring

TrustedRouter has a separate synthetic monitoring plane for public uptime.
Synthetic workers run outside the enclave, send tiny real requests into the
public attested API, and store only metadata. The monitor model aliases are:

- `trustedrouter/free`: OpenRouter-style free pool. Useful for users, not an
  SLA signal.
- `trustedrouter/cheap`: cheapest paid pool with provider diversity.
- `trustedrouter/eu`: EU-focused provider pool. It prefers European,
  EU-regionable, and privacy-forward providers, especially when paired with
  `https://api-europe-west4.quillrouter.com/v1`. This is a routing policy, not
  a blanket data-residency guarantee.
- `trustedrouter/monitor`: internal uptime pool for PONG and fallback checks.
  It is visible in the catalog for transparency, but authorization requires
  the configured `TR_SYNTHETIC_MONITOR_API_KEY`; normal API keys receive 403.

Workers should run from `us-central1` and `europe-west4`, using a dedicated
`trustedrouter-synthetic-monitoring` workspace/key with hard spend caps and
auto-refill. Raw samples are append-only Bigtable rows; public status pages
read compact rollups exposed at `/status`, `/status.json`, and
`/status/history?window=5m|24h|daily`. Synthetic generations use the
`TrustedRouter Synthetic` app label and are excluded from customer/app
analytics.

Provider measurement uses two independent probe classes:

- Short PONG probes randomly cover the full active catalog and measure uptime,
  TTFB, TTFT, and upstream API drift.
- A sustained 512-token stream covers the 200 most important provider/model
  routes in deterministic rotation from `us-central1`. It measures output
  tokens per second after the first token. It runs in a separate Cloud Run Job,
  so slow streams cannot delay uptime probes. Long-probe failures never count
  against provider uptime or API-drift alerts.

The current two-minute schedule gives each sustained route about 25 samples per
week and 108 per 30 days. CI calculates a full-cap spend estimate from the live
catalog and fails if it exceeds the reviewed monthly ceiling.

Status separates two service SLO classes instead of blending them with
upstream-provider behavior:

- `router_core`: attested API reachable, key authorization works, route
  candidates/fallback are available, and settle/refund is durable.
- `control_plane`: dashboard, billing UI, keys, credits, docs, trust, and
  status surfaces.

Deploy watchdogs and internal burn-rate alerts default to `router_core`.
Provider-only failures are measured per provider on `/status` and
`/leaderboard`; they do not consume the router-core error budget when fallback
remains available.

## Public Positioning

- Pricing: prepaid and BYOK usage is tracked as integer microdollars, not
  floating point dollars, so tiny token costs remain auditable in the ledger.
- Uptime target: `trustedrouter/auto` is a real chat model alias in local/test
  control-plane inference and rolls to the next configured provider on upstream
  provider failures. `trustedrouter/eu` prefers the EU-focused provider pool,
  `trustedrouter/zdr` forces a zero-retention provider floor with Anthropic
  first, and `trustedrouter/e2e` forces confidential + E2EE routes with
  Tinfoil first. Chat requests also honor OpenRouter-style `models` and
  `provider` routing filters (`order`, `only`, `ignore`, `allow_fallbacks`,
  `min_privacy`, `data_collection`, and `sort`) so clients can request explicit
  fallback chains or provider preferences. `min_privacy="confidential"` is a
  hard provider-side confidential-compute + E2EE requirement and fails closed;
  the request-value aliases `e2e` and `e2ee` select the same tier
  rather than falling back to a weaker route.
- Billing: prepaid credits and BYOK first; no subscription is required.
- Trust: hosted open source, with the running API's source commit, image
  reference, image digest, and attestation policy published at
  `trust.trustedrouter.com`.
- Signup: email signup creates a one-time management key for the workspace.
- Wallet/crypto: stablecoin checkout is wired through Stripe Checkout's Crypto
  payment method when requested. Card/default Checkout remains the default path.

## Scale Target

The goal is to support OpenRouter-class scale:

- 1 trillion tokens/day, or about 11.6 million tokens/second averaged over a
  day.
- 1-4 million developer accounts.
- 300+ actively routable models.
- 60+ providers.
- Global routing overhead competitive with edge-deployed routers.

The current production deployment does **not** meet that target yet. It runs
the control plane in four GCP regions behind a global LB with per-region
Serverless NEGs, with three live attested API regions until additional
attested regional pools are deployed. Capacity scales horizontally as more
attested pools come online; correctness, trust, billing, and SDK compatibility
are in steady-state.

Request volume depends heavily on average generation size. At 1 trillion
tokens/day:

| Average tokens/request | Requests/day | Average request rate |
| ---: | ---: | ---: |
| 1,000 | 1.0B | 11.6k rps |
| 2,500 | 400M | 4.6k rps |
| 10,000 | 100M | 1.2k rps |

The architecture can be evolved to this scale, but only if the hot path avoids
per-request global bottlenecks. That means regional stateless gateway fleets,
regional provider pools, sharded quota leases, append-only metadata writes, and
asynchronous aggregation.

## Current Latency

Measured from this development machine to the centralized GCP `us-central1`
attested API on May 2, 2026:

| Probe | p50 | p95 | Notes |
| --- | ---: | ---: | --- |
| Unauthenticated `/v1/chat/completions` rejection | 174 ms | 184 ms | Includes DNS, TCP, public TLS, enclave request handling. |
| TCP connect | 55 ms | 59 ms | Network path to `us-central1` from this machine. |
| TLS handshake complete | 112 ms | 124 ms | Public ACME cert terminates inside the enclave. |
| `/attestation` | 1.06 s | 1.12 s | Includes GCP attestation token generation, so not representative of normal routing overhead. |

The centralized network overhead is much higher than OpenRouter's reported
edge overhead, but model latency usually dominates interactive requests. The
first production scaling step should be multi-region rather than building a
custom global edge immediately.

## Horizontal Scale Shape

The production path is designed to scale by keeping the prompt gateway
stateless:

- `api.trustedrouter.com` instances can be replicated behind TCP passthrough.
  They authorize, reserve, and settle through the control plane, but prompt
  bytes never leave the attested path.
- Spanner stores strongly consistent control-plane and billing state: users,
  workspaces, keys, BYOK metadata, payment event idempotency, balances,
  aggregates, active reservations, and a 30-day terminal request audit window.
- Bigtable stores bounded high-volume activity metadata keyed by workspace and
  date. Activity and provider benchmarks retain 30 days, raw synthetic samples
  retain 14 days, and compact status rollups retain 24 months. Prompt, output,
  and tool-call arguments are not stored.
- API-key verification uses a high-entropy lookup hash for point reads; it does
  not scan keys.
- Rate limits are enforced before route handlers and use the configured store,
  so production counters are shared across Cloud Run instances.

At OpenRouter-scale traffic, the next bottleneck is not the enclave binary; it
is the synchronous billing/authorization path. The architecture needs sharded
reservations, regional Bigtable clusters, Cloud Armor edge limits, and multiple
gateway replicas before public traffic is allowed to ramp.

## Multi-Region Plan

Multi-region is feasible while preserving the trust boundary, but it has to be
done carefully:

- Run independent warm attested gateway pools in at least `us-central1`,
  `us-east4`, and `europe-west4`, then Asia once the first three regions are
  boring.
- Keep TLS private keys inside each regional Confidential Space workload.
- Move ACME from TLS-ALPN-01 to DNS-01 or another challenge flow that works
  with multiple regional endpoints for the same hostname. The current
  TLS-ALPN-01 flow is fine for one region, but a global DNS record can route
  challenges to the wrong replica.
- Keep regional hostnames such as `api-us-central1.quillrouter.com`,
  `api-us-east4.quillrouter.com`, and `api-europe-west4.quillrouter.com` for
  deterministic attestation, smoke tests, and SDK failover.
- Put `api.trustedrouter.com` behind latency/geo DNS or TCP passthrough that does
  not terminate TLS. Cloudflare orange-cloud proxying remains incompatible
  with the prompt-path trust claim.
- Authorize through regional quota leases, not a synchronous global Spanner
  transaction for every request.
- Write generation metadata to regional Bigtable clusters, then aggregate into
  global activity views asynchronously.
- Keep provider routing regional, with provider-specific circuit breakers,
  fallback policy, and per-provider rate limits.

The key design rule: a regional outage can fail closed or route to another
attested region, but it must never silently degrade to a non-attested prompt
handler.

## Router-Core Four-Nines Target

The target is an internal SLO, not a contractual SLA. 99.99% allows about
52 minutes 36 seconds of downtime per year. Public status labels this number
as a target until at least 30-60 days of measured 99.99% router-core uptime
exists.

Router-core availability means:

- attested TLS is reachable;
- API-key validation and gateway authorization work;
- route candidates are returned and fallback can choose a healthy provider;
- settlement/refund is durable or safely repairable;
- no prompt request ever falls back to a non-attested path.

The code paths that support this roadmap today are:

- `/status.json` exports `slo_classes.router_core`,
  `slo_classes.control_plane`, and burn-rate alerts for 5m, 1h, 6h, and 24h
  windows.
- The deploy watchdog reads `router_core` by default, so provider-only outages
  do not automatically roll back a control-plane deploy.
- SDKs are expected to retry connection failures and 502/503/504 across
  regional attested endpoints before surfacing failure.
- Bigtable activity writes are repairable from the durable settlement outbox.
  Settlement uses deterministic generation IDs, so retries overwrite the same
  index rows and cannot double charge or duplicate activity.

Before describing four nines as measured availability rather than a target,
require three warm GCP attested regions, tested paging, router-core chaos
tests, staged regional deploys with rollback gates, and at least 30 days of
measured router-core uptime at or above 99.99%.

## Internal Gateway Contract

The attested API plane can reserve and settle usage without sending prompt or
output content to the control plane:

- `POST /v1/internal/gateway/authorize`: validates the API key hash, reserves
  credits/key limits, and returns provider/BYOK routing metadata, route
  candidates derived from `model`, `models`, and `provider` request filters,
  and configured regional endpoints.
- `POST /v1/internal/gateway/settle`: settles successful usage and appends
  metadata-only activity rows.
- `POST /v1/internal/gateway/refund`: releases reservations after provider
  failures or client disconnects.

Set `TR_INTERNAL_GATEWAY_TOKEN` outside local development.

## Production Storage

Production uses:```text
TR_STORAGE_BACKEND=spanner-bigtable
TR_SPANNER_INSTANCE_ID=trusted-router
TR_SPANNER_DATABASE_ID=trusted-router
TR_BIGTABLE_INSTANCE_ID=trusted-router-logs
TR_BIGTABLE_GENERATION_TABLE=trustedrouter-generations

scripts/deploy-gcp.sh abilita le API, crea la tabella Spanner tr_entities, crea la tabella di generazione Bigtable, distribuisce Cloud Run e collega i metadati di trust GCP correnti alla pagina di trust.

Fatturazione

POST /v1/billing/checkout crea una sessione Stripe Checkout quando TR_STRIPE_SECRET_KEY è configurata, altrimenti restituisce una risposta mock locale deterministica. I webhook di Stripe accreditano i workspace in modo idempotente utilizzando l'ID del workspace nei metadati di Checkout. I pagamenti con carta vengono regolati immediatamente. I pagamenti ACH utilizzano {"payment_method":"ach"} e vengono accreditati solo dopo che Stripe invia checkout.session.async_payment_succeeded; il completamento di Checkout mentre l'addebito è in elaborazione non concede mai crediti. POST /v1/billing/portal segue lo stesso pattern Stripe-o-mock per la gestione della fatturazione.

Per il checkout con stablecoin, invia {"payment_method":"stablecoin"}. Quando TR_STABLECOIN_CHECKOUT_ENABLED=true, la sessione Checkout viene creata con il metodo di pagamento crypto di Stripe e accredita comunque il workspace dal webhook firmato checkout.session.completed.

ACH utilizza il metodo di pagamento us_bank_account di Stripe Checkout. La tariffa di elaborazione predefinita è 0.8% con un tetto massimo di $5 e può essere sovrascritta con TR_STRIPE_ACH_FEE_BASIS_POINTS, TR_STRIPE_ACH_FEE_FIXED_CENTS e TR_STRIPE_ACH_FEE_MAX_CENTS. Il ricaricamento automatico con carta salvata rimane esclusivamente tramite carta.

Categorie