In vielen Architekturen müssen Zugriffsentscheidungen an Netzwerkgrenzen getroffen werden – etwa in API-Gateways oder Service-Meshes. Üblich ist der Einsatz von OPA als WASM-Modul innerhalb von Envoy, doch die damit verbundene Go-Runtime und der Rego-Parser führen zu einer unerwünschten Größe. Hier setzt Zopa an: ein neuartiger Autorisierungsservice in Zig, der mit nur 60 KB auskommt und trotzdem volle Kompatibilität zu Proxy-WASM 0.2.1 bietet.
Warum herkömmliche Lösungen zu schwer sind
Die meisten Autorisierungsdienste wie OPA integrieren neben dem Evaluator auch einen Parser und eine Laufzeitumgebung. Während dies die Flexibilität erhöht, führt es zu einer binären Größe von mehreren Megabytes. Für Edge-Filter in Envoy ist dies oft überdimensioniert, da hier nur einfache allow/deny-Entscheidungen benötigt werden.
Alternative Frameworks wie Cedar oder Casbin bieten derzeit keine offiziellen WASM-Builds an. Zopa füllt diese Lücke mit einer schlanken, auf Zig basierenden Lösung. Das Binary läuft auf jedem Host, der Proxy-WASM 0.2.1 unterstützt – darunter Envoy, Wasmtime, WAMR und V8.
Trennung von Policy und Evaluation
Zopa folgt einem klaren Architekturprinzip: Policy wird außerhalb des WASM-Moduls definiert, während die Evaluation im Binär stattfindet.
- Schritt 1: Policy-Autoren schreiben Regeln in Rego (OPA’s deklarative Sprache).
- Schritt 2: Ein CI-System wandelt die Rego-Regeln in ein AST-JSON um.
- Schritt 3: Envoy lädt das AST bei Startzeit als Plugin-Konfiguration.
- Schritt 4: Bei jeder Anfrage evaluiert Zopa die Regel und gibt
1(allow) oder0(deny) zurück.
Dieser Ansatz vermeidet die Integration eines Compilers oder Parsers in das WASM-Modul – ein entscheidender Faktor für die Größenreduktion.
Die Technik hinter der 60-KB-Größe
Die kompakte Größe von Zopa resultiert aus drei zentralen Designentscheidungen:
- `wasm32-freestanding`-Target:
- Keine Abhängigkeit von WASI oder Betriebssystemaufrufen.
- Nur ein minimaler Teil der Standardbibliothek wird eingebunden.
- Kein Garbage Collector:
- Zig verwendet explizites Speichermanagement (ähnlich Rust).
- Keine GC-Overheads oder Metadaten für Speicherbereinigung.
- Null Abhängigkeiten:
- Sämtliche Logik – einschließlich eines handgeschriebenen JSON-Parsers – stammt aus der Zig-Standardbibliothek.
- Der Parser ist in wenigen hundert Zeilen implementiert und unterstützt sogar Surrogatpaare.
Im Vergleich dazu integriert OPA WASM die Go-Runtime, den Rego-Parser und den Evaluator – was zu einer deutlich größeren Binärdatei führt.
Speichermanagement: Arena-Allocator im Einsatz
Zopa nutzt zwei Allokatoren mit unterschiedlichen Lebenszyklen:
- `host_allocator`
- Verantwortlich für Puffer, die die Host-WASM-Grenze überschreiten.
- Basierend auf Zig’s
std.heap.wasm_allocator(Freelist-Allocator). - Lebensdauer: die gesamte Modulausführung.
- `request_arena`
- Wird pro Anfrage neu initialisiert.
- Implementiert als
std.heap.ArenaAllocator(Scratch-Space). - Nach der Anfrageverarbeitung wird der gesamte Speicher mit
reset(.retain_capacity)freigegeben. - Vorteil: Nach der Warm-up-Phase wächst der WASM-Heap nicht mehr, da bestehende Speicherseiten wiederverwendet werden. Dies führt zu konstanter Speichernutzung und höherem Durchsatz.
Die Regel ist einfach: Ein von einem Allokator erzeugter Zeiger darf nur vom entsprechenden Deallokator freigegeben werden. Der Proxy-WASM-Adapter gibt Host-allocierte Puffer korrekt zurück, während der Evaluator auf die Arena setzt.
Drei-Phasen-Prüfung für HTTP-Anfragen
Zopa trifft Autorisierungsentscheidungen in drei separaten Phasen der HTTP-Verarbeitung. Jede Phase verwendet eine spezifische Zielregel:
| Phase | Zielregel | Eingabedaten | Verhalten bei deny | |-------|-----------|--------------|----------------------| | proxy_on_request_headers | allow | {method, path, headers} | 403 Forbidden | | proxy_on_request_body | allow_body | {body, body_raw} | 403 + Pause | | proxy_on_response_headers | allow_response | {response: {status, headers}} | 503 Service Unavailable |
- Eine Policy mit nur einer
allow-Regel überspringt die Body- und Response-Phasen automatisch. - Die Entscheidung basiert auf booleschen Flags, die bei der Konfiguration gesetzt werden. Existiert eine Zielregel nicht, gibt der Callback
Continuezurück.
Der Ablauf einer Anfragenverarbeitung
Wenn Envoy eine Anfrage an Zopa übergibt, läuft folgende Logik ab:
- Initialisierung:
- Das Policy-AST wird einmalig bei Startzeit geladen und im
host_allocatorgespeichert. - Pro Anfrage wird ein neuer
request_arenaangelegt.
- Phasenverarbeitung:
- Für jede Phase wird
evaluate()aufgerufen. - Nach Abschluss einer Phase wird der
arenazurückgesetzt.
- Ergebnis:
1=allow(Regel erfolgreich evaluiert)0=deny(keine passende Regel oder defaultfalse)-1= Fehler (z. B. Parsing-Problem oder Rekursionslimit)
Fehler werden standardmäßig als deny behandelt, um Sicherheit zu gewährleisten.
Das Policy-AST: Struktur und Beispiel
Zopa erwartet keine Roh-Rego-Dateien, sondern ein AST-JSON als Eingabe. Die unterstützten Knoten entsprechen einem Subset von Rego:
{
"type": "module",
"rules": [
{
"type": "rule",
"name": "allow",
"default": true,
"value": {
"type": "value",
"value": false
}
},
{
"type": "rule",
"name": "allow_body",
"default": false,
"value": {
"type": "ref",
"path": ["input", "body_size"]
}
}
]
}Ein Beispiel: Die Regel "role equals admin → allow" könnte als AST wie folgt aussehen:
{
"type": "rule",
"name": "allow",
"default": false,
"value": {
"type": "eq",
"left": {"type": "ref", "path": ["input", "role"]},
"right": {"type": "string", "value": "admin"}
}
}Dieses Format ermöglicht eine effiziente Evaluation ohne zusätzlichen Parsing-Overhead während der Laufzeit.
Ausblick: Leichtere Autorisierung für Edge-Netzwerke
Mit Zopa zeigt sich, dass Autorisierungsdienste auch an Netzwerkgrenzen schlank und performant umgesetzt werden können. Die Kombination aus Zig, handoptimiertem Speichermanagement und der Trennung von Policy und Evaluation setzt neue Maßstäbe für WASM-basierte Filter.
Für Teams, die bisher auf OPA oder ähnliche Lösungen verzichtet haben, weil der Overhead zu groß war, bietet Zopa eine überzeugende Alternative. Die Zukunft könnte weitere Optimierungen in Richtung Echtzeit-Regelaktualisierung oder maschinelles Lernen für Policy-Generierung bringen – doch schon jetzt ist Zopa ein Game-Changer für ressourcenbewusste Architekturen.
KI-Zusammenfassung
Zopa, proxy-wasm için yazılmış 60 KB'lik bir izin motorudur. Rego dilini destekler ve hızlı izin kararları verir.