# Auth

URL: /code/platform/auth · Id: `page:code/platform/auth`

> How people, agents and programs sign in, act for others, and get the grants each call is checked against.

Every call to a [Startup](/business/nouns/startup) answers three questions before it runs: who is acting, for whom, and by what right. The answers stay on the [Action](/business/nouns/action).

## Who is acting
[People](/business/nouns/person) sign in with a passkey, an email link or their own single sign-on; the `signup` [Setting](/business/nouns/setting) in `startup.ts` picks the default. [Agents](/business/nouns/agent) carry their own credentials and never borrow a person's. Programs hold a key.

```bash
curl https://api.sb/leaseline.app/offers \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

A key starts `sk_test_` or `sk_live_`, and the prefix picks the environment. A key acts only in its namespace and scopes, and mints only narrower keys:

```bash
npx startup-builder keys create --name ci --scope leaseline.app --expire-in 30d
```

A missing or expired key returns [unauthorized](/code/api/errors/unauthorized). A valid key without the right returns [forbidden](/code/api/errors/forbidden), naming the grant it lacks.

## For whom
An agent acting for a person or the Startup does so under a [Mandate](/business/nouns/mandate): one [Verb](/business/nouns/verb), within a [Limit](/business/nouns/limit), until it expires.

```ts
import { $ } from 'startup-builder'

await $.Mandate.authorize({ agent: 'agent_1', verb: 'Invoice.refund', limit: 'limit_100_usd' })
```

Every Action records the [Worker](/business/nouns/worker) that acted and the [Party](/business/nouns/party) it acted for.

## By what right
| Grant | Comes from | Declared in |
| --- | --- | --- |
| [Permission](/business/nouns/permission) | A [Role](/business/nouns/role) | `agents/[team]/[role].mdx` |
| [Entitlement](/business/nouns/entitlement) | An accepted [Offer](/business/nouns/offer) | `offers/[offer].mdx` |
| [Persona](/business/nouns/persona) access | An [App](/business/nouns/app) | `apps/[app]/app.mdx` |
| Mandate | A Party's authorization | `Mandate.authorize` |

A call over its Limit does not fail. It waits as an [Approval](/business/nouns/approval) for a Worker who may allow or refuse it.

## Customers and their teams
A [Customer](/business/nouns/customer)'s people sign in to the Startup's App and see only their own [Tenant](/business/nouns/tenant). A Customer that is an [Organization](/business/nouns/organization) connects its own single sign-on and directory. Because every call is checked, MCP shows a Customer exactly what the portal shows.