Auth Middleware
You want execution authentication that rejects unauthenticated route-execution requests and passes the verified user identity to every tool call in that execution. 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
- Tool name equals the file basename. The tool file is
tools/loadProfile.ts, so it is called asctx.tools.loadProfile(...). A file namedtools/load-profile.tswould instead bectx.tools["load-profile"](...). Use camelCase filenames to get camelCasectx.toolskeys. - One global middleware.
src/middleware.tsruns once per route-execution request before the route. Branch byreq.routeIdif you need per-route policy — there is no array of layered middlewares. rejectshort-circuits. The route never executes; the body ofreject(status, body?)is the HTTP response.allow(context)flows to tools. Whatever you pass becomesctx.middlewareon every tool call for that request. It isundefinedif you callallow()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. - Deployment scope matters. This middleware runs under
dawn dev, the Node Dawn HTTP runtime (dawn startor generatedserver.mjs), and Hono builds. Generated LangSmith graph entries do not include Dawn HTTP middleware, so enforce authentication at that platform boundary separately.