---
title: Auth
description: Sign-in for your app's own users - passwords, Google, a second factor and hosted pages - with the end users and sessions you can read and revoke.
type: tutorial
product: auth
summary: What Auth serves, the keys it uses, and how a sign-in reaches your app.
updated: 2026-10-01
order: 0
---

Auth signs in the people who use **your** app. They are *end users*: a record
in your environment, never a Sylphx account. Auth holds their passwords (hashed
and checked against breached passwords), their sessions and their sign-in
history, so your app does not.

You work with Auth in two places.

- **Your server** manages end users and their sessions through the one API at
  `https://api.sylphx.com`, with your secret key.
- **Your pages** sign users in through the *client API* at
  `https://api.sylphx.com/v1/client`, with a publishable key that is safe to
  ship in a browser.

## What is served

| Method | Status |
| --- | --- |
| Email and password, with sign-up and an email verification link | Served. |
| Google, on Sylphx's shared Google client | Served. Nothing to set up in the Google console. |
| Google, GitHub and Apple on your own client | Served. GitHub and Apple need your own client: Sylphx has no shared GitHub or Apple client. |
| A TOTP second factor at sign-in | Served for a user who has an active factor: password sign-in then needs a `totp` or `recovery_code` proof. |
| Hosted sign-in, consent and device approval pages | Served, on the Account Portal. |
| Magic link, email code and passkeys | Not served on the client API. `GET /v1/client/config` reports each method as enabled or not, so render your sign-in from it. |

Every provider returns to one callback: `https://api.sylphx.com/v1/oidc/callback`.
When you bring your own Google, GitHub or Apple client, register exactly that
URL with the provider.

## The two keys

<KeyValue
	items={[
		{ key: 'Publishable key', value: 'sylphx_pk_live_… or sylphx_pk_test_…, scope auth:public. For the client API. Public by design.', mono: true },
		{ key: 'Secret key', value: 'sylphx_sk_…, scope auth:read and auth:write. For end_users and sessions. Server only.', mono: true },
	]}
/>

The platform delivers `SYLPHX_PUBLISHABLE_KEY` to every environment's services at
runtime, not at build time. Read it on your server and pass it to the page.

## How a sign-in reaches your app

1. The page reads `GET /v1/client/config?publishable_key=…`: the enabled
   `methods`, the `social` providers with their `start_url`, and your branding.
2. The user signs in. Password: `POST /v1/client/sign-in/password`. Social:
   send the browser to `/v1/client/oauth/{provider}/start?publishable_key=…&redirect_url=…`.
3. With the default `session_mode: "server"`, the page receives a one-time
   **ticket** (two minutes, one use), as `auth_ticket` on your `redirect_url` or
   in the password answer. Your server redeems it with `POST /v1/client/tickets:redeem`
   and keeps the session in an `HttpOnly` cookie. No bearer token is ever
   readable by page script. Apps with no backend use `session_mode: "browser"`
   and hold the session bearer.
4. `GET /v1/client/session` returns the current session and user, and
   `POST /v1/client/sign-out` ends it.

An error is a JSON object with a stable `code`: `invalid_request`,
`unauthorized`, `mfa_required`, `forbidden`, `not_found`, `conflict`,
`locked_out` (with `Retry-After`), `rate_limited`, `internal` and
`store_unavailable`. `mfa_required` means the user has a second factor: send it
as `factor_proofs` on the next password sign-in. Sign-up always answers
`202 {"accepted": true}`, whether or not the email already has an account.

## Manage end users from your server

```bash
sylphx auth end-users list orgs/acme/projects/shop/envs/production
sylphx auth sessions list orgs/acme/projects/shop/envs/production/end_users/<user>
sylphx auth end-users revoke-sessions orgs/acme/projects/shop/envs/production/end_users/<user>
```

Deleting an end user is revocation: every session ends and new sign-ins are
refused. [The quickstart](/docs/auth/quickstart) creates, reads and deletes one.

## Sign in a CLI or an agent: the device flow

For a program with no browser form, Auth serves the OAuth device grant (RFC
8628). An OAuth client that allows the device grant calls
`POST https://api.sylphx.com/v1/oauth/device_authorization` and receives a
`device_code`, a short `user_code` and a `verification_uri`: the Account
Portal's `/device` page. The user opens `…/device?user_code=ABCD-EFGH`
(`?code=` works too) or opens `/device` and types the code, signs in, and
approves or denies. The program polls `POST /v1/oauth/token` with the device
grant until it is approved. `sylphx login` uses the same pattern against
`sylphx.com/device`. The `oauth_clients` collection in the API reference is not
routed on `api.sylphx.com`: write to hi@sylphx.com and we register a client
for your environment.

<RelatedDocs
	links={[
		{
			href: '/docs/auth/quickstart',
			label: 'Quickstart',
			description: 'Create an end user, read it back and delete it.',
		},
		{
			href: '/docs/api/end_users',
			label: 'The end_users collection',
			description: 'Every method, field and example.',
		},
		{
			href: '/docs/api/sessions',
			label: 'The sessions collection',
			description: 'List and revoke an end user\'s sessions.',
		},
	]}
/>
