Skip to content

Custom JWT (jose)

Use a custom JWT when you already issue bearer tokens (internal IdP, API gateway, or multi-service mesh) and want Arivie to verify signatures with jose rather than adopting a full auth framework.

  1. Copy examples/with-custom-jose/.env.example:

    • DATABASE_URL
    • JWT_SECRET (HS256 symmetric key for the example; adapt for RS256 in production)
    • Model keys (optional)
  2. Install:

    Terminal window
    pnpm add jose
  3. Clients send Authorization: Bearer <jwt> on Arivie API requests.

app/api/arivie/route.ts
/* SPDX-License-Identifier: Apache-2.0 */
import { getArivieRuntimeForOwner } from "../../../arivie.config";
import { resolveOwnerId } from "../../../lib/resolve-owner";
import { assertAuthBypassAllowed } from "../../../lib/auth-bypass";
assertAuthBypassAllowed();
export async function POST(req: Request): Promise<Response> {
const ownerId = await resolveOwnerId(req);
const { arivie } = await getArivieRuntimeForOwner(ownerId);
return arivie.next.POST(req);
}
lib/resolve-owner.ts
/* SPDX-License-Identifier: Apache-2.0 */
import { BYPASS_OWNER_ID, isAuthBypassRequest } from "./auth-bypass";
import { verifyJwt } from "./verify-jwt";
export async function resolveOwnerId(req: Request): Promise<string> {
if (isAuthBypassRequest(req)) {
return BYPASS_OWNER_ID;
}
const header = req.headers.get("authorization") ?? "";
const match = /^Bearer\s+(.+)$/i.exec(header);
if (match?.[1] == null) {
throw new Error("Authorization: Bearer <jwt> required");
}
const { sub } = await verifyJwt(match[1]);
return sub;
}

The verified JWT’s sub claim is ownerId. Missing or invalid bearer tokens throw before the handler runs.

Terminal window
pnpm --filter with-custom-jose dev

Canonical tree: arivie/examples/with-custom-jose/.

Tested with jose ^6.2.3.