PRODPiattaforma BaaS europea sovranaApri Dashboard →

Ingegneria · 15 lettura minima

Il core Rust di Aurabase: un Backend-as-a-Service unificato

Affane Daylami · Fondateur · 16 agosto 2026

Torniamo al blog

Aurabase è un Backend-as-a-Service scritto in Rust, non solo per alcuni servizi periferici, ma per l'intero nucleo applicativo: gateway, autenticazione, database, tempo reale, archiviazione, notifiche, AI, provisioning. L'area di lavoro Cargo alla radice del repository elenca 18 casse compilate insieme da un singolo spazio di lavoro di build cargo, senza linguaggio di terze parti nascosto dietro la logica del prodotto.

Questo testo inglese è stato generato automaticamente dall'originale francese e non è stato ancora rivisto.
Questa pagina è stata tradotta automaticamente. Fa fede la versione inglese.

Questo file documenta questa architettura così come esiste effettivamente nel codice, verificata file per file al 23 agosto 2026 - diagrammi, figure ed estratti inclusi. Questa è la pagina pilastro del cluster “Rust Engineering”: fornisce la panoramica e i collegamenti alle analisi tecniche approfondite (Axum, Cargo workspace, gateway, PostgREST, pg_graphql e il resto del file) pubblicate o in fase di pubblicazione. Per il confronto completo del prodotto con un BaaS concorrente, vedere il nostro confronto Aurabase vs Supabase.

L'essenziale

  • Single Workspace Cargo: 18 crate (11 servizi aziendali, auraCLI, 5 librerie condivise, Rust SDK) compilati insieme da un singolo cargo build --workspace.
  • Il codice aziendale pesa circa 274.000 righe di Rust (misurate tramite find + wc -l, 23 agosto 2026), distribuite su queste 18 casse.
  • Il gateway (aura-gateway) separa due piani: dati (SDK, porta 8080) e gestione (Studio, porta 8090), ciascuno con il proprio stack middleware e autenticazione.
  • Aurabase non riscrive PostgREST: il vero binario upstream (v12.2.8) viene eseguito per tenant, orchestrato dai servizi Rust: il valore aggiunto è attorno ad esso, non invece.
  • L'unico allontanamento degno di nota dal puro Rust: il runtime predefinito di Edge Functions (modalitàdeno) è un servizio TypeScript dedicato basato su V8 Isolates; esiste un secondo percorso, nativo e in Rust tramite Wasmtime, per la modalità wasm.
18
CASSE PER AREA DI LAVORO
11 servizi + CLI + 5 librerie + SDK Rust
~274k
LINEE DI RUGGINE
find + wc -l, 23 agosto 2026
2
PIANI GATEWAY
dati: 8080 · gestione: 8090
10/11
SERVIZI SU NATS
async-nats in dipendenza diretta
#
Posizionamento

Ciò che distingue Aurabase da un servizio assemblato BaaS per servizio

La maggior parte dei BaaS Postgres open source confeziona i propri servizi in più lingue. Questo non è un giudizio di valore: è un fatto architettonico che ha conseguenze concrete: tante catene di compilazione, convenzioni di errore e logiche di autenticazione da mantenere sincronizzate quante sono le lingue in gioco.

In Aurabase, il livello di prodotto che scriviamo e manteniamo noi stessi (gateway, autenticazione, database, tempo reale, archiviazione, notifiche, intelligenza artificiale, provisioning, gestione degli account) è un unico spazio di lavoro Cargo, un unico linguaggio, un'unica catena di creazione. Questa è la scelta che questo fascicolo documenta.

Precisione necessaria

"Nucleo unificato" non significa che tutto ciò che viene eseguito in produzione è Rust. Come ogni Postgres BaaS, anche Aurabase si basa su elementi costitutivi open source che non ha scritto: PostgreSQL stesso, PostgREST, NATS. La differenza strutturale con uno stack eterogeneo non riguarda questi elementi costitutivi condivisi, ma riguarda lo strato di prodotto che li orchestra. Le sezioni seguenti descrivono in dettaglio dove passa esattamente questo confine, inclusa l'unica vera eccezione che abbiamo riscontrato durante l'auditing del codice (Funzioni Edge, sezione 09).

