# Identity

Put Buddy authentication in front of a Sandbox endpoint and let the app inside read who the visitor is - name, email, and groups - with no login flow.

Your application runs in a Sandbox and is published through an [endpoint](/docs/sandboxes/endpoints.md). 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](#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

- [Endpoints](/docs/sandboxes/endpoints.md)
- [Custom domains](/docs/sandboxes/custom-domains.md)
- [Permissions and security](/docs/sandboxes/permissions-and-security.md)


---
Original source: https://buddy.works/docs/sandboxes/identity