open source · ejabberd module · 04
mod_signup_keyword
Keyword-gated registration for ejabberd.
A custom ejabberd module that gates XEP-0077 in-band registration behind one reusable shared keyword — the simplest onboarding model for a small or private XMPP server, where you want friends-of-friends to self-register without per-person invite tokens.
01 Built on ejabberd
One shared keyword
Give your friends one word. Anyone who has it registers themselves over in-band registration; everyone else is turned away. Lowest-friction onboarding for a personal server.
Standard IBR, untouched
Sits on XEP-0077 in-band registration and surfaces the keyword as a XEP-0004 data-form field. Clients that render data forms generically — including Mach — need zero changes.
Reuses ejabberd auth
Accounts go straight through ejabberd_auth:try_register/3, so SCRAM hashing and your existing Mnesia or SQL storage stack are reused unchanged. No parallel user database.
Constant-time gate
The keyword is compared in constant time — no timing side-channel — and the keyword itself is never logged. Only the source IP and attempted username are recorded on a failed attempt.
02 What it is
ejabberd ships two registration models, and both are awkward for a personal server. Open in-band registration lets anyone on the internet create accounts — a spam magnet. XEP-0445 invite tokens are single-use, so you must mint one per person. mod_signup_keyword splits the difference: one shared keyword for everyone, rotated when you like.
The keyword is a password gate on in-band registration. The server returns a data form with username, password, and keyword fields; it validates the keyword in constant time and creates the account only on a match. The honest trade-off is that a leaked keyword lets anyone register until you rotate it — strictly weaker than per-person tokens, by design.
03 How it works
- 01
Compile
Build the .beam against your ejabberd tree with erlc. One expected warning — behaviour gen_mod undefined — resolves at load time once ejabberd is on the code path.
- 02
Configure
Add mod_signup_keyword to ejabberd.yml with your keyword, a welcome message, reserved usernames, and a per-IP rate limit. Do not load mod_register alongside it — both own the register namespace and will conflict.
- 03
Restart
Restart ejabberd (systemctl, or stopsrc/startsrc on AIX). The module advertises register and answers the jabber:iq:register IQ handler.
- 04
Verify
Run the bundled test script against your host to confirm the form advertises the keyword field, then hand the keyword to the people you want on the server.
04 What’s in it
Per-IP rate limiting
A module-level registration_timeout_ms throttle (10 min default) — ejabberd’s top-level registration_timeout does not apply, since this module replaces mod_register.
Reserved usernames
Common admin names — admin, root, support, info — can’t be claimed even with the right keyword. Editable in config.
Welcome message
An optional message body sent to each newly registered user. Empty string to disable.
Standard error mapping
Wrong keyword, taken username, malformed JID, weak password, and rate limiting each return the appropriate XMPP error stanza.
Keyword never logged
Failed attempts log the source IP and attempted username only. The keyword stays on-box and out of source control.
No dependencies
Erlang/OTP and ejabberd, nothing else. A single .beam file dropped into your ebin directory.
05 Get it
mod_signup_keyword is open source, GPL-2.0-or-later (the same licence as ejabberd, since it is a derivative work). The source, configuration reference, and an end-to-end test script live on GitHub.
View on GitHubVerified with Mach — Mach detects the keyword field and renders it as an invite-code input, no changes required.