Platform

Architecture

How Trellaris is built, and why it is built that way. The through-line is a single rule: there is one path that runs an agent. Every surface, every trigger, and every integration converges on it, which is what lets one governance decision be authoritative everywhere instead of being re-implemented per feature.

Trellaris deployed: people and clients reach an NGINX ingress with TLS; inside the Kubernetes cluster the web, API, gateway and docs services and the Celery worker and beat all run the one execution path over shared modules; a database with vectors, a distributed cache, object storage and a secret store hold the data and secrets; model providers, connectors, MCP servers and the web are reached only through governed egress; logs and metrics, workload identities, infrastructure as code and Helm support it. PEOPLE AND CLIENTS Browser Next.js web app: chat, build, workspaces, admin Slack · Microsoft Teams channel adapters, same runtime as chat API, MCP and A2A clients scoped API keys, JSON-RPC, signed agent cards Identity providers Google · GitHub · company SSO SCIM provisioning GitHub Actions OIDC login → build images → IaC → Helm upgrade DNS · trellaris.app zone delegated from the registrar; app and api host names Ingress · NGINX TLS from Let's Encrypt via cert-manager; SSE-friendly timeouts, no buffering Container Registry api · web · docs · sandbox images, pinned by digest Kubernetes cluster one autoscaled node pool · workload identity · secrets CSI driver · KEDA · container insights pull images · helm upgrade SERVICE PLANE Web · Next.js session, BFF, proxies /api and /docs to the cluster services API · FastAPI REST + SSE run streams, A2A server, /mcp, webhooks Gateway · MCP one governed MCP endpoint per published tool set Docs · nginx this site; no runtime dependency on the API ASYNC PLANE Worker · Celery queues: runs · scans · ingest; one event loop per process Beat · schedules automations, reaper, retention, rollups, eval sampling, SLOs Jobs · Helm hooks alembic migrations on upgrade; demo-org seed when enabled Sandbox · one per run one hardened Pod per run under gVisor or Kata, on its own pool One execution path every agent, whoever asked: chat, automations, channels, orchestrator, A2A, MCP · one event bus, one ledger, one trace queues via the distributed cache MODULES · ONE CODE BASE FOR API AND WORKER Identity & tenancy Registry Runtime Orchestrator Governance Knowledge Memory Automations Channels Interop · A2A / MCP Tools library & gateway Observe Analytics Evals & promotion Workspaces Avatar Marketplace Compliance Audit Incidents OUTSIDE THE BOUNDARY Model providers Anthropic · Gemini · OpenAI · OpenAI-compatible; embeddings; auto-routing and failover Connectors Google Workspace, ServiceNow, Jira and more; the agent acts as the person, never shared MCP servers · A2A agents registered in the library, tool surfaces reviewed, cards signed and verified The web web_search, web_fetch, browser_use behind a default-deny egress policy GOVERNED EGRESS DLP both ways · allow-lists · approvals budgets · injection screen · audit data perimeter · breakers · incidents DATA SERVICES Database · RDBMS + vector Relational DB + Vector DB, one store: every durable row and embedding Distributed cache Distributed cache: event streams, queues, rate limits, policy cache, locks Object storage artifacts, skill bundles, uploaded documents; presigned downloads Secret store every secret; synced into pods by the CSI driver, never in Helm values PLATFORM SERVICES Logs · metrics · traces container logs, OTel GenAI spans, metrics; any OTLP backend Workload identities pods hold no credentials; deployer federated to GitHub OIDC Infrastructure as code the entire environment from one command; staging and prod Helm chart · per-cloud values one chart, three tiers; a cloud values file wires secrets and hosts Region one region per environment; private endpoints for data services Scale start at two nodes; the node pool, workers and cache tier each grow independently
Trellaris deployed, on any Kubernetes. Colour marks the plane: clients, edge, services, async work, the execution path and its modules, data, secrets, platform services, and everything outside the boundary that is reached only through governed egress. Every box is live, including the sandbox: one hardened pod per run, reached through the API server.

The rules the code obeys