#
Lo spazio di lavoro

18 casse, una catena di compilazione

La root Cargo.toml dichiara un'area di lavoro Cargo nel risolutore v2 con 18 membri: 11 servizi aziendali, aura-cliCLI, 5 librerie condivise e aurabase-rsSDK. Ecco l'elenco effettivo, come appare nel repository.

Cargo.tomltoml
[workspace]
resolver = "2"

members = [
    # Servizi (11)
    "services/aura-gateway", "services/aura-auth", "services/aura-db",
    "services/aura-provisioner", "services/aura-realtime", "services/aura-storage",
    "services/aura-functions", "services/aura-notifications", "services/aura-ai",
    "services/aura-migrator", "services/aura-control",
    # Strumenti
    "aura-cli",
    # Librerie (5)
    "libs/aura-core", "libs/aura-crypto", "libs/aura-db-adapters",
    "libs/aura-migrations", "libs/aura-telemetry",
    "aurabase-rs",
]

Le dipendenze condivise risiedono in [workspace.dependencies]: Axum 0.8 (con WebSocket, multipart, macro), Tokio, Tower/Tower-HTTP, SQLx 0.8 (Postgres + MongoDB tramite mongodb per motore NoSQL secondario), async-nats 0.47, sqlparser 0.53 (convalida SQL di NL2SQL), oauth2 5, jsonwebtoken 10 e due librerie di prestazioni presenti in quasi tutti i servizi: mimalloc come allocatore globale e moka/dashmap per la cache in memoria.

Il profilo di rilascio documenta una scelta presunta: panic = "unwind" anziché "abort". Il commento del file si spiega da sé: il panico in un gestore Axum/Tokio viene isolato dal runtime (la richiesta interessata restituisce 500) invece di interrompere l'intero processo e tagliare le richieste concorrenti. Il miglioramento delle prestazioni diabort (circa dall'1 al 2% di RPS) non vale la perdita di isolamento, secondo la stessa nota. Si tratta di un compromesso tra affidabilità e velocità documentato nel codice, non un'affermazione di marketing.

Un singolo cargo build --workspace compila il tutto. Un singolo cargo test --workspace esegue l'intera suite di test. Un singolo cargo clippy --workspace --all-targets -- -D warnings uniforma l'intero prodotto con le stesse regole. I dettagli di questa struttura - ereditarietà delle dipendenze, grafico interno tra librerie e servizi, insidie ​​che abbiamo incontrato durante la sua crescita - sono oggetto di un articolo dedicato: Architettura dello spazio di lavoro Cargo, come strutturare un backend Rust multi-servizio.

Linee Rust per servizio (find services -name '*.rs' | xargs wc -l, 23 agosto 2026):

controllo dell’aura

36 024

aura-db

30 255

aura-auth

28 431

fornitore dell'aura

28 271

notifiche dell'aura

18 498

avrà

18 305

aura-gateway

16 938

aura in tempo reale

16 799

immagazzinamento dell'aura

13 747

funzioni dell'aura

11 619

aura-migratore

538

Escluse le librerie condivise (aura-db-adapters: 24.725 linee, aura-core: 7.259, aura-migrations: 3.641, aura-crypto: 2.718, aura-telemetry: 201), la CLI (aura-cli: 9.845) e l'SDK di Rust (aurabase-rs: 6.363). aura-migrator, un lavoro di migrazione monouso e non un server HTTP di lunga durata, rimane deliberatamente il servizio più piccolo nell'area di lavoro.

#
Servizi

11 servizi aziendali, ciascuno un server Axum autonomo

Ogni servizio è un binario Axum/Tokio indipendente, con la propria configurazione e porta. Dieci degli undici espongono /health e /metrics e dichiarano mimalloc come allocatore globale: l'unica eccezione, aura-migrator, è un lavoro a scopo singolo anziché un server in esecuzione continua.

