Skip to content

Sign-in and sessions

Sign-in and sessions is how each principal proves who it is: people by passkey, email link or single sign-on; agents and apps by credential.

From sign-in to a held move

Every product serves the same sign-in on every Interface. Filled: what the person sees.

Ways in, for every principal

Sign-in belongs to the product, under your brand, so a UI built on the UI contracts never invents its own.

FamilyWhat it does
Sign-in methodsPasskeys, an email link or code, a password, a social account, and single sign-on per org over SAML or OIDC; the file names which a product offers
Sessions and tokensA session per device, each with its own short-lived access token and a refresh that rotates; listed, named and revoked one by one or all at once
Publishable keysA Key a browser or a mobile app holds in public, bound to its origins, acting only through a signed-in member's session
Second factors and step-upA factor per org policy (everyone, admins, or nobody), and a fresh factor confirmed within five minutes before any Verb stepUp names
Recovery and devicesAccount recovery by a second factor, a recovery code or an org admin, and devices a person trusts or forgets
Org policyAn org admin enforces single sign-on, sets session and idle limits, picks the methods and factors allowed, and links accounts by a checked email domain
The product as identity providerEvery product is an OIDC provider for its own UIs and for apps Customers connect, with its keys at /.well-known/openid-configuration
Brand, one level downA Customer's own customers sign in on that Customer's Domain, under its name and logo; no other brand appears
How a UI signs inThe authorization code flow with PKCE, a session cookie on the product's own Domain, and every read and move through the same Verbs as an agent
PrincipalHow it signs inWhere
A Customer's memberPasskey, email link, password or single sign-onYour Domain, in your brand
A Customer's own customerThe methods the Customer's org allowsThe Customer's Domain, in its brand
A supplierEmail, then verification, then a passkeyYour Domain, under the supplier account kind
A party without an accountA single-use link for one actThe link's own page
An appOAuth, with scopes a Customer's admin consents toThe product's identity provider
An agentA Key, an OAuth 2.1 token over MCP, a signed request, and a mandateEvery Interface

Example

Members sign in by passkey, email or their org's single sign-on, admins keep a second factor, and a win asks for a fresh one.

definition.ts
18 lines
import { define } from 'apis.dev'

/** Deals for each Customer, kicked off when won. */
export default define({
  name: 'pipeline', domain: 'pipeline.apis.dev',
  Company: { name: 'string', domain: 'url!#', deals: '<-Deal.company' },
  Deal: {
    title: 'string', amount: 'decimal(12,2)', company: '->Company.deals',
    stage: { open: [], qualify: 'opened', win: 'qualified', lose: ['opened', 'qualified'] },
  },
  auth: {
    methods: ['passkey', 'email', 'sso'],  // single sign-on per org, when its admin connects one
    session: '30d', idle: '7d',
    mfa: 'admins',                         // every admin keeps a second factor
    stepUp: ['Deal.win'],                  // a fresh factor before a win
  },
  offer: { Team: { month: 49, seats: 5, seat: 9 }, 'Deal.open': 0.001 },
})

A win from a session whose factor is an hour old waits for a fresh one.

Response
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json
X-Cost: price=0, currency="USD"
X-Request-Id: req_2f7a91c04e6b3d58a1c2

{
  "type": "https://pipeline.apis.dev/docs/errors#step_up_required",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Deal.win asks for a factor confirmed in the last five minutes.",
  "code": "step_up_required",
  "stepUp": "https://pipeline.apis.dev/auth/step-up?for=req_2f7a91c04e6b3d58a1c2",
  "instance": "req_2f7a91c04e6b3d58a1c2"
}

Sessions, factors and connections, state by state

Every move below is a Verb on the product's own API, MCP server and CLI.

An agent with an admin's grant makes each one with no UI.

ThingStatesWhat moves it
A sessionactive, idle, then expired, signed_out or revokedA sign-in starts it; its idle and total limits end it; the person or an admin revokes it with Session.revoke
An access tokenissued, refreshed, expired, revokedEach refresh rotates it; revoking the session revokes every token under it
A factorenrolled, verified, removedFactor.enroll and its first use; the person or an admin removes it, and the last one only after another is enrolled
A step-upasked, then confirmed or lapsedA Verb stepUp names; the person confirms within five minutes, and the move runs once
A recoveryrequested, verified, then completed or expiredRecovery.start, then a second factor, a recovery code or an admin's approval; every session ends when it completes
A single sign-on connectiondraft, testing, enforced, disabledThe org's admin connects it, tests it with one member, then enforces it for the org's domain
A publishable keyactive, rolled, revokedYou or the Customer's admin; a roll keeps the old one answering for its grace period

Every sign-in, failure, factor change and revoke writes an Event to the org's audit log, so Session.revoked reaches a Watch like any other.

Agents on the access ladder

An agent call stands on one rung, and each Verb names the lowest rung it accepts.

The rung is an input to the one decision, beside the Role and the mandate. A call below the rung answers 401 with the cure: a signature, a mandate, or the person present.

RungWhat the call carriesWhat it may do
anonymousNothingRead the offer card and the docs, and pay for one call in the call
keyedA Key or an OAuth tokenCall the Verbs its Customer's plan and Role allow
signedA request signed by the agent's provider, checked against the key directory Signature-Agent namesCalls whose seller wants to know which agent and which provider is calling
mandatedA mandate presentation from its personVerbs that commit money or act in the Customer's name
presentA mandate, with its person signed in and able to step upVerbs that reserve a fresh factor or a person's own act

agents.accept sets the rung per Verb. A seller may take orders only from a mandated agent, while its reads stay open to any keyed one.

Crawlers and answer engines meet the same ladder. discovery.crawlers says what an answer engine reads (full, an excerpt or none) and whether a model trainer pays per read or is refused. A crawler that does not sign is anonymous.

What members, admins and agents meet

  • A member. Sign in with a passkey on your Domain, see every session and device, and sign out of one or all of them.
  • An admin. Connect single sign-on, enforce it, require a second factor, set session limits, and recover a locked-out member.
  • A Customer's own customer. Sign in under that Customer's brand and Domain, never yours or the platform's.
  • A UI builder. One authorization flow, one session cookie and the Verbs the API serves, so the UI holds no rule of its own.
  • An agent. A Key for its Customer, a signature for its provider, a mandate for its person, and a 401 that names the missing rung.

Every principal signs in the same way on every Interface, so no UI and no agent holds a rule the product does not.