What your app receives after sign-in
When a visitor signs in through an OAuth2 middleware, including Sign in with Cruma, the agent forwards their request to your app with the visitor's identity attached. Your app reads the identity from request headers and never handles the sign-in itself. The same facts are shown under What your app receives on the Auth page of the desktop app, the terminal interface and the web dashboard.
Headers
| Header | Example | Meaning |
|---|---|---|
x-auth-subject | 1234567890 | Who signed in: the user id. |
x-auth-provider | cruma | Which sign-in they used. |
x-auth-claims | eyJlbWFpbCI6ImFkYUBleGFtcGxlLmNvbSIsIm5hbWUiOiJBZGEifQ | Base64url JSON of the provider's claims, such as email and name. |
x-cruma-identity | eyJhbGciOiJFZERTQSJ9.… | The same identity as a short-lived token signed by the agent. |
x-auth-subject is on every signed-in request. x-auth-provider and x-auth-claims are added when the sign-in carries them. Requests that are not signed in carry none of these headers.
Signing a visitor out
Link the visitor to the middleware's sign-out path with a plain GET. The agent clears the session and returns them to /, or to the relative path in ?next=. A next that points at another site is ignored.
| Middleware created in | Sign-out path |
|---|---|
| The desktop app, the terminal interface or the web dashboard | /_auth/logout |
| A coding agent over MCP, for a shared site | /_cruma_auth/logout |
The path is the middleware's logout_path setting, so a configuration file can use another. The Auth page shows the path of the middleware you have.
<a href="/_auth/logout?next=/goodbye">Sign out</a>
When to trust the headers
The agent removes every copy of these headers that a visitor sends, on every route. Trust x-auth-subject, x-auth-provider and x-auth-claims only if your app can be reached solely through the agent: they were set by the agent, or they are absent. If your app can also be reached another way, such as directly on your network, do not trust them. x-cruma-identity is signed, so verify it instead where the agent sends it.
🚧 In development
Publishing the public key that verifies
x-cruma-identityis not available yet. Until it is, rely on thex-auth-*headers behind the agent.
Reading the headers
A Node.js app using Express:
import express from "express";
const app = express();
app.get("/", (req, res) => {
const subject = req.get("x-auth-subject");
if (!subject) return res.status(401).send("Not signed in");
const claims = JSON.parse(
Buffer.from(req.get("x-auth-claims") ?? "e30", "base64url").toString(),
);
res.send(`Hello ${claims.name ?? subject}. <a href="/_auth/logout">Sign out</a>`);
});
app.listen(3000);
See Security for the sign-in types and Desktop security for the Auth Providers page.