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 únicocargo 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 (modo
deno) es un servicio TypeScript dedicado basado en V8 Isolates; Existe una segunda ruta, nativa y en Rust a través de Wasmtime, para el modowasm.
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.
“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).
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.
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.
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 aura | Puerta de enlace de doble plano (datos:8080, gestión:8090): proxy para todos los demás servicios. |
|---|---|
| autenticación de aura | Autenticación: JWT, 15 proveedores OAuth nombrados + OIDC genérico por proyecto, sesiones, MFA. |
| aura-db | API de base de datos: gestión/recarga de PostgREST por inquilino, adaptadores de Postgres y MongoDB, CDC. |
| proveedor de aura | Ciclo de vida del proyecto: clusters CNPG dedicados o compartidos, roles, PostgREST por inquilino. |
| aura-en tiempo real | WebSocket y SSE, transmisión CDC, presencia entre instancias a través de NATS JetStream KV. |
| almacenamiento de aura | Objetos compatibles con S3 (MinIO), políticas RLS transferibles desde Postgres. |
| funciones-del-aura | Funciones perimetrales: implementación, trabajos, cron, tiempo de ejecución nativo de Wasmtime (consulte la sección 09). |
| notificaciones-de-aura | Correo 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 aura | Motor de migración: fuente única del esquema de retención que se reproduce en cada aprovisionamiento. |
| control del aura | Plan 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 .
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 aura | 7 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-db | 24 725 l. | Característica para adaptar las implementaciones de bases de datos unificadas, Postgres y MongoDB utilizadas por aura-db. |
| aura-cripto | 2 718 l. | Hashing de contraseñas, generación de tokens, firma/validación JWT, cifrado a nivel de campo. |
| migraciones-de-aura | 3 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-aura | 201 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.
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).
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.
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.
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".
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.
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.
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:
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.
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.
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.
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
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ón | Próximamente |
|---|---|
| Funciones de borde en Rust/WASM versus Cloudflare Workers y Vercel Edge | Pró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