PRODPlataforma BaaS soberana europeaAbrir panel →

Ingeniería · 15 lectura mínima

El núcleo Rust de Aurabase: un backend como servicio unificado

Affane Daylami · Fondateur · 16 de agosto de 2026

volver al blog

Aurabase es un backend como servicio escrito en Rust, no solo para algunos servicios periféricos, sino para todo el núcleo de su aplicación: puerta de enlace, autenticación, base de datos, tiempo real, almacenamiento, notificaciones, inteligencia artificial y aprovisionamiento. El espacio de trabajo Cargo en la raíz del repositorio enumera 18 cajas compiladas juntas por un único espacio de trabajo de construcción de carga, sin ningún lenguaje de terceros oculto detrás de la lógica del producto.

Este texto en inglés se generó automáticamente a partir del original en francés y aún no ha sido revisado.
Esta página fue traducida automáticamente. La versión en inglés es autorizada.

Este archivo documenta esta arquitectura tal como existe realmente en el código, verificada archivo por archivo al 23 de agosto de 2026; se incluyen diagramas, figuras y extractos. Esta es la página principal del grupo "Rust Engineering": brinda una descripción general y enlaces a los análisis técnicos en profundidad (Axum, Cargo workspace, gateway, PostgREST, pg_graphql y el resto del archivo) publicados o en proceso de publicación. Para ver la comparación completa del producto con un BaaS de la competencia, consulte nuestra comparación entre Aurabase y Supabase.

Lo esencial

  • Carga de espacio de trabajo único: 18 cajas (11 servicios empresariales, la CLI aura, 5 bibliotecas compartidas, el SDK de Rust) compiladas juntas por un único cargo build --workspace.
  • El código comercial pesa aproximadamente 274.000 líneas de Rust (medidas mediante find + wc -l, 23 de agosto de 2026), distribuidas en estas 18 cajas.
  • La puerta de enlace (aura-gateway) separa dos planos: datos (SDK, puerto 8080) y administración (Studio, puerto 8090), cada uno con su propia pila de middleware y autenticación.
  • Aurabase no reescribe PostgREST: el binario ascendente real (v12.2.8) se ejecuta por inquilino, orquestado por los servicios de Rust; el valor agregado está alrededor de él, no en su lugar.
  • La única desviación notable del Rust puro: el tiempo de ejecución predeterminado de Edge Functions (mododeno) es un servicio TypeScript dedicado basado en V8 Isolates; Existe una segunda ruta, nativa y en Rust a través de Wasmtime, para el modo wasm.
18
CAJAS PARA EL ESPACIO DE TRABAJO
11 servicios + CLI + 5 bibliotecas + Rust SDK
~274k
LÍNEAS DE ÓXIDO
buscar + wc -l, 23 de agosto de 2026
2
PLANES DE ENTRADA
datos: 8080 · gestión: 8090
10/11
SERVICIOS EN NATS
async-nats en dependencia directa
#
Posicionamiento

Lo que diferencia a Aurabase de un BaaS ensamblado servicio por servicio

La mayoría de Postgres BaaS de código abierto empaquetan sus servicios en varios idiomas. Esto no es un juicio de valor, es un hecho arquitectónico que tiene consecuencias concretas: tantas cadenas de compilación, convenciones de error y lógicas de autenticación para mantener en sincronización como lenguajes en juego.

En Aurabase, la capa de producto que escribimos y mantenemos nosotros mismos (puerta de enlace, autenticación, base de datos, tiempo real, almacenamiento, notificaciones, inteligencia artificial, aprovisionamiento, gestión de cuentas) es un único espacio de trabajo de Cargo, un único lenguaje, una única cadena de construcción. Esta es la elección que documenta este archivo.

Precisión necesaria

