From 6e655722e48d491b519c25a038467e86974acbbc Mon Sep 17 00:00:00 2001 From: emi Date: Tue, 21 Jul 2026 23:23:37 +0000 Subject: [PATCH] Forgejo: OAuth-only login with approval-gated access + mesh mailer (#24) --- deploy/forgejo/docker-stack.yml | 36 +++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/deploy/forgejo/docker-stack.yml b/deploy/forgejo/docker-stack.yml index 2c5d6ed..9d94cbd 100644 --- a/deploy/forgejo/docker-stack.yml +++ b/deploy/forgejo/docker-stack.yml @@ -71,16 +71,36 @@ services: FORGEJO__security__INSTALL_LOCK: "true" # Actions on: repo/org/user-level runners register against this instance. FORGEJO__actions__ENABLED: "true" - # Google SSO account handling. Forgejo only consults ACCOUNT_LINKING during - # the auto-registration path, so auto-registration must be ON for a Google - # login to auto-link (by verified email) to the existing account instead of - # dropping to the manual link/register page. To keep that from letting *any* - # Google user register, the auth source pins a required email claim (added - # via `forgejo admin auth update-oauth --required-claim-name email - # --required-claim-value @gmail.com`), so only that one address can log - # in at all — it collides with the existing account's email and links to it. + # --- Access model: OAuth-only login, multi-user via an approval gate --- + # Login is Google SSO only. Forgejo 9.0.3 has no setting to hide the + # password sign-in form, so "OAuth-only" is enforced operationally: every + # account is given an unusable (random) password and no NEW local account + # can be created (ALLOW_ONLY_EXTERNAL_REGISTRATION). ENABLE_PASSWORD_SIGNIN_FORM + # is set anyway — ignored on 9.0.3, effective if the instance is upgraded. + # Auto-registration stays ON so a Google login auto-links (by verified email) + # to a PRE-CREATED account (`forgejo admin user create --username X --email + # X@gmail.com --random-password`). A single required-claim-value can't + # allowlist more than one email, so instead of pinning one address the + # required-claim-value is CLEARED (a DB change on the auth source, persisted + # in the forgejo_data volume — not re-applied from here) and every NEW signup + # is gated: a stranger who signs in with Google lands INACTIVE + # (REGISTER_MANUAL_CONFIRM) and RESTRICTED (DEFAULT_USER_IS_RESTRICTED) + # pending admin approval, so an un-provisioned Google user gets zero access. FORGEJO__oauth2_client__ACCOUNT_LINKING: "auto" FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION: "true" + FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true" + FORGEJO__service__ENABLE_PASSWORD_SIGNIN_FORM: "false" + FORGEJO__service__REGISTER_MANUAL_CONFIRM: "true" + FORGEJO__service__DEFAULT_USER_IS_RESTRICTED: "true" + # Outbound mail via prod's Postfix null client over the WireGuard mesh + # (10.10.0.1:25 — mynetworks permits beta); self-signed cert on :25, so + # trust it. Send-only; used for admin/approval and notification mail. + FORGEJO__mailer__ENABLED: "true" + FORGEJO__mailer__PROTOCOL: "smtp" + FORGEJO__mailer__SMTP_ADDR: "10.10.0.1" + FORGEJO__mailer__SMTP_PORT: "25" + FORGEJO__mailer__FORCE_TRUST_SERVER_CERT: "true" + FORGEJO__mailer__FROM: "Thermograph Git " # Gitea/Forgejo's app.ini env-mapping honors a __FILE suffix to read a # value from a file instead of the literal env var — same convention as # the official Postgres image's POSTGRES_PASSWORD_FILE above.