aura-gatewayGateway a doppio piano (dati:8080, gestione:8090): proxy per tutti gli altri servizi.
aura-authAutenticazione: JWT, 15 provider OAuth denominati + OIDC generico per progetto, sessioni, MFA.
aura-dbAPI del database: gestione/ricaricamento PostgREST per tenant, adattatori Postgres e MongoDB, CDC.
fornitore dell'auraCiclo di vita del progetto: cluster CNPG dedicati o condivisi, ruoli, PostgREST per tenant.
aura in tempo realeWebSocket e SSE, trasmissione CDC, presenza tra istanze tramite NATS JetStream KV.
immagazzinamento dell'auraOggetti compatibili S3 (MinIO), policy RLS trasferibili da Postgres.
funzioni dell'auraFunzioni Edge: distribuzione, processi, cron, runtime Wasmtime nativo (vedere sezione 09).
notifiche dell'auraE-mail, push, webhook in uscita.
avràGateway NL2SQL, RAG e LLM (OpenAI nativo, Anthropic, Gemini + qualsiasi endpoint compatibile con OpenAI).
aura-migratoreMotore di migrazione: singola origine dello schema di mantenimento riprodotto ad ogni provisioning.
controllo dell’auraPiano di gestione: account sviluppatore, organizzazioni, fatturazione, API Studio.

La aura CLI (≈ 9.800 righe) comunica con le stesse API degli SDK: non ha un percorso privilegiato. Il riferimento completo per ciascun servizio si trova nella documentazione dell'architettura e nel riferimento CLI .

#
Biblioteche condivise

5 casse che evitano la deriva tra i servizi

In uno stack poliglotta, una regola di sicurezza – formato degli errori, protezione SSRF, limitazione della velocità – deve essere reimplementata in ciascuna lingua e quasi sempre cambia nel corso dei mesi. Aurabase lo codifica una volta, in una libreria dello spazio di lavoro, consumata da tutti i servizi interessati.

nucleo dell'aura7 259 l.Primitive condivise: errori, busta di risposta API, attestazioni JWT, autenticazione interna da servizio a servizio, helper NATS, limitazione della velocità, client HTTP protetto SSRF, interruttore automatico, risoluzione tenant, misurazione.
adattatori aura-db24 725 l.Tratto per adattare il database unificato, le implementazioni Postgres e MongoDB utilizzate da aura-db.
aura-cripto2 718 l.Hashing delle password, generazione di token, firma/convalida JWT, crittografia a livello di campo.
migrazioni dell'aura3 641 l.Motore di migrazione: origine unica dello schema tenant, riprodotta dal provider (non le migrazioni/cartelle specifiche per ciascun servizio).
aura-telemetria201 l.Configurazione OpenTelemetry + tracciamento, condivisa dagli 11 servizi.

Conseguenza diretta: una patch di sicurezza in aura-core (la protezione SSRF, ad esempio) si propaga a ciascun servizio consumer nel successivo cargo build, non attraverso cinque patch separate in cinque lingue.

#
La porta

Doppio piano: traffico SDK e traffico Studio

aura-gateway separa due superfici che non hanno né gli stessi client né lo stesso modello di autenticazione. Il piano dati (porta 8080, variabile GATEWAY_PORT) riceve traffico SDK/app, autenticato dalla chiave API (apikey, X-API-Key o ?apikey=). Il piano di gestione (porta 8090, MANAGEMENT_PORT) riceve il traffico Studio/amministratore, autenticato da una console JWT (Authorization: Bearer).

gateway/routes.rsrust
// Piano dati: chiave API
.route("/v1/auth/{*path}", any(auth_proxy))
.route("/v1/db/{*path}", any(db_proxy))
.route("/v1/realtime/ws", get(realtime_ws_proxy))
.route("/v1/realtime/sse", get(realtime_sse_proxy))
.route("/v1/storage/{*path}", any(storage_proxy))
.route("/v1/notifications/{*path}", any(notifications_proxy))
.route("/v1/ai/{*path}", any(ai_dispatcher))
.route("/v1/functions/{*path}", any(functions_proxy))

// Piano di gestione: console JWT
.route("/v1/control/{*path}", any(control_proxy))