“Núcleo unificado” no significa que todo lo que se ejecuta en producción sea Rust. Como cualquier Postgres BaaS, Aurabase también se basa en bloques de construcción de código abierto que no escribió: el propio PostgreSQL, PostgREST, NATS. La diferencia estructural con una pila heterogénea no se relaciona con estos componentes básicos compartidos, sino con la capa de producto que los orquesta. Las siguientes secciones detallan dónde pasa exactamente este límite, incluida la única excepción real que encontramos al auditar el código (Edge Functions, sección 09).

#
El espacio de trabajo

18 cajas, una cadena de compilación.

La raíz Cargo.toml declara un espacio de trabajo de carga en resolutor v2 con 18 miembros: 11 servicios empresariales, la CLI aura-cli, 5 bibliotecas compartidas y el SDK aurabase-rs. Aquí está la lista real, tal como aparece en el repositorio.

Cargo.tomltoml
[workspace]
resolver = "2"

members = [
    # Servicios (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",
    # Herramientas
    "aura-cli",
    # Bibliotecas (5)
    "libs/aura-core", "libs/aura-crypto", "libs/aura-db-adapters",
    "libs/aura-migrations", "libs/aura-telemetry",
    "aurabase-rs",
]

Las dependencias compartidas viven en [workspace.dependencies]: Axum 0.8 (con WebSockets, multipart, macros), Tokio, Tower/Tower-HTTP, SQLx 0.8 (Postgres + MongoDB vía mongodb para motor NoSQL secundario), async-nats 0.47, sqlparser 0.53 (validación SQL de NL2SQL), oauth2 5, jsonwebtoken 10 y dos bibliotecas de rendimiento que se encuentran en casi todos los servicios: mimalloc como asignador global y moka/dashmap para el caché en memoria.

El perfil de versión documenta una elección supuesta: panic = "unwind" en lugar de "abort". El comentario del archivo se explica por sí mismo: el tiempo de ejecución aísla un pánico en un controlador de Axum/Tokio (la solicitud afectada devuelve 500) en lugar de detener todo el proceso y cortar las solicitudes competidoras. La ganancia de rendimiento deabort (aproximadamente 1 a 2% de RPS) no compensa la pérdida de aislamiento, según esta misma nota. Esta es una compensación entre confiabilidad y velocidad documentada en el código, no una afirmación de marketing.

Un solo cargo build --workspace compila todo. Un solo cargo test --workspace ejecuta todo el conjunto de pruebas. Un solo cargo clippy --workspace --all-targets -- -D warnings une todo el producto con las mismas reglas. Los detalles de esta estructura (herencia de dependencias, gráfico interno entre bibliotecas y servicios, dificultades que encontramos al desarrollarla) son el tema de un artículo dedicado: Arquitectura del espacio de trabajo de carga, cómo estructurar un backend Rust multiservicio.

Líneas de óxido por servicio (busque servicios -nombre '*.rs' | xargs wc -l, 23 de agosto de 2026):

control del aura

36 024

aura-db

30 255

autenticación de aura

28 431

proveedor de aura

28 271

notificaciones-de-aura

18 498

tendrá

18 305

puerta de entrada del aura

16 938

aura-en tiempo real

16 799

almacenamiento de aura

13 747

funciones-del-aura

11 619

migrador de aura

538

Excluyendo bibliotecas compartidas (aura-db-adapters: 24,725 líneas, aura-core: 7,259, aura-migrations: 3,641, aura-crypto: 2,718, aura-telemetry: 201), la CLI (aura-cli: 9,845) y el SDK de Rust (aurabase-rs: 6,363). aura-migrator, un trabajo de migración de un solo uso y no un servidor HTTP de larga duración, sigue siendo deliberadamente el servicio más pequeño en el espacio de trabajo.

#
Servicios

11 servicios empresariales, cada uno de ellos un servidor Axum independiente

Cada servicio es un binario Axum/Tokio independiente, con su propia configuración y puerto. Diez de los once exponen /health y /metrics y declaran mimalloc como asignador global; la única excepción, aura-migrator, es un trabajo de propósito único en lugar de un servidor en ejecución continua.

