checkrd

Hono

Add Checkrd policy enforcement to Hono routes via app.use middleware.

Hono

Checkrd's Hono integration is a standard Hono middleware. Mount it once on the app and every request flows through the policy engine before reaching your handlers.

Install

bash
npm install checkrd hono

Quickstart

typescript
import { Hono } from "hono";
import { initAsync } from "checkrd";
import { checkrdHono } from "checkrd/integrations/hono";

const app = new Hono();
const checkrd = await initAsync({
  policy: "policy.yaml",
  agentId: "api-gateway",
});

app.use(
  "*",
  checkrdHono({
    engine: checkrd.engine,
    enforce: true,
    agentId: "api-gateway",
    sink: checkrd.sink,
  }),
);

app.post("/chat", async (c) => {
  const body = await c.req.json();
  // ... your handler runs only if the policy allowed the call ...
  return c.json({ ok: true });
});

export default app;

What gets enforced

The middleware evaluates each request through the policy engine using the request's actual method, URL, headers, and body. Standard URL matchers apply:

yaml
agent: api-gateway
default: deny

rules:
  - name: allow-public-chat
    allow:
      url: "POST */chat"
      body:
        messages: "*"

  - name: deny-admin-from-public
    deny:
      url: "POST */admin/*"
      headers:
        x-tenant-tier: "public"

Context variables

The middleware sets a checkrd value on the Hono context so downstream handlers can read the request's evaluation result:

typescript
app.post("/chat", async (c) => {
  const evalResult = c.get("checkrd"); // CheckrdHonoVariables
  console.log(evalResult.requestId, evalResult.allowed);
  // ...
});

This is useful for emitting custom telemetry that joins to the Checkrd request id.

Edge runtimes

Hono runs in Cloudflare Workers, Vercel Edge, Deno, Bun, and Node. The Checkrd middleware is runtime-agnostic — initAsync in the bootstrap loads the WASM via fetch.

Caveats

  • Body is read once. The middleware reads the request body for policy evaluation. Hono caches the body on the request, so handlers can still call c.req.json() / c.req.text() afterward — but if your handler uses a streaming reader, plumb it via c.req.raw.body directly.
  • Mount order. Place checkrdHono BEFORE any handlers you want enforced, but AFTER any auth middleware that adds identity headers — those headers feed the policy engine's header matchers.