
`import auth` constructs the in-memory and SQLite auth services that
back the Vary HTTP runtime, plus OIDC provider configuration and signed
session cookie settings. Authenticated routes are served by the
runtime - this module is what tests, local apps, and explicit identity
flows use to construct the same components.

For the production environment variables that configure
`VARY_AUTH_MODE`, OIDC discovery, capability claims, CSRF, and the auth
SQLite binding, see
[Public API security: production auth configuration](/docs/public-api-security/#production-auth-configuration).

## Services

```text
import auth

let memory_svc = auth.memory_service()
let sqlite_svc = auth.sqlite_service(db)
```

| Constructor | Purpose |
|---|---|
| `memory_service()` | In-memory auth service for tests. |
| `sqlite_service(db)` | Auth service on the managed auth schema. |
| `oidc_memory_service(auth)` | OIDC service layered on an auth service. |
| `oidc_sqlite_service(db)` | OIDC service on the managed auth schema. |
| `schema()` | Managed `SqlSchema` for Vary-owned auth storage. |

Pair `schema()` with `Sql.migrate_binding("AUTH", schema)` during startup.

## Session cookies

```text
import auth

let cookie = auth.cookie_settings(
    name = "vary_session",
    secure = True,
    http_only = True,
    same_site = "Lax",
    path = "/",
    max_age_seconds = 2592000)
```

`cookie_settings(...)` produces an `AuthCookieSettings` value the runtime
uses to mint session cookies. The defaults are production-safe: HTTPS
only, no JavaScript access, `Lax` same-site, 30-day max age.

`SESSION_SIGNING_KEY` (HMAC) is required in production deploys; the
preflight blocker `auth_session_signing_key_missing` is raised when it is
absent for any session route.

## API token verification

The runtime hash-stores API tokens. `VARY_AUTH_TOKEN_HASH_SECRET`
provides the hash secret; tokens carry an opaque hash id surfaced as
`RequestContext.api_token_id` on verified requests. `last_used`
metadata is updated atomically with the verification.

## OIDC providers

```text
import auth

let oidc = auth.oidc_sqlite_service(db)
let provider = auth.discover_oidc_provider(
    oidc,
    id = "primary",
    issuer = "https://login.example.com",
    client_id = "vary-app",
    scopes = "openid profile email")
```

| Helper | Purpose |
|---|---|
| `oidc_provider(id, issuer, client_id, ...)` | Build an `OidcProviderConfig` from explicit endpoints. |
| `discover_oidc_provider(svc, id, issuer, ...)` | Fetch OIDC discovery metadata (JWKS, endpoints). |

Full signatures:

```text
oidc_provider(id, issuer, client_id, authorization_endpoint, scopes?)
discover_oidc_provider(svc, id, issuer, client_id, scopes?)
```

The HTTP runtime exposes built-in `/auth/login`, `/auth/callback`, and
`/auth/logout` routes when a provider is registered, using Authorization
Code + PKCE. CSRF tokens are validated by the runtime; routes do not
need to call CSRF helpers unless they accept cross-origin POSTs.

## Registration, login, and reset

`AuthService` covers registration, email verification, password login,
password reset, rotating sessions, expiring API tokens, last-used
metadata, and auth audit events. Registration and reset return a stable
public message; proof tokens are emitted for trusted out-of-band
delivery, not direct public responses.

## Interaction with generated HTTP route auth

The Vary HTTP runtime owns route auth: `auth optional`, `auth session`,
and `auth capability` clauses are enforced by the generated boundary
before the handler runs. Handler code does not call `auth` to gate
requests; it calls helpers in `import api_context`
(`authenticated_user`, `required_capability`, `require_csrf`) against the
already-verified `RequestContext`.

Reach for `import auth` in these situations:

| Use case | Notes |
|----------|-------|
| Construct services for unit and integration tests | Mostly `memory_service()` and friends. |
| Run the auth schema migration during startup | `Sql.migrate_binding("AUTH", auth.schema())` |
| Register and configure OIDC providers | Issuer, client id, secret, scopes. |
| Override default cookie settings | Name, lifetime, SameSite, secure flag. |