puerta de entrada del auraPuerta de enlace de doble plano (datos:8080, gestión:8090): proxy para todos los demás servicios.
autenticación de auraAutenticación: JWT, 15 proveedores OAuth nombrados + OIDC genérico por proyecto, sesiones, MFA.
aura-dbAPI de base de datos: gestión/recarga de PostgREST por inquilino, adaptadores de Postgres y MongoDB, CDC.
proveedor de auraCiclo de vida del proyecto: clusters CNPG dedicados o compartidos, roles, PostgREST por inquilino.
aura-en tiempo realWebSocket y SSE, transmisión CDC, presencia entre instancias a través de NATS JetStream KV.
almacenamiento de auraObjetos compatibles con S3 (MinIO), políticas RLS transferibles desde Postgres.
funciones-del-auraFunciones perimetrales: implementación, trabajos, cron, tiempo de ejecución nativo de Wasmtime (consulte la sección 09).
notificaciones-de-auraCorreo electrónico, push, webhooks salientes.
tendráPuerta de enlace NL2SQL, RAG y LLM (OpenAI nativo, Anthropic, Gemini + cualquier punto final compatible con OpenAI).
migrador de auraMotor de migración: fuente única del esquema de retención que se reproduce en cada aprovisionamiento.
control del auraPlan de gestión: cuentas de desarrollador, organizaciones, facturación, Studio API.

La CLI aura (≈ 9800 líneas) se comunica con las mismas API que los SDK: no tiene una ruta privilegiada. La referencia completa para cada servicio se encuentra en la documentación de arquitectura y la referencia CLI .

#
Bibliotecas compartidas

5 cajas que evitan la deriva entre servicios

En una pila políglota, se debe volver a implementar una regla de seguridad (formato de error, protección SSRF, limitación de velocidad) en cada idioma, y casi siempre cambia con el paso de los meses. Aurabase lo codifica una vez, en una biblioteca del espacio de trabajo, y lo consumen todos los servicios involucrados.

núcleo de aura7 259 l.Primitivas compartidas: errores, sobre de respuesta API, reclamos JWT, autenticación interna de servicio a servicio, ayudantes NATS, limitación de velocidad, cliente HTTP protegido SSRF, disyuntor, resolución de inquilinos, medición.
adaptadores-aura-db24 725 l.Característica para adaptar las implementaciones de bases de datos unificadas, Postgres y MongoDB utilizadas por aura-db.
aura-cripto2 718 l.Hashing de contraseñas, generación de tokens, firma/validación JWT, cifrado a nivel de campo.
migraciones-de-aura3 641 l.Motor de migración: fuente única del esquema del inquilino, reproducida por el aprovisionador (no las migraciones/carpetas específicas para cada servicio).
telemetría-aura201 l.Configuración de OpenTelemetry + rastreo, compartida por los 11 servicios.

Consecuencia directa: un parche de seguridad en aura-core (protección SSRF, por ejemplo) se propaga a cada servicio al consumidor en el siguiente cargo build, no a través de cinco parches separados en cinco idiomas.

#
la puerta de entrada

Plan dual: tráfico de SDK frente a tráfico de Studio

aura-gateway separa dos superficies que no tienen los mismos clientes ni el mismo modelo de autenticación. El plano de datos (puerto 8080, variable GATEWAY_PORT) recibe tráfico de SDK/aplicación, autenticado mediante clave API (apikey, X-API-Key o ?apikey=). El plano de administración (puerto 8090, MANAGEMENT_PORT) recibe tráfico de Studio/administrador, autenticado por una consola JWT (Authorization: Bearer).

gateway/routes.rsrust
// Plano de datos: clave 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))

// Plan de gestión: consola JWT
.route("/v1/control/{*path}", any(control_proxy))

Cada plano lleva su propia pila de middleware (identificación de consultas, registro de acceso, límite de velocidad, autenticación (específica del plano), disyuntor y luego proxy) implementado en módulos separados (middleware/rate_limit.rs, middleware/circuit_breaker.rs, middleware/auth_data_plane.rs, middleware/auth_management_plane.rs) en lugar de una única cadena compartida accidentalmente entre dos superficies que no deberían confiar entre sí de la misma manera. forma.

