auth.factory0.ventures · SHARED INFRASTRUCTURE
Every Factory Zero venture needs people to sign in, and none of them should own a password table. This service is the one place logins happen. A venture registers as a client, sends people here, and gets back a token it can verify on its own.
Six ways in, one session. Passkeys, Google, Apple, Meta, email and password, magic links. Whichever a person picks, the result is the same session, and one person can use all six on one account.
Built as a consumer of the
Cratefield harness: one Worker,
one D1 database, modules that see only ports. It depends on the published
crates (cratefield-core and friends on crates.io), not on a git revision.
Its own crates stay factory0-auth-* and are never published: they are
Factory Zero's service, not part of the harness (harness ADR 0011). Read
docs/ARCHITECTURE.md for how it fits, what was
validated before the issues were written, and what is deferred.
- Register the venture as a client: it gets an id, a secret, and an exact list of redirect URIs. No wildcards.
- Send people to
/authorizewith PKCE. They log in here, onauth.factory0.ventures, by any method. - Exchange the code at
/tokenfor a short-lived ES256 access token and a single-use refresh token. - Verify tokens locally with
factory0-auth-client, which fetches and caches the published JWKS and checks the audience so nobody has to remember to.
| Module | What it owns |
|---|---|
auth-core |
schema, clients, sessions, tokens, the authorization flow, account linking |
auth-passkeys |
WebAuthn registration and login |
auth-oidc |
Google and Apple: discovery, PKCE, ID tokens, minted Apple client secret, form_post callback |
auth-meta |
Facebook Login: OAuth 2.0 plus a Graph profile call, with no OpenID Connect anywhere. The data deletion callback is #18 |
auth-password |
Email and password: argon2id, a per-account lockout, a breach check, and answers that reveal nothing about who has an account. Needs the paid Workers plan (ADR 0100) |
auth-magic-link |
Sign in by email: a single-use bearer credential, the way an address gets verified, and the way back in for a locked or passwordless account |
/v1/auth-core/authorize renders a sign-in page whenever there is no session.
Which buttons it offers is configuration, not discovery:
AUTH_CORE_LOGIN_METHODS=passkey,google,apple,meta
Order is display order. An unknown slug fails validate_config, which today
means cargo test catches it: nothing on the production boot path calls that
check, so at runtime an unknown slug is silently dropped and simply renders no
button. Setting a provider's credentials does not by
itself put it on the chooser: which methods a deployment offers is a decision.
Redirect-shaped methods are plain links and work with script switched off. A passkey cannot be: a WebAuthn credential is bound to a relying-party id, and a browser only runs a ceremony on a page whose origin matches, so a passkey registered here works on this service's own pages and nowhere else. That is why the chooser ships one small inline script, and why it ships it only when a passkey is enabled. See ADR 0103.
Design adopted 2026-09-06. Three spikes come first; everything else is blocked on them. Enterprise SAML SSO is deliberately deferred. Progress is in the issues and milestones.
MIT. Built in the open by Factory Zero.
