Backend Authentication Validation
Protect your server endpoints by verifying embarkAI-issued JWTs with
EmbarkAIAuthServicefrom@embarkai/core/auth/node.
Overview
When a user authenticates on the frontend, embarkAI issues a signed JWT. Your backend must verify that token on every protected request to confirm the caller’s identity and extract the userId.
The verification logic is the same regardless of your framework. The core steps are:
- Extract the
Authorization: Bearer <token>header from the incoming request. - Verify the token with
EmbarkAIAuthService.verifyToken(), which validates the signature against embarkAI’s JWKS endpoint. - Reject the request with a
401response if the token is missing, malformed, or invalid. - Propagate the verified
userIdto your route handler for use in business logic.
You can wrap these steps in whichever middleware or interceptor pattern your framework supports — Express middleware, Fastify hooks, Next.js Route Handlers, Hono middleware, etc.
Core Usage
1. Instantiate the service
Create a single shared instance of EmbarkAIAuthService. The jwksUri option is optional — it defaults to embarkAI’s production TSS service.
import { EmbarkAIAuthService } from "@embarkai/core/auth/node";
export const embarkaiService = new EmbarkAIAuthService({
// jwksUri: optional override, e.g. "https://custom-api.embarkai.io"
// Defaults to https://api.embarkai.io
});2. Verify a token
Call verifyToken() with the raw JWT string. On success it returns { valid: true, user: { userId } }. On failure it returns { valid: false }.
const token = "eyJ..."; // raw Bearer token from the Authorization header
const result = await embarkaiService.verifyToken(token);
if (!result.valid || !result.user) {
// respond with 401
}
const { userId } = result.user; // verified EmbarkAI user IDHono Middleware Example
The following shows how to wire verification into a Hono application. The same pattern applies to any framework — replace Hono-specific APIs (c.req.header, c.set, c.json) with the equivalents for your stack.
Middleware
Define a reusable middleware that extracts and verifies the token, then stores userId in the request context.
import type { Context, Next } from "hono";
import type { HonoAppEnv } from "@src/types";
import { EmbarkAIAuthService } from "@embarkai/core/auth/node";
const embarkaiService = new EmbarkAIAuthService();
export type HonoAppEnv = {
Variables: { userId: string };
};
export const jwtAuthMiddleware = async (c: Context<HonoAppEnv>, next: Next) => {
try {
const authHeader = c.req.header("Authorization");
if (!authHeader) {
throw new Error("Authorization header missing");
}
if (!authHeader.startsWith("Bearer ")) {
throw new Error('Invalid authorization format. Use "Bearer <token>"');
}
const token = authHeader.slice(7); // Remove "Bearer " prefix
if (!token) {
throw new Error("Token missing from authorization header");
}
const verificationResult = await embarkaiService.verifyToken(token);
if (!verificationResult.valid || !verificationResult.user) {
throw new Error("Invalid token format");
}
c.set("userId", verificationResult.user.userId);
await next();
} catch (error) {
const message =
error instanceof Error ? error.message : "Authentication failed";
return c.json(
{
error: "Authentication required",
message: `${message}. Please provide a valid Bearer token.`,
},
401,
);
}
};Protected Routes
Apply the middleware to any route or route group that requires authentication. The verified userId is available via c.get("userId").
import { Hono } from "hono";
import type { HonoAppEnv } from "<your-types-file>";
import { jwtAuthMiddleware } from "<middleware-path>/jwtAuthMiddleware";
export function mountProtectedRoutes(honoApi: Hono<HonoAppEnv>) {
honoApi.get("/your-protected-endpoint", jwtAuthMiddleware, async (c) => {
const userId = c.get("userId"); // verified EmbarkAI userId
// Your endpoint logic here
return c.json({ message: `Hello, user ${userId}!` });
});
}App / Router Setup
Register the protected routes on your Hono app instance.
import { Hono } from "hono";
import type { HonoAppEnv } from "<types-path>";
const honoApp = new Hono<HonoAppEnv>(baseHonoOptions);
const honoApi = honoApp.basePath("/base-api-path");
mountProtectedRoutes(honoApi);Next Steps
- Server Wallets — create and manage MPC wallets after authentication
- Vault Backup — back up keyshares with password encryption
- Bundler — submit UserOperations with authenticated sessions