RuleWhat it buys
One execution path Chat, automations, channels, the orchestrator, A2A and MCP all call the same executor. One event bus, one usage ledger, one set of governance checks — no surface can drift into a second set of semantics.
Tenancy is not optional Every repository extends a base that force-injects the organization filter and the visibility predicate. There is no raw database access outside a repository, so a query cannot return another tenant's row.
Strict layering Router handles HTTP, service holds business logic, repository owns all data access. No logic in routers, no queries outside repositories.
Modules talk through services A module never reads another module's tables or imports its models. Cross-module references are a UUID plus a service call, so a module can be reasoned about — and changed — on its own.
Dependency inversion at every seam Model providers, storage, the sandbox, policy providers, tool discovery, identity — each sits behind an interface with a deterministic default. Swapping a real backend in is configuration, not a rewrite, and CI can run without any of them.
One error contract Every failure is a problem document with a stable machine-readable code — including terminal events on a stream — so clients handle errors identically wherever they arise.
Immutability where it matters Agent versions, skill versions, and canvas revisions are immutable with a pointer to the current one. Rollback moves a pointer; nothing is mutated or lost.

How the pieces fit together

The functional picture: what an agent is made of, what it is granted, where requests come from, and what a run leaves behind.

Functional composition: surfaces enter through governance into the agent, which is granted tools and attaches skills, knowledge and memory, and produces a run record Organization · workspace · ring — everything inside is tenancy-scoped Chat Canvas Voice Slack · Teams Automations API · MCP · A2A Governance policy engine · DLP · allowlists · approvals · budgets · injection screen · data perimeter · breakers · audit Skills playbooks, loaded on demand Knowledge labelled · cited retrieval Memory durable user / agent facts Agent Agent.md identity · tool grant policy boundary Built-in tools web · code · media · utilities Connectors delegated OAuth, as the user MCP servers Tools Library · gateway Run record events · messages · artifacts · taint usage ledger · trace · audit trail A skill may only use tools the agent already grants — it packages procedure, never access. A connector is a tool that carries the user's own identity. An MCP server is a tool surface resolved through the library. Platform services Relational DB + Vector DB · distributed-cache streams · object storage · ephemeral sandbox · the LLM gateway Reached only through interfaces — a router never touches them directly.
Functional composition. Requests enter from any surface, pass governance, and reach the agent — the one entity that carries identity, holds the tool grant, and forms the policy boundary.

Reading the diagram

What happens on every run

The same six steps regardless of what triggered the work. The right-hand column is where governance actually lands — each check is at a specific point, not a general aspiration.

The six steps of a run, from trigger to persistence, with the governance check enforced at each step Execution Enforced at that step 1 · Trigger chat · schedule · webhook · channel · A2A · MCP Plan gates on automation create · webhook signature verification and rate limit · scoped API key 2 · Run created queued, then leased by a worker Emergency stop · agent paused (by an admin, or by a breaker that tripped on its own signals) or killed · budget hard stop, all refused before a run row exists 3 · Assemble tool registry + system prompt for this run Tool allowlist — a denied MCP server is hidden, not failed · autonomy = min(declared, org floor) · every labelled read raises the run's taint; a chunk above the provider limit is withheld 4 · Model turn streamed through the LLM gateway DLP on input · model allowlist · tokens and cost metered · auto-routing with cross-provider failover 5 · Tool call executed, then fed back to the model Data perimeter on the run's taint, per channel: redact, park, refuse · writes park for approval · DLP on arguments and results · gateway rate limit and budget · injection screen · breaker signals counted 6 · Deliver and persist the answer, its artifacts, and the record DLP on output · taint on the run · events, messages, artifacts, usage ledger, trace and audit, all replayable afterwards · a breaker trip or a refused Restricted read opens an incident next turn
Steps 4 and 5 loop until the agent has an answer or hits its turn cap. A parked approval, including one the data perimeter asked for, suspends the loop here with its state saved and resumes it on a decision. A breaker never acts inside the run that produced the signal; it trips in a separate task.

What the loop actually does

  1. Assembly is per run, not per agent. The tool registry is rebuilt every time from the declaration plus configuration, so a policy change or a revoked credential takes effect on the next run without touching the definition.
  2. The system prompt is composed from the guardrail preamble, the agent body, a compact skill index, and injected context — memories, knowledge citation rules, attached documents, and a canvas diff if the human edited past the agent.
  3. The model turn streams. Tokens, tool calls, and status land on the run's event stream as they happen, so the interface is live and the same sequence can be replayed later.
  4. Tool results are treated as data. They are screened before re-entering the model — this is where a prompt-injection attempt planted in a fetched page is caught — and a labelled result raises the run's taint, which the data perimeter reads before the next outbound call.
  5. Parking is real suspension. Loop state is serialized to the run row; the worker is released. Approving reconstructs the loop and executes the call exactly once.
  6. Nothing is left hanging. Workers hold a heartbeat lease. If one dies, a reaper resolves the run — resuming a background run from its last checkpoint, or failing it with a reason.

