Tags
Creators
Details
v0.4.0-beta.1-mc1.21.1
Compatibility
Required content
Changes
Security release. Beta: every change here is covered by tests — 361 of them, up from zero — but none has been soaked on a live server. Please try it on something you can restart.
Read this first — behaviour that changes for admins
- Operators no longer skip authentication.
vouch.bypass.authused to fall back to OP level 4. On an offline-mode serverops.jsonmatches the offline UUID derived from a username, which is exactly what a cracked client gets by joining under an operator's name — so typing an operator's name skipped the whole mod. It now requires an explicit grant from a permission provider, and on an offline server the holder must also arrive through premium login. session.bind_to_ipandsession.bind_to_uuidare gone. Withbind_to_ip = falsea session was validated by UUID alone, which on an offline server means "anyone who knows the username, from anywhere".bind_to_uuidwas documented but read by nothing. Old keys are ignored with a startup warning.- New:
session.require_2fa_on_restore, on by default. A restored session is not a second factor. - A Mojang outage now disconnects premium players instead of quietly admitting them as offline accounts — which cost them their world data and left their username claimable. Set
auth.premium_offline_by_defaultif you prefer the lookup skipped entirely. database.type = "sqlite"now fails at startup with a clear message. The driver was never bundled, so it always failed — just further along and less legibly.- Malformed config is now fatal. Vouch previously logged the error, silently substituted defaults, and overwrote your
vouch.tomlwith only the keys it knew — losing comments, unknown keys, and any${ENV:...}reference, whose resolved secret it then wrote to disk in cleartext. A config it cannot read now stops the server instead.
Fixed
Unauthenticated players could run commands. The pre-auth jail only blocked chat. Since 1.19 commands travel on their own packet, so anything at permission level 0 went through — /msg defeated the chat block outright, and on a modded server /tpa, /home and /kit were all reachable. Commands and inventory are now blocked, matched on the command root, with minecraft:me-style namespacing handled.
Premium status was inferred, not verified. A player was treated as premium if their UUID merely differed from the offline UUID for their name. Geyser/Floodgate and proxies in legacy forwarding mode both produce such a UUID, so anything that could present one got password-less login. The login handler now records what it actually verified.
Changing an Argon2 setting locked out every player, permanently. Parameters were not stored with the hash, so verify recomputed using whatever the config currently said. Hashes are now PHC-encoded and carry their own parameters; existing hashes still verify and are upgraded transparently on next login.
Any schema change would have broken every existing server. There was no versioning — CREATE TABLE IF NOT EXISTS silently ignores added columns on an existing table. There is now a version table and a migration ladder. Its first migration also repairs MySQL installs that were left without vouch_premium_overrides, because the old index DDL was invalid on MySQL and aborted the rest of schema setup.
A slow Mojang could freeze the server. The login path blocked a shared Netty I/O thread on an HTTP call; eight connections could stall I/O for everyone already online. It is now fully asynchronous with explicit timeouts.
A 2FA bypass under database load, an unbounded memory leak on the login-rejection path, unlimited brute-forcing of 2FA codes, and a rate limiter that reset on a correct password even when the second factor then failed.
Added
/vouch password <old> <new> and /vouch admin user <player> resetpw <new> — until now the documented recovery was to delete the account.
Reworked command surface. /login, /register and /logout stay flat, with /l and /reg aliases; everything else lives under /vouch. Tab-completion is now state-aware — an unauthenticated player is offered only what can log them in — and admin commands suggest real player names. /2fa, /auth and /vouch markAsOnline keep working.
Please report
Anything around login on a real server, and the schema migration if you run MySQL or PostgreSQL with existing data — that path is tested against H2 and reasoned through for the others.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:E4nhP7pz:qfx526I6"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:E4nhP7pz:qfx526I6"
}