Ogni piano trasporta il proprio stack di middleware - identificazione delle query, registro di accesso, limite di velocità, autenticazione (specifica del piano), interruttore di circuito, quindi proxy - implementato in moduli separati (middleware/rate_limit.rs, middleware/circuit_breaker.rs, middleware/auth_data_plane.rs, middleware/auth_management_plane.rs) piuttosto che una singola catena condivisa accidentalmente tra due superfici che non dovrebbero fidarsi l'una dell'altra allo stesso modo. modo.

L'ordine esatto dei middleware, il rate limiting per target e il proxy NATS/HTTP sono oggetto di un articolo dedicato: dual-plane gateway, progettare un gateway API data-plane/management-plane in Rust.

#
I dati

Perché Aurabase non reimplementa PostgREST in Rust

L'API REST autogenerata utilizzata dall'SDK non è un modulo Rust interno: è il vero binario upstream PostgREST (postgrest/postgrest:v12.2.8), distribuito in 2 repliche per progetto dedicato (deploy/cnpg/tenant-postgrest.yaml), co-localizzato con l'istanza CNPG del tenant. aura-provisioner crea questa distribuzione e aura-db analizza il suo endpoint OPTIONS dopo ogni ricaricamento dello schema per confermare che PostgREST ha preso in considerazione la modifica DDL.

Si tratta di una scelta architetturale scontata, non di una scorciatoia: PostgREST è un progetto maturo e ampiamente adottato, la cui riscrittura del comportamento poco a poco in Rust non porterebbe a nulla. Il lavoro su Rust di Aurabase è incentrato su routing multi-tenant, provisioning, isolamento della rete da parte di NetworkPolicy, autenticazione condivisa con il gateway, ricaricamento dello schema orchestrato, non all'interno del motore di query stesso. Ciò che copre realmente questa compatibilità, e dove si ferma, è oggetto di un articolo separato: PostgREST, compatibilità effettiva e alternative.

Stessa logica sul lato GraphQL: l'estensione Postgres pg_graphql (pacchetto .deb precompilato, v1.6.1) è installata nell'immagine CNPG dedicata e attivata su richiesta per progetto tramite l'endpoint POST /v1/control/projects/{project_id}/graphql/enable - non è nemmeno un motore GraphQL riscritto. Dettagli e confronto onesto con Hasura e PostGraphile: API GraphQL nativa su Postgres con pg_graphql.

#
Isolamento

Ruolo RLS e autenticatore, non un livello di applicazione

L'isolamento multi-tenant non si basa su un filtro WHERE tenant_id = ? aggiunto da un ORM dell'applicazione: ogni richiesta passa attraverso il ruolo aura_authenticator, che esegue un SET LOCAL ROLE tenant_<uuid> con ambito transazione prima di eseguire la richiesta, esattamente il modello che PostgREST stesso si aspetta. La sicurezza a livello di riga fa il resto, a livello del motore, non a livello del codice aziendale.

Non tutti i progetti condividono la stessa topologia Postgres. Il codice aura-provisioner espone un tipo ProjectInstanceKind con almeno due varianti reali: FullyDedicated (istanza CNPG interamente dedicata al progetto) e SharedClusterDedicated (schema isolato da RLS su un cluster CNPG condiviso). Il piano sottoscritto determina la topologia: non è una promessa uniforme di una “base dedicata per tutti”.

Astuce

L'argomento “perché una base dedicata per progetto piuttosto che un puro isolamento applicativo” è oggetto di un articolo dedicato: RLS e base dedicata per progetto. La documentazione Sicurezza a livello di riga copre l'implementazione pratica.

#
Messaggistica

Nucleo NATS, non JetStream: messaggistica asincrona tra servizi

Dieci degli undici servizi aziendali dichiarano async-nats come dipendenza diretta nel loro Cargo.toml – solo aura-migrator ne fa a meno. Ciò che il nome di questa cassa non dice: questi servizi quasi ovunque utilizzano l'API pub/sub coredi NATS (Client::publish / publish_with_headers, consegna al massimo una volta senza persistenza o riproduzione), non JetStream. Questo è il caso verificato nel codice per i tre usi che contano di più: la distribuzione del CDC PostgreSQL su aura-realtime, la notifica dei lavori Edge Functions in aura-functions (il DLQ stesso risiede in Postgres, non in NATS) e gli eventi di provisioning tra aura-provisioner e il resto della flotta.

