feat: add browser auth shell
This commit is contained in:
@@ -19,9 +19,11 @@ surface concern. Better Auth is an implementation detail contained entirely behi
|
||||
Auth instance, session token, or raw database client.** This holds structurally today: modules
|
||||
cannot import `core` at all under `scripts/check-boundaries.ts`'s boundary matrix, regardless of
|
||||
what Core exposes.
|
||||
- **Surfaces will eventually authenticate through Core-exposed HTTP/API and client contracts**,
|
||||
never by querying Better Auth's tables directly. `apps/api` (Phase 4B, see [API](api.md)) is that
|
||||
transport for server-side/API consumers; no Dashboard, Website, or Mobile Surface exists yet.
|
||||
- **Surfaces authenticate through Core-exposed HTTP/API contracts**, never by querying Better
|
||||
Auth's tables directly. `apps/api` (Phase 4B, see [API](api.md)) is that transport. The Dashboard
|
||||
now owns its browser login/logout UX and uses only `/api/auth/sign-in/email`,
|
||||
`/api/auth/sign-out`, and the narrow `/api/v1/principal` contract; modules receive none of those
|
||||
controls. Website and Mobile authentication do not exist yet.
|
||||
- Better Auth's `user` row is an authentication identity, not the future church-person/profile
|
||||
model. Church membership, ministry roles, contact history, attendance, permissions, and other
|
||||
module-specific fields must never be added to the identity tables; a future, separately designed
|
||||
@@ -168,7 +170,8 @@ address passes this validation, and a firewall, network policy, or reverse proxy
|
||||
parsing — is what actually determines who can reach a deployment.
|
||||
|
||||
Secret rotation (Better Auth's plural `secrets` list) and cross-subdomain cookies are deferred; see
|
||||
ADR 0010.
|
||||
ADR 0010. The Dashboard flow in ADR 0034 deliberately retains a host-only cookie: a future
|
||||
deployment must not assume sibling subdomains share a session.
|
||||
|
||||
## The identity runtime (Core's Better Auth transport boundary)
|
||||
|
||||
@@ -184,6 +187,21 @@ exported from `@ekklesia/core/identity`, exposes `auth.api`, Better Auth's sessi
|
||||
Drizzle adapter, the raw database, a session token, or Better Auth configuration. `apps/api` is the
|
||||
only current consumer of this boundary; see [API](api.md).
|
||||
|
||||
Core still returns Better Auth's normal `Response` to that consumer. At the browser-facing API
|
||||
composition boundary, [ADR 0034](../architecture/decisions/0034-host-owned-browser-authentication.md)
|
||||
defines exactly two exceptions. First, any body-bearing successful `2xx` from
|
||||
`POST /api/auth/sign-in/email` preserves Better Auth's status, headers, and HttpOnly `Set-Cookie`
|
||||
but replaces its token/user JSON with fixed `{"ok":true}`. Second, the token-bearing native paths
|
||||
`/api/auth/get-session`, `/api/auth/list-sessions`, `/api/auth/update-session`, and
|
||||
`/api/auth/change-password` receive a sanitized `404` without reaching Better Auth. The last path
|
||||
is denied even though password/account management is not built, because the pinned implementation
|
||||
can return a new raw session token when revoking other sessions.
|
||||
|
||||
Failures and every other supported auth endpoint retain their native semantics. The Dashboard
|
||||
ignores even the normalized sign-in body as identity and re-resolves `/api/v1/principal`, the only
|
||||
supported browser session read; no session token is exposed to browser application JavaScript or
|
||||
added to a module context.
|
||||
|
||||
Construction also explicitly configures four things the pinned release would otherwise leave on an
|
||||
environment-sensitive or implicit default, all covered by [ADR 0012](../architecture/decisions/0012-identity-origin-csrf-protection-under-test.md)
|
||||
and [API](api.md#logging):
|
||||
@@ -233,13 +251,17 @@ database, and a query timeout therefore all produce a sanitized
|
||||
logs, and error carry no relation name, column name, SQL, driver message, host, or stack. See
|
||||
[ADR 0018](../architecture/decisions/0018-identity-session-resolution-and-database-transport.md).
|
||||
|
||||
## What is not operational yet
|
||||
## What is and is not operational
|
||||
|
||||
No email verification, password recovery, invitation flow, email delivery, social or OAuth
|
||||
provider, passkey, magic link, two-factor authentication, or roles/groups/teams/tenants model
|
||||
exists. Public registration, sign-in, principal resolution, and sign-out over HTTP **are**
|
||||
operational as of Phase 4B — see [API](api.md) for the transport and routes, and ADR 0011 for why
|
||||
public registration is intentional and grants no elevation. Core's authorization foundation
|
||||
(platform owners, explicit grants, an immutable permission registry) landed in Phase 4C and is
|
||||
covered separately — see [Authorization](authorization.md) — not a Dashboard Surface, which still
|
||||
depends on an authorization model that only now exists and has not yet been built on.
|
||||
Email/password sign-in, principal resolution, sign-out, and the Dashboard's host-owned browser flow
|
||||
are operational — see [API](api.md) and ADR 0034. Public registration remains a future product
|
||||
policy, not a production capability: it is disabled by default, may be explicitly enabled only for
|
||||
development/test, and production rejects it. No email verification, password recovery, invitation
|
||||
flow, email delivery, social or OAuth provider, passkey, magic link, two-factor authentication, or
|
||||
roles/groups/teams/tenants model exists.
|
||||
|
||||
Core's authorization foundation (platform owners, explicit grants, and an immutable permission
|
||||
registry) is covered separately in [Authorization](authorization.md). Its bootstrap command grants
|
||||
an existing identity; it does not create one. Because production signup is prohibited and no
|
||||
operator enrollment command exists, creating the initial production identity needed for owner
|
||||
bootstrap remains an explicit operational gap.
|
||||
|
||||
Reference in New Issue
Block a user