Docs
Set it up
This copy runs only on its owner's servers. To use AltWarden on your own, host your own copy, then follow these steps.
- Add AltWarden to your server with the link it writes to its log when it starts. Only the owner of the Discord app can use that link while Public Bot is off in the Discord Developer Portal, and it should stay off. The link asks for Administrator by default.
- In Server Settings, Roles, drag AltWarden's role above the role it will give out. Administrator doesn't change this, because Discord only lets a bot give roles below its own highest role.
- Open the dashboard, or run
/setup, and pick a verified role and a verification channel. Unless you're an Administrator, the role has to sit below your own highest role. - Lock your channels so only the verified role can see them, and leave the verification channel visible.
- Open Health on the dashboard, or run
/health, to catch anything missing.
Switching from another bot? Press Import members on the Members page, or run /import-members, with the role your members already hold. They're marked verified, and they won't be asked to verify while they stay in the server. No roles are given, so anyone missing the verified role gets it by pressing Verify, with no checks. Someone who leaves and rejoins verifies again, unless you turn on Remember verified members.
Lock down your server
Set the verification channel so new members can read it but can't chat in it.
| Permission in the channel | @everyone | AltWarden |
|---|---|---|
| View Channel | Allow | Allow |
| Read Message History | Allow | Allow |
| Send Messages | Deny | Allow |
| Embed Links | Allow |
Then choose one of two ways to keep new members out of everything else.
- Unlock with the verified role. On each channel or category, deny View Channel for @everyone and allow it for the verified role. Keep the verification channel visible to @everyone.
- Restrict with an unverified role. Turn on the unverified role in Rules. On each channel or category, deny View Channel for that role, and allow it in the verification channel. This keeps your current permissions, but members who joined earlier won't have the role.
Verification modes
| Mode | What the member does | Checks that run |
|---|---|---|
| Web page | Opens a private link and signs in with Discord | All of them |
| Button | Presses Verify in the channel | Account age, profile picture, attempt limit, cooldown |
| Instant | Nothing | Account age, profile picture, attempt limit, cooldown |
Actions
| Action | What happens |
|---|---|
| Watch | The match is recorded and the member gets in. Use this to learn what a rule would catch. No preset is built on it, so a rule watches only when you set it to. |
| Deny | The member isn't verified and can try again. |
| Kick | The member is told by DM, then kicked. |
| Ban | The member is told by DM, then banned. |
Every enabled check runs on an attempt, and the strongest action wins. A failure set to Deny can't hide a match set to Ban. Two things end an attempt before that: a cooldown still running, and an attempt limit already used up with its action on Deny. Neither sends a DM or a log line, or records an attempt. In Instant mode there is no page to show the answer on, so each rejoin past the limit gets one DM.
Rules
Every rule is optional. Rules that can't run in the current mode stay saved, and the Rules page marks them as paused.
| Rule | What it catches | Runs in |
|---|---|---|
| Attempt limit | Too many failed tries. The limit's action applies on the attempt that reaches it, and the stronger of that and the failed check's action wins. Attempts can come back after 5 minutes to 30 days, or never. Members see how many tries they have left, and when attempts come back. | Every mode |
| Account age | Accounts younger than a set age, up to 10 years. Members are told when they'll be old enough. | Every mode |
| Profile picture | Accounts with no picture. | Every mode |
| Cooldown | Retries too soon after a failure. A wait isn't a failure, so it isn't logged. | Every mode |
| Two-factor login | Accounts without two-factor login. | Web page |
| Throwaway email | Accounts on a temporary inbox, and accounts with no verified email at all. Only the domain is checked, so a verified address at a major provider always passes. | Web page |
| Alt accounts | A second account of someone who verified here, even one who left or was banned. An account that tried and never got in doesn't count. See how alt matching works. | Web page |
| VPN and proxy | VPNs, proxies, Tor, data centers and iCloud Private Relay, from lists searched in memory. A server can add an outside lookup. | Web page |
| Mobile data | Carrier networks, by the address or by what the browser reports. | Web page |
| Country rules | A block list or an allow list, with an action per continent, region or country. On an allow list, an address the lists can't place doesn't pass, once a country list has loaded for that kind of address. Logs never show a member's country. | Web page |
| Automated browser | Browsers driven by Selenium, Puppeteer and similar tools, and reports a real page couldn't have sent, such as one with sections missing or from a browser that drops the device cookie. | Web page |
| Anti-detect browser | Browsers that invent a new device for every profile, seen as functions rewritten across two or more families, or a worker that sees a different device. | Web page |
| Browser tampering | Rewritten built-in functions, scored from 1 to 100. | Web page |
| Fake browser identity | A browser claiming to be a different browser or system. | Web page |
| Developer tools | Developer tools open during the check, and scripts driving the browser through them. Not available on Safari or phones. | Web page |
| Private window | Private and incognito windows. Chrome's Guest mode can read as one too. | Web page |
| Fingerprint blocking | Browsers that randomize or hide device details: Brave with Shields up, Tor Browser, Firefox with fingerprint resistance or canvas noise, blocked verification scripts, and extensions that wrap the canvas or hide the graphics chip. Safari's own canvas noise doesn't count. | Web page |
| Threat score | Two scores. The bot score rates automation, and the suspect score adds up many small signals. | Web page |
| Virtual machine | Virtual machines and software graphics. A PC with hardware acceleration off looks like a virtual machine with 3D off, so it counts, and the member is told how to turn acceleration on. | Web page |
| Modified phone | Android emulators, and Pixel phones whose model doesn't fit their graphics chip or whose Android is newer than that model ever got. | Web page |
Presets
| Preset | Meant for |
|---|---|
| Gentle | Stops throwaway emails, fake browser identities and alt accounts. Everything else stays off. Two-factor login keeps its own setting. All three deny, so nobody is removed. |
| Standard | Stops anyone who fails a check. Kicks fake browser identities and alt accounts. The default. An alt of a banned account is banned. Denied members can try again, up to 5 times, and attempts come back after a day. Profile picture and Mobile data stay off. |
| Strict | For servers under attack. Kicks or bans on most failures, and removes anyone who doesn't verify within 10 minutes. Accounts must be 30 days old. Three failed attempts end it for good. Alts are banned, and the earlier account is kicked. Mobile data, Developer tools and Fingerprint blocking deny. |
A preset changes nothing until you save. It sets every check it covers, with that check's thresholds, so your own numbers for those checks are replaced. It turns on Auto DM and the closed-DM notice at 30 seconds. Strict turns Auto Kick on at 10 minutes, and the other two turn it off. A preset never touches roles, channels, messages, logs, alerts, country rules, the help desk, the honeypot, cooldown or the two-factor rule.
How alt matching works
When someone verifies, AltWarden compares their connection and browser with every account that has verified in your server before, even one that left or was banned. Any one match makes the new account an alt of the earlier one, and the action you choose applies. Matches only ever compare accounts in your own server.
| Evidence | What it matches |
|---|---|
| Same connection | The same internet connection. A VPN address or a carrier's shared IPv4 address doesn't make a match alone. |
| Same browser cookie | The same browser, using a signed cookie set on the verification page. |
| Same browser fingerprint | The same browser setup. On a phone, tablet or Chromebook, it doesn't make a match alone. |
The log shows both accounts, what matched, how strong the match is, and whether their operating system and browser also match. A cookie match is confirmed, the same connection is likely, and a fingerprint alone is possible. Your setting for which matches to act on starts at any match.
A match to a banned account counts from a score of 60, whatever your setting. A match below your setting, to an account that verified or was banned, is recorded as Watch.
The account that verified first counts as the main one. If it verifies again later, it gets the action for the main account, not the action for an alt.
An alt of a banned account has its own action, so you can ban ban evaders and only deny everyone else. If two accounts are really two people, approve the appeal with "trust the link", or run /trust-accounts, and they won't match again. Trusting also gives both accounts their attempts back and takes the limit role away. A plain Approve lets the member in now and leaves the link standing, so it stops them again if they rejoin.
Outside VPN lookup
A server can add a proxycheck.io key on the Rules page. The key is encrypted when it's stored, and a key proxycheck.io doesn't recognize is refused. AltWarden asks only when the answer could change the result: the VPN or Threat check is on, the lists haven't already flagged the address, the address is public, and the member isn't past a limit or skipping the VPN check. An answer is kept for an hour per network. One network, meaning an IPv6 /48 or an IPv4 /24, can spend at most 50 lookups a day, and past that the check runs on the lists alone. One member can spend at most 20 lookups a day. With the attempt limit off, a member past that counts as on a VPN, because twenty networks in a day isn't someone at home.
A failed or skipped lookup stops nobody, because anyone can use up a quota by verifying over and over. When a lookup fails, staff are told once a day in the log and on the Health page until one works again.
Staff tools
Logs. Each rule has its own log module, and staff actions, verified members, Auto Kick, the help desk, the honeypot, raids, appeals and settings changes each have one too. Send each to its own channel, a whole category to one channel, or everything to one channel. Logs never show an IP address, email, cookie, fingerprint or country.
Alerts. On by default. Pick one role, and it's pinged in the log channel when a check stops someone, the honeypot catches someone, a raid starts or an appeal comes in. Customize turns any of these off, adds routine logs, or gives one its own role.
Auto Kick. Removes members who don't verify within a time you set, from 5 minutes to 7 days. They get one reminder halfway through, and a member removed this way can rejoin and try again.
Bypass links. A link for one member that skips the checks you pick, for 1 to 168 hours. Every other check still runs, even on a server in Button mode. The link is shown to you once, and it's never posted in a log or a channel. If you choose to notify in a channel, the member is pinged in the verification channel, and presses Verify to get it. With Auto Kick on, the member's time to verify starts when the link ends.
Help desk. Adds a help button that opens a private thread with your support role. The first message is pinned, lists the member's failed attempts, by time alone if the server hides reasons, and has Verify and Bypass buttons for staff. Threads archive after a week of quiet, reopen when the member presses the button again, and close when the member leaves.
Honeypot. Anything posted in the trap channel is deleted, and the account is logged, timed out, kicked, softbanned or banned. A member is told by DM first and can appeal. Posts in threads under the channel are caught too. Roles you whitelist are ignored. Posts by bots and webhooks are only deleted and logged, because any member can make another bot post there.
Appeals. Members who were stopped can explain themselves for 7 days after a failed attempt, once per failure, and a try past a used-up limit counts as a new failure. Staff decide with buttons in Discord or on the dashboard. The decision goes by DM and shows on the appeal page, because Discord won't deliver a DM to someone who left the server. Approving an appeal from a banned account lifts the ban, so it takes Ban Members. Approving a honeypot appeal also ends a timeout.
Raid mode. When joins spike, the rules tighten for a while and staff are alerted. A raid only ever makes a rule stricter. You can also start it with /raid.
Messages
The Messages page edits the verification message, the first message of each help thread, and the honeypot warning, with a live preview. The verification message is posted again when you change it, change the channel, or turn the help desk on or off. A changed message names the staff member who wrote it, with a link to report it.
The same page sets AltWarden's profile in your server: one of eight pictures, a name, a bio, and a name style with any of 12 fonts and 7 effects. If Discord refuses a style, the page says so and the rest still saves.
Who can do what
The Access page sets who can open each dashboard page and run each command, using Discord's own order. A member override decides first, then roles, then Everyone, then the required permissions. The server owner and Administrators always pass, so nobody gets locked out. Commands can also be limited to chosen channels. Anyone else can change a rule only if they pass it now and hold every permission in its default.
The page also shows Discord's own command permissions, the same ones as Server Settings, Integrations. These decide who sees a command in Discord's list. Out of the box, Discord lists each staff command only for people with the permission it needs. To let a role without that permission use a command, allow it in Discord's list. That one allow is enough for slash commands and right-click commands while the command's rule on the Access page is still its default: Discord shows the command, and AltWarden lets it run, because setting an allow there takes Manage Server and Manage Roles. A rule you change there is final, so a block or a raised permission holds against anyone who adds themselves on Discord's side. A deny on Discord's side also refuses the help thread's staff buttons that stand in for that command. An allow only on AltWarden's rule also lets someone run the command, but Discord keeps hiding it from them, so the page offers to load it into Discord's list. Discord only takes changes to them from a person's account, so saving asks you to approve the change on Discord once. AltWarden makes the change and ends that approval straight away, and keeps no token.
Commands
| Command | What it does | Who can run it by default |
|---|---|---|
/setup | Sets the verified role and channel, and posts the message. Works only on a server not set up yet. | Manage Server |
/settings | Posts publicly which checks are on, and never what each one does. | Manage Server |
/post-message | Posts the verification or honeypot message again. | Manage Server |
/health | Finds what would stop members from verifying, and notes what's worth a look, such as channels everyone can read. | Manage Server |
/verify-user | Verifies a member yourself. | Manage Roles |
/reset-user | Clears a member's records so they verify again. A banned account keeps its hashes, a connection hash ends on its own date, and the first date it verified stays. | Manage Roles |
/create-bypass | Makes a link that skips the checks you choose, for one member. | Manage Roles |
/lookup | Shows a member's history and links. | Manage Roles |
/trust-accounts | Marks two accounts as different people. | Manage Roles |
/import-members | Marks everyone with a role as verified. | Manage Server and Manage Roles |
/raid | Turns raid mode on or off. | Manage Server and Kick Members |
/uninstall | Deletes all settings and records for the server. It tells the staff log first, and hands you your rules as a code you can paste into a new setup. | Administrator |
/my-data | Links anyone to their own data. | Anyone |
/help, /ping | Links, and a speed check. | Anyone |
Right-click a member and open Apps for Verify, Reset, Create Bypass and Lookup. Each follows the rule of the slash command it stands in for. The Access page on the dashboard controls who can use each one, and where.
Acting on a member has its own limits, whoever is asking. Unless you're an Administrator or the owner, you can't act on someone whose highest role is at or above yours, you can't give a verified role that sits at or above yours, and resetting or trusting a banned account takes Ban Members.
Integrations
The Integrations page sends signed webhooks for member.verified, member.failed, appeal.opened, appeal.decided, raid.started and raid.ended. Check the signature by computing HMAC-SHA256 of t.body with your secret.
X-AltWarden-Signature: t=1793760000,v1=5f2b...
API keys answer one question, whether a member is verified:
GET /api/v1/guilds/{guild}/members/{user}
Authorization: Bearer aw_...
{"verified": true, "verified_at": 1793760000.0}
Common problems
| What you see | What to do |
|---|---|
| Members don't get the role | In Server Settings, Roles, drag AltWarden's role above the role it gives, and check it has Manage Roles. If you recreated the role, pick the new one on the Rules page. |
| A member says the link doesn't work | Links last an hour, or your Auto Kick time, and stop working once used or replaced. The member can press Verify in the channel for a new one. |
| Your server isn't on the dashboard | You need access to at least one page, which by default means Manage Server, or Manage Roles for the Appeals page. AltWarden also has to be in that server. Reload the page after adding it. |
| The verification message is gone | Run /post-message, or press Post it again on the Messages page. |
| New members no longer see Discord's rules screen | Discord skips that screen for anyone given a role, so the Unverified role turns it off. Leave that role off if you rely on the screen. |
| A real member keeps failing one check | Send a bypass link that skips only that check, or verify them yourself with /verify-user. |
| A member wants their data deleted | They can do it themselves at My data, with no request to you or anyone else. |
For anything else, run /health first, then open an issue on GitHub.
Host it yourself
AltWarden is one Python process with a SQLite file. See the README.