El orden exacto de los middlewares, la limitación de velocidad por objetivo y el proxy NATS/HTTP son el tema de un artículo dedicado: puerta de enlace de doble plano, diseño de una puerta de enlace API de plano de datos/plano de administración en Rust.

#
los datos

Por qué Aurabase no reimplementa PostgREST en Rust

La API REST autogenerada que consume el SDK no es un módulo interno de Rust: es el binario ascendente real PostgREST (postgrest/postgrest:v12.2.8), implementado en 2 réplicas por proyecto dedicado (deploy/cnpg/tenant-postgrest.yaml), ubicado junto con la instancia CNPG del inquilino. aura-provisioner crea esta implementación y aura-db prueba su punto final OPTIONS después de cada recarga de esquema para confirmar que PostgREST haya tenido en cuenta el cambio de DDL.

Esta es una elección arquitectónica asumida, no un atajo: PostgREST es un proyecto maduro y ampliamente adoptado, cuyo comportamiento reescribir poco a poco en Rust no aportaría nada. El trabajo de Aurabase en Rust se centra en: enrutamiento multiinquilino, aprovisionamiento, aislamiento de red mediante NetworkPolicy, autenticación compartida con la puerta de enlace, recarga de esquema orquestada, no dentro del motor de consulta en sí. Lo que realmente cubre esta compatibilidad y dónde termina es el tema de un artículo separado: PostgREST, compatibilidad real yalternativas.

La misma lógica en el lado de GraphQL: la extensión de Postgres pg_graphql (paquete .deb precompilado, v1.6.1) se instala en la imagen CNPG dedicada y se activa a pedido por proyecto a través del punto final POST /v1/control/projects/{project_id}/graphql/enable; tampoco es un motor GraphQL reescrito. Detalles y comparación honesta con Hasura y PostGraphile: API GraphQL nativa en Postgres con pg_graphql.

#
Aislamiento

RLS y rol de autenticador, no una capa de aplicación

El aislamiento multiinquilino no depende de un filtro WHERE tenant_id = ? agregado por un ORM de aplicación: cada solicitud pasa por el rol aura_authenticator, que ejecuta una transacción SET LOCAL ROLE tenant_<uuid> con alcance antes de ejecutar la solicitud, exactamente el modelo que PostgREST espera. La seguridad a nivel de fila hace el resto, a nivel del motor, no a nivel del código comercial.

No todos los proyectos comparten la misma topología de Postgres. El código aura-provisioner expone un tipo ProjectInstanceKind con al menos dos variantes reales: FullyDedicated (instancia CNPG completamente dedicada al proyecto) y SharedClusterDedicated (esquema aislado por RLS en un clúster CNPG compartido). El plan suscrito determina la topología; no es una promesa uniforme de una "base dedicada para todos".

Astucia

El ángulo "por qué una base dedicada por proyecto en lugar de un aislamiento puramente de aplicaciones" es el tema de un artículo dedicado: RLS y una base dedicada por proyecto. La documentación Seguridad a nivel de fila cubre la implementación práctica.

#
Mensajería

Núcleo NATS, no JetStream: mensajería asíncrona entre servicios

Diez de los once servicios empresariales declaran async-nats como una dependencia directa en su Cargo.toml; sólo aura-migrator prescinde de él. Lo que el nombre de esta caja no dice: estos servicios en casi todas partes usan lacore pub/sub API de NATS (Client::publish / publish_with_headers, entrega como máximo una vez sin persistencia ni repetición), no JetStream. Este es el caso verificado en el código para los tres usos que más importan: la distribución del CDC de PostgreSQL a aura-realtime, la notificación de trabajos de Edge Functions en aura-functions (el DLQ en sí vive en Postgres, no en NATS) y el aprovisionamiento de eventos entre aura-provisioner y el resto de la flota.

