# Sign-in

> Email and password, verification, magic links and social sign-in per project and environment, with allowed email domains.

The `auth` resource gives a project its own sign-in service: users, sessions, email and password, magic links, and Google, GitHub or Vercel sign-in. It stores users in the project's database (adding `auth` brings `database`). Production and development each have their own sign-in with their own users: the development copy trusts `http://localhost:3000` only.

## Pricing

No separate charge today: sign-in is part of the project's database. Pricing is not decided.

## Limits

- Social providers: `google`, `github`, `vercel`. Only Google has shared keys (no OAuth app of your own needed); GitHub and Vercel need your own `client_id` and `client_secret`.
- Magic link lifetime: 5–1440 minutes. App name in emails: 1–256 characters.
- Allowed email domains: at most 50 (empty = anyone may sign up).
- Link-style email verification needs your own SMTP sender; the shared sender does one-time codes (`otp`).
- Not available yet: session lifetime, email templates, MFA, banning users.

## In the app

The `nextjs-saas` template (`vibiz init --template nextjs-saas`) has sign-in wired: `currentUser()` in `lib/auth/server.ts` returns the signed-in user, and `/api/auth/*` serves the flows. The app's env carries:

| Variable | |
| --- | --- |
| `VIBIZ_AUTH_BASE_URL` | the sign-in service for this environment |
| `VIBIZ_AUTH_COOKIE_SECRET` | signs the session cookie |
| `VIBIZ_AUTH_JWKS_URL`, `VIBIZ_AUTH_PROJECT_ID` | for code that verifies tokens itself |

Before the app runs on a domain outside Vibiz hosting, add it (`vibiz domains add app.example.com --elsewhere`) so sign-in trusts it. An owner's is trusted at once; one an agent key adds is trusted once its TXT record (`trust_record`) is in and `vibiz domains verify` finds it, or the owner confirms it ([Hosting ▸ Your own domain](https://app.vibiz.app/docs/hosting#your-own-domain)). A domain Vibiz hosting serves is trusted too.

## Settings

```bash
vibiz auth --dev                                   # the development copy's settings
vibiz auth providers add google --dev              # shared keys
vibiz auth providers add github --own --client-id Iv1.abc --dev   # secret from GITHUB_CLIENT_SECRET or a prompt
vibiz auth domains acme.com,partner.com --dev      # only these email domains may sign up
vibiz auth domains none --dev
```

```bash
curl -X PATCH "https://app.vibiz.app/v1/projects/$PROJECT/auth/settings?env=development" \
  -H "Authorization: Bearer $VIBIZ_API_KEY" -H 'content-type: application/json' \
  -d '{"magic_link":{"enabled":true,"expires_in_minutes":30},"allowed_email_domains":["acme.com"]}'

curl -X PUT "https://app.vibiz.app/v1/projects/$PROJECT/auth/providers/google?env=development" \
  -H "Authorization: Bearer $VIBIZ_API_KEY" -H 'content-type: application/json' \
  -d '{"credentials":"shared"}'
```

The settings carry each provider's `callback_url` (per environment) and, under `available_providers`, where to create the OAuth app and the steps for that provider's console. Secrets are never returned: `has_client_secret`, `has_password`.

| Setting | Field |
| --- | --- |
| App name in emails | `app_name` |
| Email + password, verification, closed sign-up | `email_password.{enabled, require_email_verification, email_verification_method, disable_sign_up, auto_sign_in_after_verification}` |
| Magic link | `magic_link.{enabled, expires_in_minutes}` |
| Localhost | `allow_localhost` (production: off by default; development: on) |
| Allowed email domains | `allowed_email_domains` |
| Email sender | `email_sender`: `{type: "shared"}` or `{type: "smtp", host, port, username, password, sender_email}` |

## What agents can and can't do

Agents change the **development** copy: app name, email and password, magic link, localhost, allowed email domains, and shared-key providers on or off (`vibiz_auth_settings`). Production settings and test emails are the owner's: an agent key gets `403 owner_only`. Your own OAuth secrets and SMTP passwords are entered by a person (the console, or the CLI's hidden prompt), never through an agent.

## Errors

| Code | Status | When | Next step |
| --- | --- | --- | --- |
| `invalid_request` | 400 | an unknown provider, `credentials: "shared"` for anything but Google, `own` without a client id or secret, `link` verification with the shared sender, out-of-range values | fix the field in `details` |
| `forbidden` + `owner_only` | 403 | an agent on production settings | the owner, in the console ▸ Sign-in |
| `dependency_not_ready` | 409 | no `auth` resource yet, or `env=development` before `vibiz dev` | add `auth`, or run `vibiz dev` |