JetStream, la modalità di persistenza e flussi denominati di NATS, viene visualizzato solo in una posizione verificata nel monorepo: la presenza tra istanze KV Store in aura-realtime (bucket aura_presence, archivio di memoria, 60 secondi max_age), che sincronizza chi è connesso a quale canale su più istanze di ws-front: uno stato condiviso tra istanze, non un flusso di eventi da riprodurre. Nessun flusso JetStream persistente è stato trovato altrove nell'area di lavoro. I dettagli della pipeline CDC - wal2json, elezione di un cdc-worker unico da parte di Lease Kubernetes, fan-out core NATS alle repliche ws-front, nuova verifica RLS da parte dell'abbonato - sono oggetto di un articolo dedicato: ha trasmesso il CDC PostgreSQL con NATS. La documentazione Realtime copre l'utilizzo sul lato SDK.

#
L'eccezione accettata

Edge Functions: due runtime per due esigenze

Questa è la sfumatura più importante di questo file e l'unico vero allontanamento dal puro Rust nel codice prodotto Aurabase. Ogni funzione trasporta un campo runtime che vale "wasm" o "deno". Il gestore di invocazione sceglie di conseguenza il percorso di esecuzione: lo snippet effettivo, commentato nel codice stesso:

functions/dispatch.rsrust
// Invio in base al runtime: WASM (wasmtime) o Deno (V8 isola tramite edge-runtime)
let resp = if func.runtime == "wasm" {
    state.runtime.invoke(&wasm_bytes, &func.code_hash, req).await?
} else {
    // Proxy per aura-edge-runtime — V8 Isolates (supabase/edge-runtime, MIT)
    proxy_to_edge_runtime(&state.config.edge_runtime_url, …).await?
};

La modalità wasm è nativa: aura-functions dipende direttamente da Wasmtime (versione 43, presenta async e cranelift) ed esegue il modulo nello stesso processo Rust, con conteggio del carburante, interruzione per epoca e limitazione della memoria tramite StoreLimits. La modalità deno — quella utilizzata per impostazione predefinita nell'editor di Studio, per una compatibilità quasi diretta Deno.serve() con il codice Supabase esistente — delega l'esecuzione a aura-edge-runtime, un servizio TypeScript separato di circa 550 righe, modellato esplicitamente — lo stesso commento dell'intestazione del file sorgente lo cita — su supabase/edge-runtime (licenza MIT), che isola ogni invocazione nel proprio Isolamento V8.

Perché è onesto dirlo così?

Il controllo (distribuzione, autorizzazioni, lavori, cron, quote) rimane interamente in Rust in aura-functions. Solo l'esecuzione del codice utente in modalità deno fa uscire dal binario Rust. Si tratta di un compromesso ingegneristico difendibile (gli Isolati V8 sono ciò che Deno fornisce nativamente per questo livello di sandboxing), non un'omissione che preferiamo tacere. Il confronto Wasmtime vs Wasmer e l'analisi dell'avvio a freddo di WebAssembly, presto disponibili in questo file, approfondiranno questo argomento.

Per la documentazione procedurale di entrambi i percorsi di distribuzione, vedere Edge Functions. Per il playbook sulla migrazione di Deno da Supabase, consulta Migrare un progetto Supabase ad Aurabase, che ha già documentato questa distinzione prima di questo file.

#
In pratica

Ciò che questo cuore unificato cambia concretamente per te

Se chiami l'API semplicemente tramite un SDK, questa architettura è invisibile: questo è l'obiettivo. È importante principalmente per tre tipi di pubblico: coloro che valutano l'affidabilità operativa di un backend multi-tenant prima di migrarvi i dati di produzione, coloro che intendono contribuire al repository (MIT, monorepo singolo) e coloro che vogliono capire perché una patch di sicurezza sul lato Aurabase si diffonde rapidamente anziché lentamente.

