Native principal
Your Express session middleware, Fastify JWT plugin, or Hono auth middleware already knows who the caller is. By default Arc ignores that and runs its own authentication handlers. When you want Arc to use the host’s verified user instead, switch on the native principal mode and hand the principal over explicitly.
Turn it on
Section titled “Turn it on”Set nativePrincipal: true in the options, and pass a callback as the second argument to cratisArc. The callback runs for every Arc request and returns a NativeRequestContext:
import express from 'express';import { ArcApplication, type Principal } from '@cratis/arc.core';import { cratisArc } from '@cratis/arc.express';
// Your own session middleware sets request.user after verifying the session.type SessionRequest = express.Request & { user?: { id: string; roles: string[] } };
const builder = ArcApplication.createBuilder({ nativePrincipal: true });await builder.discover(new URL('./Features/', import.meta.url));const arc = await builder.build();
const app = express();// app.use(yourVerifiedSessionMiddleware);app.use(cratisArc(arc, request => { const user = (request as SessionRequest).user; const principal: Principal | undefined = user ? { ...user, isAuthenticated: true } : undefined; return { principal };}));The session middleware in this example is yours. Arc does not implement or validate session cookies: host sessions can use HttpOnly, Secure, and SameSite cookies according to your framework’s own middleware.
The native context
Section titled “The native context”| Property | Meaning |
|---|---|
principal | The host-verified caller; used only when nativePrincipal is on |
secure | Whether the connection is TLS; Express and Fastify take it from the Node TLS socket unless you override it |
authority | A host name known from trusted configuration, not the request Host header; used by the subdomain tenant source |
remoteAddress | The caller’s address, for anonymous per-caller observable limits |
The callback can be async. Adapters invoke it inside Arc’s error boundary, so a thrown error becomes a redacted 500 with a correlation ID and a logger call.
nativePrincipal: truecannot be combined with Arc authentication handlers; the server refuses to start with both.- For an operation that requires a named scheme, the callback must supply a principal carrying that
scheme. - WebSocket upgrades take their own callback; see WebSockets.
- The standalone Node host takes the same callback as its
nativeoption; see Arc.Core. server.handle(request, native)accepts the same context, or an async callback returning it, for Fetch API hosts. This is a privileged, server-side seam.