Deployment topology

Four planes and one ingress. Each service scales independently, and the documentation site you are reading is its own container with no runtime dependency on the API.

Deployment topology: clients reach an ingress that fronts the service plane, which uses an async plane, a data plane, and governed egress to external systems Clients Browser Slack · Teams MCP & A2A clients IdP · SCIM directory TLS ingress — / → web · /api → api · /docs → docs · /gateways → gateway Service plane Web Next.js · BFF proxy API FastAPI · the executor Gateway external MCP face Docs nginx · this site Async plane Worker Celery — runs · scans · ingest Beat dispatch · sweeps · rollups Sandbox ephemeral, network-less Data plane Database + Vector DB Distributed cache queues · run streams Object storage S3 · MinIO · Azure Blob Keycloak IdP broker External — governed egress Model providers via the LLM gateway MCP servers via the Tools Library SaaS systems via connectors, as the user A2A peers signed agent cards
Outbound traffic originates from the API, the worker, and the gateway. The sandbox has no network at all, so nothing a model writes can call out from inside it.

What each plane is responsible for

PlaneContainsScales on
ServiceThe Next.js web app (which also proxies /api and /docs in development), the FastAPI application, the MCP gateway as its own deployment, and this documentation container.Request volume; the gateway independently, since it is the external face.
AsyncCelery workers on per-class queues — runs, scans, ingest — plus the beat scheduler for dispatch, sweeps, and rollups, and one ephemeral sandbox container per code execution.Run volume and scan/ingest backlog.
DataA relational database with a vector store for rows and embeddings alike, a distributed cache for queues and per-run event streams, object storage for documents and artifacts, Keycloak as the identity broker.Managed externally at the team and enterprise tiers.
ExternalModel providers, MCP servers, SaaS systems reached through connectors, and A2A peers.—
Why the sandbox is a separate concern Code the model wrote runs in a throwaway container with no network, a non-root user, dropped capabilities, capped memory, CPU, process count and wall clock, and no package managers installed. Files move in and out as archives rather than host mounts. In development that container is a child of the local Docker daemon; in production a Kubernetes driver runs each execution as its own hardened Pod — read-only root, no service-account token, deny-all network policy — on a tainted node pool, under gVisor or Kata Containers. Nothing above the driver changes between the two. See Secure code execution.

Module map

The API is one deployable but fifteen owned boundaries. Each module owns its tables and exposes a service; nothing reaches across. The worker runs the same code base, so a module is a module in both processes.

ModuleOwnsCode
Identity & tenancyOrganizations, teams, users, API keys, SCIM, login hooks, line managers for approval routing, the sign-in log, the ADR-001 visibility primitive and the ring/default workspaces it filters onidentity/
WorkspacesNamed workspaces and membership, the board, the shared memory pool, activity, stage-gated processes, blueprints, settings and agent instructions, document templates, and Word/PowerPoint/Excel generationworkspace/ (membership rows and the crossing live with identity/ and promotion/)
Registry & definitionsAgents, skills, versions, validation, the catalog, @handles, built-in skills, the template packregistry/
Marketplace, evals & promotionScanning, evaluation sets and runs, continuous sampling, the promotion pipeline (agents and whole workspaces), reviews, packsmarketplace/ · evals/ · promotion/
Runtime & executionThe one executor, LLM gateway, sandbox, DLP, memory, approvals, the run's taint and the perimeter gate, background runs, fan-out, charts, the keyless market and weather toolsruntime/
KnowledgeCollections, ingestion, chunk search with source ACLs, classification labels on collections, documents and chunks (with the map for synced sensitivity labels), citations, the sync connectors (Confluence, Google Drive, Gmail, Google Calendar, Outlook, Teams)knowledge/
Avatar & knowledge graphOne avatar per user: profile, configuration and its versions, consents, activity, the owner-scoped reads, and the personal knowledge graph (nodes, edges, proposals, extraction, recall)avatar/ · avatar/graph/
Interop & adaptersA2A server and client, the MCP server, A2UI surfaces, connectors, delegated credentials, secrets, the Tools Library, the MCP gatewayinterop/ · connectors/ · credentials/ · secrets/ · tools_library/ · gateway/
Conversations & channelsThreads and the surface each belongs to (chat, workspace, document, research), messages, the Slack and Teams adapters, canvas documents and their images, voice sessionsconversations/
Automation & notificationsCron, webhook, watch, email-in and wake-up triggers, the dispatcher, delivery, the inboxautomation/ · notifications/
OrchestratorThe supervisor graph, capability-filtered routing, checkpoints, the durable task treeorchestrator/
Built-in agents & authoringThe Assistant, Architect, ITHelp, IT Fulfilment, Travel Desk, Market Watcher, Weather, Document Author, the four Knowledge Agents and their corpus; Deep Research and its research engine (plan approval, parallel researchers, the evidence store, verification); per-org seeding on login; skill proposals; the Playgroundassistant/ · architect/ · research/ · ithelp/ · it_fulfilment/ · travel_desk/ · markets/ · weather_agent/ · doc_author/ · knowledge_agents/ · onboarding/ · workshop/ · playground/
Governance & adminThe policy engine with floors, DLP simulation, the classification vocabulary and the data perimeter, breakers, incidents and their containment actions, kill switches, audit, legal holds, privacy tiers, risk, compliance, blueprintsgovernance/ · incidents/ · admin/ · audit/ · risk/ · compliance/
Analytics & observabilityRollups, dashboards, budgets, SLOs, showback, the opportunity miner; the durable run trace behind Observe, with each run's taintanalytics/ · observability/
PlatformDatabase session and base repository, migrations, crypto, object storage drivers, cache, telemetry, the worker's event loopplatform/ · workers/

