Auth middleware

You want to reject unauthenticated requests and pass the verified user identity to every tool call. Here's how.

The code

import { allow, defineMiddleware, reject } from "@dawn-ai/sdk"
 
export default defineMiddleware(async (req) => {
  const auth = req.headers["authorization"]
  if (!auth?.startsWith("Bearer ")) {
    return reject(401, { error: "Missing bearer token" })
  }
 
  const token = auth.slice("Bearer ".length)
  const userId = await verifyJwt(token).catch(() => null)
  if (!userId) {
    return reject(401, { error: "Invalid token" })
  }
 
  return allow({ userId })
})
 
async function verifyJwt(token: string): Promise<string> {
  // Replace with your real verifier.
  const res = await fetch("https://auth.example.com/verify", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ token }),
  })
  if (!res.ok) throw new Error("verify failed")
  const body = (await res.json()) as { readonly sub: string }
  return body.sub
}

Notes

  • One global middleware. src/middleware.ts runs once per request before any route. Branch by req.routeId if you need per-route policy — there is no array of layered middlewares.
  • reject short-circuits. The route never executes; the body of reject(status, body?) is the HTTP response.
  • allow(context) flows to tools. Whatever you pass becomes ctx.middleware on every tool call for that request. It is undefined if you call allow() with no arguments.
  • Throwing equals 500. Any uncaught error becomes HTTP 500. Prefer explicit reject(401, ...) with a real body so callers see a useful response.

Related