Show HN: Nenya – A lightweight, highly secure AI API Gateway/Proxy written in Go A new open-source AI API gateway called Nenya, written in Go, provides a lightweight, zero-dependency proxy that sits between AI coding clients and upstream large language model providers. The gateway adds security features including secret redaction, context management, agent routing, and MCP tool integration with transparent SSE streaming, while enforcing non-root execution, mlock for secrets, and seccomp with no-new-privileges. Nenya supports any provider implementing OpenAI or Anthropic Chat Completions APIs, ships with 23 built-in adapters, and offers config-driven provider registration without code changes. A lightweight, zero-dependency AI API Gateway written in Go. Nenya sits between your AI coding clients and upstream LLM providers, adding secret redaction, context management, agent routing, and MCP tool integration — all with transparent SSE streaming. Security-hardened: non-root execution, mlock for secrets, seccomp + no-new-privileges. Compatible with any provider that implements the OpenAI Or Anthropic Chat Completions API. For 23 providers we ship built-in adapters with specialized handling. +----------------------------------------------+ | Client Cursor / OpenCode / Aider / etc. | | OpenAI-compatible request | | POST /v1/chat/completions + Bearer token | | or | | Anthropic Messages API request | | POST /v1/messages + x-api-key | +----------------------------------------------+ | v +----------------------------------------------+ | Nenya Gateway | | - auth check + RBAC enforcement | | - parse JSON + extract model | | - resolve agent/provider | | - optional cache HIT = replay SSE | | - optional MCP context/tool injection | +----------------------------------------------+ | v +----------------------------------------------+ | Interceptor Chain pluggable, best-effort | | - RedactInterceptor regex patterns | | - EntropyInterceptor high-entropy strings | | - TFIDFInterceptor relevance scoring | | - BouncerInterceptor engine summarization | +----------------------------------------------+ | v +----------------------------------------------+ | Token Budget Trimming if payload hard | | limit drops oldest non-system messages and | | applies token-aware middle-out truncation | +----------------------------------------------+ | v +----------------------------------------------+ | Routing | | A Standard forwarding | | - fallback chain + circuit breaker + RL | | B MCP multi-turn tool loop if enabled | | - buffer SSE, execute MCP tools, re-send | | C Context-limit retry | | - on upstream 413/context exceeded, | | summarize payload, retry with fallback | +----------------------------------------------+ | v +----------------------------------------------+ | Upstream LLM Providers | | Anthropic | Gemini | DeepSeek | Mistral | ...| +----------------------------------------------+ | | SSE stream v +----------------------------------------------+ | Nenya SSE Pipeline | | - adapter response transforms | | - optional OpenAI→Anthropic conversion | | - usage accounting + stream filter | | - flush + optional cache capture | | - optional MCP auto-save | +----------------------------------------------+ | v +----------------------------------------------+ | Client receives transparent SSE output | +----------------------------------------------+ Flow notes: /v1/ endpoints require client bearer auth; /healthz , /statsz , /metrics do not.- Pipeline failures degrade gracefully and forward the request instead of returning a 500. - MCP-enabled agents can run local/remote tools without exposing MCP complexity to the client. Config-driven provider registry — add providers via JSON, zero code changes 23 built-in providers with specialized adapters for wire format differences Dynamic model discovery — fetches live model catalogs from providers at startup and on reload Model registry — reference models by string shorthand with automatic provider/context resolution Multi-provider model resolution — when a model exists in multiple providers, all are added to the agent's fallback chain Three-tier model resolution — config overrides discovered models static registry Per-model wire format — models from multi-format gateways OpenCode Zen auto-convert between OpenAI, Anthropic, and Gemini wire formats based on the model's format attribute Agent fallback chains — round-robin or sequential with circuit breaker and automatic failover Latency-aware routing — auto-reorder targets by historical median response time with ±5% jitter to prevent thundering herd Per-agent system prompts — inline or file-based Tier-0 regex secret filter — always-on redaction of AWS keys, GitHub tokens, passwords, etc. 3-Tier content pipeline — pluggable interceptor chain: regex redaction, entropy filtering, TF-IDF relevance scoring, engine summarization Context window compaction — sliding window summarization with configurable engine Stale tool call pruning — compact old assistant+tool response pairs to save tokens Thought pruning — strip reasoning blocks from assistant message history Input validation — strict body limits, JSON sanitization, header filtering Graceful degradation — never blocks requests due to engine or pipeline failures Role-Based Access Control RBAC — per-API key roles admin, user, read-only with agent and endpoint restrictions Secure memory — mlock-protected token storage, read-only sealing, core dump prevention Secure memory default : All tokens stored in mlock-protected RAM, sealed read-only after init, core dumps disabled Non-root execution — runs as UID 65532 with dropped capabilities Memory protection — LimitMEMLOCK=infinity and LimitCORE=0 in systemd Read-only filesystem — immutable root + private /tmp Seccomp + no-new-privileges — restricted syscalls, prevents privilege escalation Zero-trust secrets — loaded via systemd credentials or container mounts, never to disk Socket activation — seamless restarts with zero dropped connections Zero external dependencies — Go standard library only Hot reload — systemctl reload nenya for zero-downtime config changes Circuit breaker — per agent+provider+model with automatic failover, exponential backoff, and semantic error classification Rate limiting — per upstream host RPM/TPM with per-provider overrides Response cache — in-memory LRU with SHA-256 fingerprinting and optional semantic similarity search Graceful shutdown — 5s grace period for in-flight requests, MCP client cleanup Context-limit auto-retry — upstream context-length errors trigger summarization and retry Local engine lifecycle — pre-load and manage local Ollama models with LRU eviction Structured errors — all error responses include error kind field for programmatic diagnostics Tool discovery — connect to MCP servers for automatic tool injection Multi-turn execution — intercept tool calls, execute against MCP servers, forward results Auto-search — pre-fetch relevant context from MCP servers before forwarding Auto-save — persist assistant responses to MCP memory servers Create minimal config and secrets: mkdir -p config secrets cat config/config.json << 'EOF' { "server": { "listen addr": ":8080" }, "agents": { "default": { "strategy": "fallback", "models": "gemini-2.5-flash" } } } EOF cat secrets/provider keys.json << 'EOF' { "provider keys": { "gemini": "AIza..." } } EOF cat secrets/client.json << 'EOF' { "client token": "nk-$ openssl rand -hex 32 " } EOF Run the container: podman run -d \ --name nenya \ -p 8080:8080 \ -v ./config:/etc/nenya:ro \ -v ./secrets:/run/secrets/nenya:ro \ -e NENYA SECRETS DIR=/run/secrets/nenya \ --cap-drop=ALL \ --cap-add=IPC LOCK \ --security-opt=no-new-privileges:true \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid,size=64M \ ghcr.io/gumieri/nenya:latest Test it: curl -H "Authorization: Bearer $ jq -r '.client token' secrets/client.json " \ http://localhost:8080/healthz Nenya provides native packages for major Linux distributions and community package managers: | Distribution | Command | |---|---| Debian/Ubuntu .deb | Download nenya