Data model highlights

StructureWhy it is shaped that way
Immutable versions + a current pointerRollback is a pointer move, promotion can copy and freeze a known-good version, and a diff between any two versions is always available.
A run state machineA transition table is the single gate on every status write, so parked, resumed, reaped and cancelled runs can never reach an undefined state.
A per-run event streamOne append-only sequence serves live streaming, the task tree, and later replay — the interface and the audit view read the same data.
Message partsA message is a list of typed parts (text, tool call, artifact update, data card), so approval prompts, connect cards, canvas updates, and citations all persist without schema churn.
A usage ledgerOne row per run, including delegated children and remote invocations, so a cost figure is derived from records rather than estimated.
Policies as rowsKind, scope, and config in one table read by one engine — governance is data, editable at runtime, not code that needs a release.
A label column everywhere, a taint on the runEvery content row carries its classification, so the label comes back with the chunk in the same read; the run keeps the highest label it has seen, so the decision about what may leave is a comparison, not a search. See Data classification.
One open incident per agent and kindA partial unique index makes a second trigger append to the open incident rather than open a twin, so the record of what happened and what was done stays in one place.
Embeddings alongside rowsThe vector store keeps semantic search in the same database and the same transaction as the visibility filter, so search can never leak what a query would not return.

Extension seams

Every external dependency sits behind an interface with a deterministic default, which is why the whole test suite runs with no cloud account and no model provider.

SeamDefaultProduction swap
LLM driverScripted fakeAnthropic, OpenAI/Azure, Google
EmbeddingsDeterministic feature-hashedA provider embedding model
Object storageMinIOS3 or Azure Blob
Sandbox driverDocker, or disabledKubernetes: one hardened Pod per run, under gVisor or Kata
Policy providersAllow-all stubsThe database-backed engine
MCP tool discoveryInjected inventoryA live MCP connection
Agent identity providerPlatform-signed tokensDirectory service accounts
A2A card verifierShared-secretReal signature verification
Injection detectorPattern matcherA trained classifier
Policy lintDeterministic backendA model-backed reviewer
Voice realtimeFake driverA realtime speech provider
Browser driverMockHeadless Chromium
Breaker trip dispatcherIn-process, on its own sessionA worker task, so a trip never runs inside the run that produced the signal
Source sensitivity labelsUnmapped labels land as Confidential with a warningA per-organisation map from Drive or Microsoft 365 labels
Knowledge connectorsMock servicesConfluence, Google Drive tenants
Channel adaptersMock transportsSlack, Bot Framework

Tech stack

LayerChoice
APIPython 3.12 · FastAPI · Pydantic v2 · SQLAlchemy 2 (async) · Alembic
Async workCelery 5 with per-class queues, plus a beat scheduler
DatabaseA relational database with a vector extension — every durable row, every embedding, and the avatar knowledge graph (typed nodes and edges as ordinary tables; no graph database)
Cache, queue & streamsA distributed cache (an in-cluster engine locally, a managed cache in the cloud) — Celery queues, run event streams, rate limits, the policy cache, locks
Object storageS3-compatible (MinIO locally) or Azure Blob, behind one driver interface; presigned downloads
SecretsEnvelope encryption (AES-256-GCM) in the secrets table for tokens and BYO keys; a cloud secret store synced into pods by the secrets CSI driver
IdentityKeycloak as the IdP broker · Auth.js in the web app · platform-issued JWTs for people and per-agent identities
Model providersAnthropic · OpenAI-compatible (OpenAI, Azure OpenAI) · Google Gemini, behind one gateway with tiers, auto-routing and failover; a scripted fake in CI
OrchestrationLangGraph with a database checkpointer — the orchestrator's supervisor graph and the research engine
WebNext.js 15 · React 19 · TypeScript · Tailwind CSS · shadcn/ui · Monaco · Apache ECharts
Interactive surfacesA2UI v0.9 declarative blueprints, validated against a trusted catalog; charts as full ECharts options validated at one boundary
VoiceThe browser's own SpeechRecognition and speechSynthesis — no audio reaches the platform; org switches to turn either off
Docs siteStatic HTML served by nginx — no build step, no runtime dependencies
SandboxOne isolated workload per run on python3.12 + Node 20, no network, no package managers — a child container in development, a hardened pod (gVisor or Kata) in production; secure code execution
ObservabilityOpenTelemetry (GenAI semantic conventions) · Prometheus · structlog · a durable per-run trace in the database behind Observe
Packaging & deployDocker (multi-stage, production stage by default) · Helm (starter, team, enterprise and cloud value sets) · GitHub Actions · infrastructure as code for the cloud environment
Quality gatesruff · mypy --strict · pytest · ESLint · Prettier · Playwright · a license allowlist

Open-source packages

Everything Trellaris depends on is OSI open source, and CI enforces an allowlist on every build so a proprietary transitive dependency fails the pipeline rather than shipping. Licenses below are as published by each project; the build's own check is the authoritative gate.

API — runtime

PackageLicenseUsed for
fastapiMITThe HTTP application and OpenAPI schema
uvicorn[standard]BSD-3-ClauseASGI server
pydantic, pydantic-settingsMITSchemas, validation, typed configuration
sqlalchemy[asyncio]MITORM and query construction
alembicMITDatabase migrations
asyncpgApache-2.0Async PostgreSQL driver
pgvectorMITVector column and index support
celeryBSD-3-ClauseBackground workers and the beat scheduler
redisMITQueues, run event streams, rate limits, semaphores
httpxBSD-3-ClauseAll outbound HTTP — connectors, A2A, MCP over SSE
sse-starletteBSD-3-ClauseServer-sent events for run streaming
tenacityApache-2.0Retries with jittered backoff
structlogMIT or Apache-2.0Structured logging
python-json-loggerBSD-2-ClauseJSON log formatting
prometheus-clientApache-2.0Metrics endpoint
opentelemetry-sdk, -exporter-otlp, -instrumentation-fastapiApache-2.0Tracing with GenAI semantic conventions
boto3Apache-2.0S3-compatible object storage
azure-storage-blob, azure-identityMITAzure Blob object storage, signed with a workload identity rather than a stored key
pyjwt[crypto]MITPlatform JWTs and IdP token verification
email-validatorCC0-1.0Email address validation
dnspythonISCDNS TXT lookups for domain capture
python-multipartApache-2.0Multipart uploads for skill bundles and documents
pip-auditApache-2.0The dependency-audit scan stage
anthropicMITAnthropic model driver
openaiApache-2.0OpenAI and Azure OpenAI driver, embeddings
google-genaiApache-2.0Google Gemini driver
dockerApache-2.0Sandbox driver in development — ephemeral containers
kubernetesApache-2.0Sandbox driver in production — one hardened Pod per run
playwrightApache-2.0The real browser engine behind browser_use (worker image only)
mcpMITMCP client and server
croniterMITCron validation and DST-safe next-run computation
pypdfBSD-3-ClausePDF text extraction for knowledge ingestion
python-docxMITDOCX text extraction and Word generation
python-pptxMITPowerPoint generation, slide previews and reopening a deck for editing
openpyxlMITExcel generation
trafilaturaApache-2.0A web page's main text, title and date for web_fetch
maxminddbApache-2.0Reads the local IP-location database for the sign-in log
jsonschemaMITEvaluation assertions and approval-edit validation
qrcodeBSD-3-ClauseThe qr_code tool
langgraphMITThe orchestrator's supervisor graph and the research engine
langgraph-checkpoint-postgresMITDurable graph checkpoints
psycopg[binary]LGPL-3.0Driver for the checkpointer
hatchlingMITBuild backend

