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.comemails. - Multi-domain group: patterns
acme.com,acmecorp.dk,*.acme.com— covers a parent + a few subsidiaries. - SSO-only tenant: pattern
acme.complus 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.
- Toggle Enforcement on. (Pre-toggle, the allowlist patterns are saved but advisory — adds still go through.)
- Add one or more patterns. Each pattern is a lowercase hostname:
acme.com— exact match*.acme.com— any subdomain (matcheseu.acme.com,gb.acme.com, …)- Hostnames only —
*alone or full URLs are rejected
- 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:
| Action | Rejected? |
|---|---|
Add a new email at /user/settings/account/email | Yes (Bunny intercept → API returns 403 with the allowed-patterns list) |
| Promote a secondary email to primary | Yes |
| Initial signup (when joining an org with the allowlist already on) | Yes |
| Existing primary email left in place | No — 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 itemail_domains.removed— pattern, who removed itemail_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.