Skip to content

External sign-in (Google, Apple, Facebook)

Identity is deliberately split into two tables:

user            who somebody is — owns a library
auth_identity   how they prove it — 'local' password, 'google' sub, …

A password is just an identity with provider='local'. Adding an OAuth provider inserts rows into auth_identity and changes nothing else, and one person can hold several identities pointing at the same library.

To enable a provider: register an OAuth client with them, then paste the client id and secret into Admin → Sign-in providers. The page shows the exact redirect URI to register. Its button then appears on the sign-in page. Nothing else needs configuring — the flow is authorization-code with PKCE, state is kept server-side and consumed once, and ID token aud, iss and exp are checked.

Linking to an existing library. Someone who already signed up with a password can link Google from their account page and keep everything they have. A first-time Google sign-in whose verified email matches an existing account links to it rather than creating a second, empty one — which is why the registration form asks for an email.

Provider notes:

  • Google works with the shipped configuration; you only supply credentials.
  • Apple uses a short-lived ES256 JWT as its client secret rather than a fixed string. Mint one and paste it as the secret, or extend oauth._client_secret() to sign it per request.
  • Facebook is plain OAuth2 rather than OIDC, so the profile comes from the Graph /me endpoint instead of an ID token. The registry entry handles that.

Behind a reverse proxy, set LONGBOX_PUBLIC_URL so callbacks point at your external hostname rather than the container's.

Security notes

Passwords are hashed with scrypt (N=16384, r=8, p=1) and a per-password salt, verified in constant time. Session tokens are 256 bits of randomness, stored only as a SHA-256 hash, so a database leak does not hand out live sessions. Cookies are HttpOnly and SameSite=Lax, plus an Origin check on every state-changing request. Repeated failed sign-ins are throttled per username-and-address. Changing a password or disabling an account revokes every existing session.

Password reset tokens follow the same rules as sessions: 256 bits of randomness, stored only as a SHA-256 hash, single use, and short-lived. Consuming one revokes every session for that account.

Longbox still expects to live on a trusted network. Put it behind a reverse proxy with TLS if you expose it, and set LONGBOX_SECURE_COOKIES=1 when you do -- see Reverse proxy and HTTPS.