Skip to content

About

Gateway in front of several LLM providers: it checks the residency tier before every call and returns 451 for a disallowed provider instead of silently sending. Cloudflare Workers, Hono, D1.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

summary mini-corporatellm ist ein Gateway, das vor jedem LLM-Aufruf die Residenz-Stufe des Anbieters prüft und einen unerlaubten Anbieter mit 451 blockiert, statt ihn still zu senden. Läuft auf Cloudflare Workers.

mini-corporatellm

Ein Gateway vor mehreren LLM-Anbietern, das vor jedem Aufruf prüft, ob der Anbieter auf der angeforderten Residenz-Stufe erlaubt ist. Läuft auf Cloudflare Workers, braucht keinen eigenen Server und keine Anbieterwahl im Client.

English TL;DR. A gateway in front of several LLM providers. Before every call it checks whether the provider is allowed at the data-residency tier the caller asked for. If it is not, the gateway answers 451 instead of forwarding the request quietly, and the verdict is visible in the response body. Runs on Cloudflare Workers. The rest of this README is in German.

Live: https://mini-corporatellm.mariusdeving.workers.dev · Stack: Workers · Hono · D1 · Durable Objects · Mistral

Die Gateway-Konsole: eine Frage, eine Antwort, das Routing- und Residenz-Verdikt darunter

Was es tut

Ein Aufruf kommt im OpenAI-Wire-Format an. Bevor etwas gesendet wird, entscheidet ein Chokepoint anhand der angeforderten Stufe, ob der Anbieter erlaubt ist: sovereign lässt nur EU-eigene Anbieter zu (Mistral, Aleph Alpha), eu-residency zusätzlich EU-gehostete US-Anbieter (Azure-OpenAI-EU, Bedrock, Vertex), off auch die US-Direkt-APIs. Ein Anbieter außerhalb seiner Stufe wird mit 451 abgewiesen und nicht still gesendet.

Erst danach laufen Rate-Limit und Circuit-Breaker in einem Durable Object, der Aufruf geht an den Anbieter, und Verbrauch plus eine Audit-Zeile landen in D1. Die Audit-Zeile enthält nur Metadaten, keinen Prompt-Text.

Die Konsole auf / ist der sichtbare Teil davon: sie ist auf Mistral und die Stufe eu-residency festgelegt, und sie zeigt zu jeder Antwort das Routing (angefragt, bedient von, Fallback) und die Residenz-Klasse, unter der sie entstanden ist. Das Repo enthält darüber hinaus einen Agent-Loop, eine RAG-Pipeline und Mandanten-Governance; die sind in docs/ARCHITECTURE.md beschrieben.

Architektur

Der Weg einer Frage aus der Konsole:

Browser
  │  POST /web/demo/chat        Rate-Limit pro IP (8 / Minute)
  ▼
Worker (Hono)
  │  SELF-Service-Binding
  ▼
POST /v1/chat/completions
  │
  ├─ checkAllowed(anbieter, stufe) ──── nicht erlaubt ──▶ 451, kein Aufruf
  │
  ├─ RateLimitDO (Durable Object)  Limit + Circuit-Breaker
  │
  ├─ Adapter ──▶ Mistral (EU-eigen, Frankreich)
  │                 └─ Anbieter tot? Fallback auf derselben Stufe
  │
  └─ D1: Usage-Ledger + Audit-Zeile (nur Metadaten)
        ▼
     Antwort + _residency + _gateway.routing

Die Konsole erfindet das Verdikt nicht. Sie zeigt die Felder _residency und _gateway.routing aus derselben Antwort, die auch den Text trägt.

Verifikation

Was Wert Wann
Tests 150 grün, 0 rot (bun test) 2026-07-14
Typecheck tsc --noEmit sauber 2026-07-14
Live-Antwort mistral-small-latest, Klasse eu-owned, Stufe eu-residency, 1408 ms 2026-07-14
Residenz-Sperre 3 von 8 Anbietern erhalten 451 auf der Standardstufe eu-residency 2026-07-14

Reproduzierbar ohne Browser:

curl -s -X POST https://mini-corporatellm.mariusdeving.workers.dev/web/demo/chat \
  -H 'content-type: application/json' \
  -d '{"prompt":"Was ist der Unterschied zwischen EU-Datenresidenz und Souveränität?"}'

Die Antwort trägt residency.residency, gateway.routing.servedBy und den Token-Verbrauch.

Grenzen

  • Die Demo kann die Sperre nicht vorführen. Sie ist auf Mistral und eu-residency festgelegt, damit ein fremder Klick keine Anbieterwahl trifft. Die Anbieter-Matrix auf der Seite zeigt, wen ein 451 träfe, aber sie löst keinen aus.
  • EU-Residenz ist hier L1, nicht L2. Daten werden in der EU verarbeitet, aber Cloudflare und die US-Anbieter bleiben dem CLOUD Act unterworfen. Die Lücke steht in docs/EU-SOVEREIGNTY.md.
  • Die D1-EU-Location ist ein Erstellungs-Hinweis, keine harte Jurisdiktions-Zusage. R2 und Durable Objects sind hart auf eu gepinnt, D1 nicht.
  • Die Kostenzahlen stammen aus einer Platzhalter-Preistabelle (2026-05-eu-placeholder-v1), nicht aus Abrechnungsdaten.
  • Keine Kunden, kein Betrieb bei Dritten. Das Repo ist eine Demo und ein Portfolio-Stück.

Lokal starten

bun install
bun run typecheck && bun test
env -u CLOUDFLARE_API_TOKEN wrangler dev --port 8793

Ohne DEMO_API_KEY in .dev.vars zeigt die Konsole eine aufgezeichnete Antwort und sagt das auch: kein Live-Aufruf, kein Verdikt. Für echte Antworten braucht es MISTRAL_API_KEY plus einen DEMO_API_KEY, der zu einem Schlüssel in D1 gehört (scripts/seed-dev-tenants.sql legt lokal einen an).

Lizenz

MIT. Siehe LICENSE.

About

Gateway in front of several LLM providers: it checks the residency tier before every call and returns 451 for a disallowed provider instead of silently sending. Cloudflare Workers, Hono, D1.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages