fix: fail closed on production signup
Production configuration accepted publicSignupEnabled: true and started a working Identity/API runtime, even though Ekklesia has no verified email, invitation requirement, CAPTCHA, or durable shared/edge limiter — Doctor merely reported "Public signup is explicitly ENABLED" as a pass. validatePublicSignupEnabled now takes the same IdentityEnvironment the rest of this config validates against and throws the stable PUBLIC_SIGNUP_UNSUPPORTED_IN_PRODUCTION whenever the parsed value is true in production. Parsing stays separate from the policy, so a malformed value still reports PUBLIC_SIGNUP_ENABLED_INVALID everywhere. Because the executable entry point validates configuration before startApi, such a deployment fails before any pool, Better Auth instance, module runtime, or listener exists, and Doctor reports NOT READY via its existing IdentityConfigError path. Development and test composition still enable it explicitly through the identical typed path. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d3c6bd73d3
commit
1161f5a076
@@ -37,8 +37,9 @@ Phase 4B adds identity HTTP transport: a minimal Hono-based `apps/api` compositi
|
||||
Core's own Fetch-compatible identity runtime — Core still does not depend on Hono, and modules
|
||||
still cannot reach any of this. Public email/password registration is the intended eventual
|
||||
product policy — every account receives identical lowest-privilege baseline status and signup
|
||||
order never grants elevation — but is now **disabled by default** and requires an explicit opt-in
|
||||
(Phase 5D pass 1, below). See [API](docs/development/api.md) and
|
||||
order never grants elevation — but is now **disabled by default, and cannot be enabled in
|
||||
production at all** until durable abuse controls exist (Phase 5D pass 1, below). See
|
||||
[API](docs/development/api.md) and
|
||||
[ADR 0011](docs/architecture/decisions/0011-identity-http-transport-and-public-enrollment.md).
|
||||
**No email verification, password recovery, or Dashboard exists yet** — that, along with
|
||||
production approval-provider composition, jobs, physical storage provisioning, surfaces, and
|
||||
@@ -101,8 +102,10 @@ Better Auth's authentication rate limiter now resolves client identity from a se
|
||||
client-address boundary (`core/src/identity/client-address.ts`, wired in at the Node/API transport
|
||||
boundary) — direct mode trusts only the real socket peer by default, and an explicit trusted-proxy
|
||||
mode is required before any forwarded header is ever consulted, closing a rotating-header
|
||||
rate-limit bypass. Public sign-up is now **disabled by default** and requires an explicit typed
|
||||
opt-in (`EKKLESIA_PUBLIC_SIGNUP_ENABLED=true`). Every public body-consuming route — Better Auth,
|
||||
rate-limit bypass. Public sign-up is now **disabled by default, and a production configuration that
|
||||
tries to enable it fails closed** (`PUBLIC_SIGNUP_UNSUPPORTED_IN_PRODUCTION`, reported by `pnpm
|
||||
doctor` as a blocking failure) — the durable abuse-control prerequisites do not exist yet, so only
|
||||
development/test composition may enable it. Every public body-consuming route — Better Auth,
|
||||
Core's grant-mutation endpoint, and every module route (via a new, required `maxBodyBytes` field on
|
||||
the executable route contract) — now has an explicit, platform-enforced byte ceiling with one
|
||||
sanitized `413` contract. The Node HTTP server now has finite header/request timeouts. See
|
||||
|
||||
Reference in New Issue
Block a user