Identity

Your application runs in a Sandbox and is published through an endpoint. Turn on Buddy auth on that endpoint and visitors have to sign in with their Buddy account before they reach it.

Identity puts the visitor's name, email, owner/admin flags, and group membership straight into your code. Nothing to build - no OAuth flow, no session store, no token to check.

With Identity, an application can show an admin panel to administrators, a QA view to the QA group, and read-only content to everyone else.

How it works

The tunnel in front of your application intercepts GET /.buddy/auth/me, verifies the session, and answers with the current user. All verification happens on Buddy's infrastructure - raw tokens never reach your code, and there is nothing to configure inside the Sandbox.

Step 1: protect the endpoint

Turn on Buddy auth on the endpoint your application is exposed through:

bash
bdy sb ep add my-sandbox -e 3000 --buddy $

At this point strangers are already locked out. The application does not know anything about the visitor yet.

Step 2: add the library to your application

In the codebase of the app that runs in the Sandbox:

bash
npm install @buddy-works/identity $

The library requires Node.js 18 or newer on the server and any modern browser on the client. Inside a Sandbox that is already covered - the image ships Node 24 - so in practice the requirement matters for local development.

Step 3: read the current user

The same call works in the browser and on the server:

ts
import { getCurrentUser } from "@buddy-works/identity"; const user = await getCurrentUser();

Server-side, pass the request so the session cookie travels with it:

ts
app.get("/api/whoami", async (req, res) => { const user = await getCurrentUser(req); if (!user) return res.status(401).json({ error: "Not logged in" }); res.json({ message: `Welcome ${user.name}` }); });

Or install the middleware and read req.buddyUser anywhere:

ts
import { buddyIdentity } from "@buddy-works/identity"; app.use(buddyIdentity()); // or buddyIdentity({ required: true }) app.get("/api/admin", (req, res) => { if (!req.buddyUser?.admin) return res.status(403).json({ error: "Admins only" }); res.json({ secret: "…" }); });

What you get

ts
interface BuddyUser { id: number; // Buddy user id name: string; email: string; owner: boolean; // workspace owner admin: boolean; // workspace administrator avatar: string | null; sso_id: string | null; // SSO identifier, null when SSO is not bound groups: { id: number; name: string }[]; }

owner, admin, and groups are enough to gate features without maintaining a user table of your own.

Other languages

The library is a thin client over an HTTP endpoint. From any stack, call GET /.buddy/auth/me with the incoming request's cookies and read the JSON response. A non-2xx status means nobody is signed in.

Local development

The package ships mocks, so the app still runs on your machine with no tunnel in front of it:

ts
import { mockAuthEndpoint } from "@buddy-works/identity/dev"; app.use(mockAuthEndpoint("admin")); // "owner", "member", a custom object, or null

For single-page apps, mockUser("admin") and clearMockUser() do the same in process, with no HTTP involved.

Next

Last modified on Aug 17, 2026