Skip to main content
Private preview. fremforge is in private preview — invited customers only. Content is still subject to change. Request access →
Email-domain allowlist

Email-domain allowlist

The email-domain allowlist is a per-org enforcement rule that constrains which email-address hostnames members can attach to their fremforge user accounts. When enabled, only emails matching one of your configured patterns can be added through the user-settings page or the Forgejo API.

Combined with signed commits and Forgejo’s existing mailer-verified ownership gate, this closes the “user adds attacker@arbitrary-domain.com, then claims commits as that attacker” path during a forensic review.

When to enable it

You want this on for any regulated tenant where commit authorship has to map to a known corporate identity. Typical configurations:

  • Single-domain tenant: pattern acme.com — members can only add @acme.com emails.
  • Multi-domain group: patterns acme.com, acmecorp.dk, *.acme.com — covers a parent + a few subsidiaries.
  • SSO-only tenant: pattern acme.com plus require OIDC sign-in via SSO settings — every member’s email is then both shape-checked AND verified by the IdP.

Configuring

Org admin → Security → Email-domain allowlist.

  1. Toggle Enforcement on. (Pre-toggle, the allowlist patterns are saved but advisory — adds still go through.)
  2. Add one or more patterns. Each pattern is a lowercase hostname:
    • acme.com — exact match
    • *.acme.com — any subdomain (matches eu.acme.com, gb.acme.com, …)
    • Hostnames only — * alone or full URLs are rejected
  3. The admin table lists every existing member whose primary email doesn’t match a current pattern. Resolve those before enabling — otherwise affected members can’t change their email-related settings without removing the violating address first.

Pattern syntax matches the HTML form’s pattern attribute. The server-side validation regex is:

^\*?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$

What gets enforced

When enforcement is on, the following user actions are rejected for an out-of-pattern email:

ActionRejected?
Add a new email at /user/settings/account/emailYes (Bunny intercept → API returns 403 with the allowed-patterns list)
Promote a secondary email to primaryYes
Initial signup (when joining an org with the allowlist already on)Yes
Existing primary email left in placeNo — pre-existing members are NOT auto-evicted (compliance kicks in on next change)

OIDC sign-in is exempt by design. When a user signs in via SSO (build/oidc/), their email comes from the verified email_verified claim on the IdP-signed JWT — the identity is already attested by your IdP, so the local allowlist check would be redundant. The non-conforming table flags these for visibility but doesn’t block them.

Forgejo’s mailer-verified ownership gate runs second. Even if a customer disables the allowlist temporarily, the mailer-verification handshake (Forgejo sends a confirmation link to the new address; the user must click it) is still required to attach the email. The “claim someone else’s commits” attack stays blocked by the mailer gate regardless of allowlist state.

Audit events

Every change emits an audit event consumed by the Org admin → Audit log + the SIEM forwarder:

  • email_domains.added — pattern, who added it
  • email_domains.removed — pattern, who removed it
  • email_domains.policy_toggled — enforcement on/off

Rejected attempts also emit (email_domains.rejected) with the attempted email + matched-or-not state, so an operator chasing a phishing attempt can find every “tried to add a lookalike” event.

Related

  • Authentication policy — the broader policy bundle (hardware keys, max PAT lifetime, signed commits required, SSO-only).
  • OIDC single sign-on — when you’d rather not let users self-manage emails at all.
  • Audit log — where the email-domain audit events surface.