Hono

Add Nyoxis threat detection to a Hono application using composable middleware. Works on Node.js, Deno, Bun, and edge runtimes.

Prerequisites

  • Hono 3 or later
  • A Nyoxis workspace API key — get one here

No extra install required

Hono uses the native fetch API. If you're running on Node.js 18, no additional dependencies are needed.

Middleware

Create src/middleware/nyoxis.ts:

typescript
import { createMiddleware } from "hono/factory"; import type { Context } from "hono"; const NYO_API = "https://api.nyoxis.com"; type NyoxisOptions = { apiKey: string; blockOnHigh?: boolean; onError?: "open" | "closed"; }; export function nyoxisWAF(options: NyoxisOptions) { const { apiKey, blockOnHigh = false, onError = "open" } = options; if (!apiKey) throw new Error("nyoxis: apiKey is required"); return createMiddleware(async (c: Context, next) => { const url = new URL(c.req.url); const payload = { method: c.req.method, path: url.pathname, query: url.search ? url.search.slice(1) : undefined, headers: Object.fromEntries(c.req.raw.headers.entries()), ip_addr: c.req.header("cf-connecting-ip") ?? c.req.header("x-real-ip") ?? c.env?.remoteAddr ?? undefined, }; try { const response = await fetch(`${NYO_API}/v0/predict?api_key=${apiKey}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), signal: AbortSignal.timeout(3000), }); const verdict = await response.json(); // Store in Hono context variables for downstream handlers c.set("nyoxis", verdict); if (blockOnHigh && verdict.prediction?.risk === "high") { return c.json({ error: "Forbidden" }, 403); } } catch (err) { console.warn("[nyoxis] prediction error:", (err as Error).message); if (onError === "closed") { return c.json({ error: "Service unavailable" }, 503); } } await next(); }); }

Register the middleware

typescript
// src/index.ts import { Hono } from "hono"; import { nyoxisWAF } from "./middleware/nyoxis"; // Declare the context variable type in your Hono app type Variables = { nyoxis: Record<string, unknown> }; const app = new Hono<{ Variables: Variables }>(); // Apply globally app.use( "*", nyoxisWAF({ apiKey: process.env.NYOXIS_API_KEY!, blockOnHigh: true }), ); app.get("/", (c) => { const verdict = c.get("nyoxis") ?? {}; const risk = (verdict.prediction as any)?.risk ?? "unknown"; return c.json({ ok: true, risk }); }); export default app;

Apply to a specific route group

typescript
// Protect only /api/* routes app.use("/api/*", nyoxisWAF({ apiKey: process.env.NYOXIS_API_KEY! }));

Acting on the verdict

typescript
app.get("/sensitive", (c) => { const verdict = c.get("nyoxis") ?? {}; const prediction = (verdict.prediction as any) ?? {}; if (["medium", "high"].includes(prediction.risk)) { return c.json({ error: "Forbidden" }, 403); } const hasXss = prediction.attacks?.some( (a: { kind: string }) => a.kind === "xss", ); if (hasXss) { console.warn("[security] XSS signal", { path: new URL(c.req.url).pathname, }); } return c.json({ data: "sensitive content" }); });

Edge runtime note

This middleware uses fetch and AbortSignal.timeout, both available on Cloudflare Workers, Deno Deploy, and Vercel Edge. No runtime-specific code is needed.

Next steps

  • API Reference — complete field descriptions and status codes.
  • Overview — how the classifier and redaction pipeline work.

Cookie preferences

Nyoxis uses essential cookies for authentication and session security. We only enable Analytics after you consent. See our Cookie Policy for details.