Concretamente: un singolo IC (cargo build --workspace, cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings) copre il 90% o più della superficie del prodotto. Una revisione del codice su aura-core influisce potenzialmente su dieci servizi contemporaneamente: in meglio (una correzione non si perde per strada) e in peggio (una modifica scarsamente isolata si diffonde altrettanto rapidamente). È un compromesso, non una soluzione magica, ed è proprio per questo che documentiamo l'architettura effettiva anziché un riepilogo di marketing.

#
Hub cartelle

Il resto del file di Rust Engineering

Questa pagina del pilastro si collega alle analisi tecniche del cluster, man mano che vengono pubblicate. Stato attuale al momento della pubblicazione di questa pagina: i collegamenti diventano attivi non appena l'articolo corrispondente è online.

Cluster A: struttura e architettura

Axum vs Actix-web: quale framework per un backend Rust in produzione?Pubblicato

Architettura del workspace Cargo: come strutturare un backend Rust multiservizioPubblicato

Gateway dual-plane: progettazione di un gateway API piano dati/piano di gestione in RustPubblicato

Cluster B: API autogenerata su Postgres

PostgREST: cosa copre realmente la compatibilità e quali alternative esistonoPubblicato

API GraphQL nativa su Postgres con pg_graphql: cosa Hasura e PostGraphile non fanno lo stessoPubblicato

RLS e base dedicata per progetto: la scelta dell'isolamento multi-tenant di AurabasePubblicato

Cluster C: tempo reale e messaggistica

Distribuisci PostgreSQL CDC con NATS: architettura in tempo realePubblicato

Cluster D: WebAssembly di funzioni Edge

Wasmtime vs Wasmer: quale runtime WebAssembly per Edge Functions in produzioneProssimamente
Funzioni Edge in Rust/WASM rispetto a Cloudflare Workers e Vercel EdgeProssimamente
WebAssembly con avvio a freddo: cosa dicono veramente i benchmark (e cosa non possiamo ancora dire)Prossimamente

Cluster E – Migrazione e alternative

Migra un progetto Supabase su Aurabase senza riscrivere le tue policy RLSPubblicato

Self-hosting sovrano: posizionamento di Aurabase contro BaaS nativo di Rust Disponibile a breve

#
Domande frequenti

Domande frequenti

Il codice Aurabase è open source?+
Il repository è un unico monorepo: i 18 crate Rust del workspace, gli SDK del client (JavaScript, Rust, Python, Dart) e Next.js Studio convivono lì, pubblicati sotto licenza MIT su GitHub.
Aurabase può essere ospitato autonomamente?+
Sì. Il banco k3d locale (./start.sh) e la tabella Helm ufficiale (deploy/helm/aurabase/) ti consentono di distribuire lo stack completo. Aurabase Cloud rimane l'opzione gestita se preferisci non gestire tu stesso l'infrastruttura.
L'SDK JavaScript utilizza la stessa sintassi di Supabase?+
In sostanza, sì: createClient(), il generatore di query concatenato .from().select().eq(), i flussi di autenticazione e le politiche RLS mirano a una compatibilità quasi diretta: questo è ciò che rende fattibile una migrazione da Supabase ad Aurabase senza una riscrittura completa.
È necessario conoscere Rust per utilizzare Aurabase?+
No. Rust è il linguaggio di backend, non quello che scrivi quotidianamente: gli SDK client esistono in JavaScript/TypeScript, Rust, Python e Dart e le funzioni Edge sono scritte per impostazione predefinita in JavaScript/TypeScript (runtime Deno). Rust entra in gioco solo se scegli esplicitamente la modalità di esecuzione WASM nativa.
Aurabase Edge Functions funziona davvero in WebAssembly?+
Dipende dalla modalità scelta. La modalità predefinita (deno) esegue il codice JavaScript/TypeScript negli isolati V8 tramite un servizio dedicato, non in un motore WASM. Esiste una seconda modalità (wasm) che viene eseguita in modo nativo nel servizio Rust aura-functions tramite Wasmtime, ma questo non è il percorso predefinito.

PRONTO PER L'IMPLEMENTAZIONE?

Il tuo backend in cinque minuti.

Nessuna carta di credito richiesta · 500 MB gratuiti · 50.000 MAU