JetStream (modo de persistencia y flujos con nombre de NATS) solo aparece en una ubicación verificada en el monorepo: la presencia entre instancias KV Store en aura-realtime (depósito aura_presence, almacén de memoria, 60 segundos max_age), que sincroniza quién está conectado a qué canal en múltiples instancias de ws-front: un estado compartido entre instancias, no un flujo de eventos para reproducir. No se encontraron transmisiones persistentes de JetStream en ninguna otra parte del espacio de trabajo. Los detalles de la canalización de CDC (wal2json, elección de un cdc-worker único por parte de Lease Kubernetes, distribución central de NATS a las réplicas de ws-front, reverificación de RLS por parte del suscriptor) son el tema de un artículo dedicado: transmitió el CDC de PostgreSQL con NATS. La documentación en tiempo real cubre el uso en el lado del SDK.

#
La excepción aceptada

Edge Functions: dos tiempos de ejecución para dos necesidades

Este es el matiz más importante de este archivo y la única desviación real del Rust puro en el código de producto de Aurabase. Cada función lleva un campo runtime que vale "wasm" o "deno". El controlador de invocación elige la ruta de ejecución en consecuencia: fragmento real, comentado en el propio código:

functions/dispatch.rsrust
// Despacho según tiempo de ejecución: WASM (wasmtime) o Deno (V8 Aisla vía edge-runtime)
let resp = if func.runtime == "wasm" {
    state.runtime.invoke(&wasm_bytes, &func.code_hash, req).await?
} else {
    // Proxy para aura-edge-runtime: aislamientos V8 (supabase/edge-runtime, MIT)
    proxy_to_edge_runtime(&state.config.edge_runtime_url, …).await?
};

El modo wasm es nativo: aura-functions depende directamente de Wasmtime (versión 43, características async y cranelift) y ejecuta el módulo en el mismo proceso Rust, con conteo de combustible, interrupción por época y limitación de memoria a través de StoreLimits. El modo deno, el que se usa de forma predeterminada en el editor Studio, para una compatibilidad casi directa de Deno.serve() con el código Supabase existente, delega la ejecución a aura-edge-runtime, un servicio TypeScript separado de aproximadamente 550 líneas, modelado explícitamente (el comentario del encabezado del archivo fuente lo cita) en supabase/edge-runtime (MIT). licencia), que aísla cada invocación en su propio V8 Isolate.

¿Por qué es honesto decirlo así?

El control (implementación, permisos, trabajos, cron, cuotas) permanece completamente en Rust en aura-functions. Solo la ejecución del código de usuario en modo deno sale del binario de Rust. Este es un compromiso de ingeniería defendible (los aislamientos V8 son lo que Deno proporciona de forma nativa para este nivel de espacio aislado), no una omisión que preferimos mantener en silencio. La comparación de Wasmtime vs Wasmer y el análisis de arranque en frío de WebAssembly, que se publicarán próximamente en este archivo, profundizarán en este tema.

Para obtener el documento instructivo de ambas rutas de implementación, consulte Funciones perimetrales. Para conocer el manual de migración de Deno desde Supabase, consulte Migrar un proyecto de Supabase a Aurabase, que ya documentó esta distinción antes de este archivo.

#
En la practica

Lo que este corazón unificado cambia concretamente para ti

Si simplemente llamas a la API a través de un SDK, esta arquitectura es invisible: ese es el objetivo. Principalmente interesa a tres audiencias: aquellos que evalúan la confiabilidad operativa de un backend multiusuario antes de migrarle datos de producción, aquellos que planean contribuir al repositorio (MIT, monorepo único) y aquellos que quieren entender por qué un parche de seguridad en el lado de Aurabase se propaga rápidamente en lugar de lentamente.

Concretamente: un solo IC (cargo build --workspace, cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings) cubre el 90% o más de la superficie del producto. Una revisión de código en aura-core afecta potencialmente a diez servicios a la vez, para bien (una solución no se pierde en el camino) y para mal (un cambio mal aislado se propaga con la misma rapidez). Es un compromiso, no una solución mágica, y es precisamente por eso que documentamos la arquitectura real en lugar de un resumen de marketing.