Agent-format package

PackageLicenseUsed for
pydanticMITFrontmatter schema and validation
python-frontmatterMITSplitting YAML frontmatter from the markdown body
pyyamlMITYAML parsing

API — development and CI

PackageLicenseUsed for
pytest, pytest-asyncioMIT · Apache-2.0Test runner and async support
anyioMITAsync test utilities
moto[s3]Apache-2.0Mock S3 for storage tests
respxBSD-3-Clausehttpx request mocking
ruffMITLinting and formatting
mypyMITStrict static typing
pip-licensesMITThe CI license allowlist gate
boto3-stubs[s3]MITType stubs

Web application

PackageLicenseUsed for
nextMITThe application framework and BFF proxy
react, react-domMITUI runtime
next-auth (Auth.js)ISCSign-in, session handling, the assertion exchange
next-themesMITLight and dark theming
@monaco-editor/reactMITThe definition editor
@radix-ui/react-slotMITComposable component primitives
class-variance-authorityApache-2.0Component variant styling
clsx, tailwind-mergeMITClass-name composition
lucide-reactISCIcons
react-markdown, remark-gfmMITRendering agent responses, with citation pills for knowledge chunks
echarts, echarts-for-reactApache-2.0 · MITCharts in chat — the agent's ECharts option, drawn theme-aware with full screen, PNG export and click-a-point
simple-iconsCC0-1.0Brand marks on connector and source cards
mermaidMITDiagrams in documents and chat
tailwindcss, tailwindcss-animateMITStyling system
shadcn/uiMITComponent source vendored into the app

Web — development and CI

PackageLicenseUsed for
typescriptApache-2.0Type checking
eslint, eslint-config-nextMITLinting
prettier, prettier-plugin-tailwindcssMITFormatting
postcss, autoprefixerMITCSS pipeline
@playwright/testApache-2.0End-to-end golden-path tests
@types/*MITType definitions

Security scanners

Pinned binaries baked into the API and worker image, each reporting its own stage.

ToolLicenseStage
OpengrepLGPL-2.1Static analysis, against Trellaris-authored OWASP LLM Top 10 rules
gitleaksMITSecret detection in skill bundles
TrivyApache-2.0Optional container and npm dependency audit
pip-auditApache-2.0Python dependency CVE audit
Why Opengrep and not Semgrep The Semgrep engine is open source, but its community rule registry moved to a source-available license with commercial-use restrictions. Trellaris uses the LGPL fork with its own rule set, so the whole scanning path stays OSI open source.

Sandbox image

Preinstalled so sandboxed scripts start fast and work entirely offline — the container has no network, so nothing can be installed at run time.

PackageLicense
numpy, pandasBSD-3-Clause
matplotlibPSF-based (Matplotlib licence)
pillowMIT-CMU (HPND)
python-dateutilApache-2.0 and BSD-3-Clause
requestsApache-2.0
beautifulsoup4MIT
reportlabBSD-3-Clause
fpdf2LGPL-3.0
pypdfBSD-3-Clause
python-docx, python-pptx, openpyxlMIT

Infrastructure

ComponentLicenseRole
PostgreSQLPostgreSQL LicencePrimary datastore
pgvectorPostgreSQL LicenceEmbedding storage and similarity search
ValkeyBSD-3-ClauseQueues, run streams, rate limits — chosen over Redis to keep the stack permissive
MinIOAGPL-3.0Local S3-compatible storage; run unmodified as a service, and replaceable with S3, Azure Blob, or an Apache-2.0 alternative
AzuriteMITLocal Azure Blob emulator
DB-IP City LiteCC BY 4.0IP-to-location data for the sign-in log, read locally — never sent to a lookup service
KeycloakApache-2.0Identity broker for enterprise SSO
nginxBSD-2-ClauseServes this documentation site
DockerApache-2.0Images and the sandbox runtime
HelmApache-2.0Kubernetes packaging
KubernetesApache-2.0The deployment target; one chart, one cluster per environment
ingress-nginx · cert-managerApache-2.0The ingress with SSE-friendly timeouts, and TLS certificates from Let's Encrypt
KEDAApache-2.0Installed as a cluster add-on for queue-depth worker scaling; the chart ships no scaler object yet
PlaywrightApache-2.0The browser image the end-to-end tests and the docs screenshots run in
gVisor · Kata ContainersApache-2.0Optional hardened sandbox runtime classes