{"slug": "show-hn-nenya-a-lightweight-highly-secure-ai-api-gateway-proxy-written-in-go", "title": "Show HN: Nenya – A lightweight, highly secure AI API Gateway/Proxy written in Go", "summary": "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.", "body_md": "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.\n\n**Compatible with any provider that implements the OpenAI Or Anthropic Chat Completions API.** For 23 providers we ship built-in adapters with specialized handling.\n\n```\n+----------------------------------------------+\n| Client (Cursor / OpenCode / Aider / etc.)    |\n| OpenAI-compatible request                    |\n| POST /v1/chat/completions + Bearer token     |\n| or                                           |\n| Anthropic Messages API request               |\n| POST /v1/messages + x-api-key                |\n+----------------------------------------------+\n                        |\n                        v\n+----------------------------------------------+\n| Nenya Gateway                                |\n| - auth check + RBAC enforcement              |\n| - parse JSON + extract model                 |\n| - resolve agent/provider                     |\n| - optional cache (HIT => replay SSE)         |\n| - optional MCP context/tool injection        |\n+----------------------------------------------+\n                        |\n                        v\n+----------------------------------------------+\n| Interceptor Chain (pluggable, best-effort)   |\n| - RedactInterceptor  (regex patterns)        |\n| - EntropyInterceptor (high-entropy strings)  |\n| - TFIDFInterceptor   (relevance scoring)     |\n| - BouncerInterceptor (engine summarization)  |\n+----------------------------------------------+\n                        |\n                        v\n+----------------------------------------------+\n| Token Budget Trimming (if payload > hard     |\n| limit) drops oldest non-system messages and  |\n| applies token-aware middle-out truncation    |\n+----------------------------------------------+\n                        |\n                        v\n+----------------------------------------------+\n| Routing                                      |\n|  A) Standard forwarding                      |\n|     - fallback chain + circuit breaker + RL  |\n|  B) MCP multi-turn tool loop (if enabled)    |\n|     - buffer SSE, execute MCP tools, re-send |\n|  C) Context-limit retry                      |\n|     - on upstream 413/context_exceeded,      |\n|       summarize payload, retry with fallback |\n+----------------------------------------------+\n                        |\n                        v\n+----------------------------------------------+\n| Upstream LLM Providers                       |\n| Anthropic | Gemini | DeepSeek | Mistral | ...|\n+----------------------------------------------+\n                        |\n                        |  SSE stream\n                        v\n+----------------------------------------------+\n| Nenya SSE Pipeline                           |\n| - adapter response transforms                |\n| - (optional) OpenAI→Anthropic conversion     |\n| - usage accounting + stream filter           |\n| - flush + (optional) cache capture           |\n| - (optional) MCP auto-save                   |\n+----------------------------------------------+\n                        |\n                        v\n+----------------------------------------------+\n| Client receives transparent SSE output       |\n+----------------------------------------------+\n```\n\nFlow notes:\n\n`/v1/*`\n\nendpoints require client bearer auth;`/healthz`\n\n,`/statsz`\n\n,`/metrics`\n\ndo not.- Pipeline failures degrade gracefully and forward the request instead of returning a 500.\n- MCP-enabled agents can run local/remote tools without exposing MCP complexity to the client.\n\n**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`\n\nattribute**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\n\n**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\n\n**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`\n\nand`LimitCORE=0`\n\nin systemd**Read-only filesystem**— immutable root + private`/tmp`\n\n**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\n\n**Zero external dependencies**— Go standard library only** Hot reload**—`systemctl reload nenya`\n\nfor 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`\n\nfield for programmatic diagnostics\n\n**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\n\nCreate minimal config and secrets:\n\n```\nmkdir -p config secrets\ncat > config/config.json << 'EOF'\n{\n  \"server\": { \"listen_addr\": \":8080\" },\n  \"agents\": {\n    \"default\": {\n      \"strategy\": \"fallback\",\n      \"models\": [\"gemini-2.5-flash\"]\n    }\n  }\n}\nEOF\n\ncat > secrets/provider_keys.json << 'EOF'\n{\n  \"provider_keys\": {\n    \"gemini\": \"AIza...\"\n  }\n}\nEOF\n\ncat > secrets/client.json << 'EOF'\n{\n  \"client_token\": \"nk-$(openssl rand -hex 32)\"\n}\nEOF\n```\n\nRun the container:\n\n```\npodman run -d \\\n  --name nenya \\\n  -p 8080:8080 \\\n  -v ./config:/etc/nenya:ro \\\n  -v ./secrets:/run/secrets/nenya:ro \\\n  -e NENYA_SECRETS_DIR=/run/secrets/nenya \\\n  --cap-drop=ALL \\\n  --cap-add=IPC_LOCK \\\n  --security-opt=no-new-privileges:true \\\n  --read-only \\\n  --tmpfs /tmp:rw,noexec,nosuid,size=64M \\\n  ghcr.io/gumieri/nenya:latest\n```\n\nTest it:\n\n```\ncurl -H \"Authorization: Bearer $(jq -r '.client_token' secrets/client.json)\" \\\n  http://localhost:8080/healthz\n```\n\nNenya provides native packages for major Linux distributions and community package managers:\n\n| Distribution | Command |\n|---|---|\nDebian/Ubuntu (.deb) |\nDownload `nenya_<version>_linux_amd64.deb` from the release page and run `sudo dpkg -i` |\nFedora/RHEL (.rpm) |\nDownload `nenya-<version>.x86_64.rpm` from the release page and run `sudo rpm -i` |\nArch Linux (.pkg.tar.zst) |\nDownload `nenya-<version>-x86_64.pkg.tar.zst` from the release page and run `sudo pacman -U` |\nArch Linux (AUR) |\n`yay -S nenya-bin` (or your preferred AUR helper) |\nNix/NixOS |\nAdd `gumieri/nur-packages` to your NUR registry and use `nenya` |\n\nAll packages install the binary to `/usr/bin/nenya`\n\nand include systemd service and socket units. After install, enable and start:\n\n```\nsudo systemctl enable --now nenya.socket\nsudo systemctl enable --now nenya.service\n```\n\nNenya supports standard environment variables for deployment portability:\n\n| Variable | Default | Description |\n|---|---|---|\n`PORT` |\n`8080` |\nListening port (overrides `server.listen_addr` ) |\n`HOST` |\n— | Optional bind address (e.g. `127.0.0.1` ). Only used when combined with `PORT` |\n`NENYA_CONFIG_DIR` |\n`/etc/nenya/` |\nConfiguration directory path |\n`NENYA_CONFIG_FILE` |\n— | Single config file path (takes precedence over `NENYA_CONFIG_DIR` ) |\n`NENYA_SECRETS_DIR` |\n— | Secrets directory (overrides `CREDENTIALS_DIRECTORY` ) |\n\nExample usage:\n\n```\nPORT=9090 HOST=127.0.0.1 ./nenya --config /path/to/config.json\n```\n\nOr in Docker:\n\n```\ndocker run -e PORT=9090 -p 9090:9090 ghcr.io/gumieri/nenya:latest\n```\n\n— Direct binary install, socket activation, hot reload[Deploy Bare Metal (systemd)](/gumieri/nenya/blob/main/docs/DEPLOY_BAREMETAL.md)— compose.yml, image verification, security hardening[Deploy Container (Podman/Docker Compose)](/gumieri/nenya/blob/main/docs/DEPLOY_CONTAINER.md)— Helm chart, ConfigMap/Secret, ingress setup[Deploy Kubernetes (Helm)](/gumieri/nenya/blob/main/docs/DEPLOY_KUBERNETES.md)\n\nAll `/v1/*`\n\nendpoints require `Authorization: Bearer <client_token>`\n\nor `Bearer <api_key_token>`\n\n.\nAPI keys support **RBAC enforcement** — agent scoping, endpoint allowlists, role-based permissions (admin bypasses all checks).\n\n| Endpoint | Auth | Description |\n|---|---|---|\n`POST /v1/chat/completions` |\nBearer + RBAC | OpenAI-compatible chat with SSE streaming, agent fallback, MCP multi-turn |\n`POST /v1/messages` |\nBearer + RBAC | Anthropic Messages API with bidirectional format conversion |\n`GET /v1/models` |\nBearer + RBAC | Live model catalog from discovered providers + static registry (context window, max tokens) |\n`POST /v1/embeddings` |\nBearer + RBAC | Passthrough proxy |\n`POST /v1/responses` |\nBearer + RBAC | Passthrough proxy |\n`POST /v1/images/generations` |\nBearer + RBAC | Image generation (OpenAI-compatible) |\n`POST /v1/audio/transcriptions` |\nBearer + RBAC | Audio transcription (Whisper-compatible, multipart support) |\n`POST /v1/audio/speech` |\nBearer + RBAC | Text-to-speech synthesis (OpenAI-compatible) |\n`POST /v1/moderations` |\nBearer + RBAC | Content moderation (OpenAI-compatible) |\n`POST /v1/rerank` |\nBearer + RBAC | Re-ranking API (Cohere/Jina/Voyage-compatible) |\n`POST /v1/a2a` |\nBearer + RBAC | Agent-to-Agent protocol (Google A2A) |\n`GET /v1/files` |\nBearer + RBAC | File listing, upload, retrieval, deletion |\n`POST /v1/batches` |\nBearer + RBAC | Batch API operations |\n`POST /proxy/{provider}/*` |\nBearer + RBAC | Arbitrary provider endpoint passthrough (all HTTP methods, SSE streaming) |\n`GET /healthz` |\nNone | Engine health probe |\n`GET /statsz` |\nNone | Token usage, circuit breaker state, MCP server status |\n`GET /metrics` |\nNone | Prometheus-compatible metrics |\n`GET /debug/pprof/*` |\nBearer | Go profiling endpoints (disabled by default, see `debug.pprof_enabled` ) |\n\nSee [ docs/PASSTHROUGH_PROXY.md](/gumieri/nenya/blob/main/docs/PASSTHROUGH_PROXY.md) for detailed passthrough proxy usage.\n\n| Document | Description |\n|---|---|\n|\n\n[Configuration](/gumieri/nenya/blob/main/docs/CONFIGURATION.md)[Deploy Bare Metal](/gumieri/nenya/blob/main/docs/DEPLOY_BAREMETAL.md)[Deploy Container](/gumieri/nenya/blob/main/docs/DEPLOY_CONTAINER.md)[Deploy Kubernetes](/gumieri/nenya/blob/main/docs/DEPLOY_KUBERNETES.md)[Passthrough Proxy](/gumieri/nenya/blob/main/docs/PASSTHROUGH_PROXY.md)[Architecture](/gumieri/nenya/blob/main/docs/ARCHITECTURE.md)[MCP Integration](/gumieri/nenya/blob/main/docs/MCP_INTEGRATION.md)[Adapters](/gumieri/nenya/blob/main/docs/ADAPTERS.md)[Secrets Format](/gumieri/nenya/blob/main/docs/SECRETS_FORMAT.md)[Security](/gumieri/nenya/blob/main/docs/SECURITY.md)Apache 2.0. See [ LICENSE](/gumieri/nenya/blob/main/LICENSE).", "url": "https://wpnews.pro/news/show-hn-nenya-a-lightweight-highly-secure-ai-api-gateway-proxy-written-in-go", "canonical_source": "https://github.com/gumieri/nenya", "published_at": "2026-06-12 17:32:40+00:00", "updated_at": "2026-06-12 17:50:54.960705+00:00", "lang": "en", "topics": ["ai-tools", "ai-infrastructure", "ai-agents", "ai-products"], "entities": ["Nenya", "OpenAI", "Anthropic", "Cursor", "OpenCode", "Aider", "Go"], "alternates": {"html": "https://wpnews.pro/news/show-hn-nenya-a-lightweight-highly-secure-ai-api-gateway-proxy-written-in-go", "markdown": "https://wpnews.pro/news/show-hn-nenya-a-lightweight-highly-secure-ai-api-gateway-proxy-written-in-go.md", "text": "https://wpnews.pro/news/show-hn-nenya-a-lightweight-highly-secure-ai-api-gateway-proxy-written-in-go.txt", "jsonld": "https://wpnews.pro/news/show-hn-nenya-a-lightweight-highly-secure-ai-api-gateway-proxy-written-in-go.jsonld"}}