Skip to content

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 answers three questions before it runs: who is acting, for whom, and by what right. The answers stay on the Action.

Who is acting

People sign in with a passkey, an email link or their own single sign-on; the signup Setting in startup.ts picks the default. Agents carry their own credentials and never borrow a person's. Programs hold a key.

Terminal
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:

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

A missing or expired key returns unauthorized. A valid key without the right returns forbidden, naming the grant it lacks.

For whom

An agent acting for a person or the Startup does so under a Mandate: one Verb, within a Limit, until it expires.

TypeScript
import { $ } from 'startup-builder'

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

Every Action records the Worker that acted and the Party it acted for.

By what right

GrantComes fromDeclared in
PermissionA Roleagents/[team]/[role].mdx
EntitlementAn accepted Offeroffers/[offer].mdx
Persona accessAn Appapps/[app]/app.mdx
MandateA Party's authorizationMandate.authorize

A call over its Limit does not fail. It waits as an Approval for a Worker who may allow or refuse it.

Customers and their teams

A Customer's people sign in to the Startup's App and see only their own Tenant. A Customer that is an Organization connects its own single sign-on and directory. Because every call is checked, MCP shows a Customer exactly what the portal shows.