#
Centro de carpetas

El resto del archivo de Rust Engineering

Esta página pilar enlaza con los análisis técnicos del clúster, tal como se publican. Estado actual en el momento de la publicación de esta página: los enlaces se activan tan pronto como el artículo correspondiente esté en línea.

Grupo A: marco y arquitectura

Axum vs Actix-web: ¿qué marco para un backend de Rust en producción?Publicado

Arquitectura del espacio de trabajo de carga: cómo estructurar un backend Rust multiservicioPublicado

Puerta de enlace de doble plano: diseño de una puerta de enlace API de plano de datos/plano de administración en RustPublicado

Grupo B: API autogenerada en Postgres

PostgREST: qué cubre realmente la compatibilidad y qué alternativas existenPublicado

API GraphQL nativa en Postgres con pg_graphql: lo que Hasura y PostGraphile no hacen lo mismoPublicado

RLS y base dedicada por proyecto: la elección del aislamiento multiinquilino de AurabasePublicado

Grupo C: mensajería y tiempo real

Distribuir PostgreSQL CDC con NATS: arquitectura en tiempo realPublicado

Grupo D: funciones perimetrales WebAssembly

Wasmtime vs Wasmer: qué tiempo de ejecución de WebAssembly para Edge Functions en producciónPróximamente
Funciones de borde en Rust/WASM versus Cloudflare Workers y Vercel EdgePróximamente
Arranque en frío de WebAssembly: lo que realmente dicen los puntos de referencia (y lo que aún no podemos decir)Próximamente

Grupo E: Migración y alternativas

Migrar un proyecto de Supabase a Aurabase sin reescribir sus políticas RLSPublicado

Autohospedaje soberano: posicionamiento de Aurabase frente a BaaS nativo de RustPróximamente

#
Preguntas frecuentes

Preguntas frecuentes

¿El código de Aurabase es de código abierto?+
El repositorio es un único monorepo: las 18 cajas Rust del espacio de trabajo, los SDK del cliente (JavaScript, Rust, Python, Dart) y Next.js Studio conviven allí, publicados bajo la licencia MIT en GitHub.
¿Aurabase puede ser autohospedado?+
Sí. El banco k3d local (./start.sh) y el gráfico oficial de Helm (deploy/helm/aurabase/) le permiten implementar la pila completa. Aurabase Cloud sigue siendo la opción administrada si prefiere no operar la infraestructura usted mismo.
¿El SDK de JavaScript utiliza la misma sintaxis que Supabase?+
En lo esencial, sí: createClient(), el generador de consultas encadenadas .from().select().eq(), los flujos de autenticación y las políticas RLS apuntan a una compatibilidad casi directa; esto es lo que hace factible una migración de Supabase a Aurabase sin una reescritura completa.
¿Necesitas conocer Rust para usar Aurabase?+
No. Rust es el lenguaje backend, no el que se escribe a diario: los SDK de cliente existen en JavaScript/TypeScript, Rust, Python y Dart, y las funciones Edge se escriben de forma predeterminada en JavaScript/TypeScript (tiempo de ejecución de Deno). Rust solo entra en juego si eliges explícitamente el modo de ejecución WASM nativo.
¿Las funciones de Aurabase Edge realmente se ejecutan en WebAssembly?+
Depende del modo elegido. El modo predeterminado (deno) ejecuta su código JavaScript/TypeScript en V8 Isolates a través de un servicio dedicado, no en un motor WASM. Existe un segundo modo (wasm) que se ejecuta de forma nativa en el servicio Rust aura-functions a través de Wasmtime, pero esta no es la ruta predeterminada.

¿LISTO PARA IMPLEMENTAR?

Tu backend en cinco minutos.

No se requiere tarjeta de crédito · 500 MB gratis · 50,000 MAU