Skip to content
jack edited this page Jun 25, 2026 · 17 revisions

The Wawel Auth server module allows to configure accepted auth providers, and also to self-host a provider on the local game server. It provides an admin web UI to manage Wawel Auth configuration, as well as server.properties. It also provides a configurable public website.

The following conditions have to be met for the server module to run:

  • The server module ha to be enabled in server.json (wawelAuthEnabled=true)
  • The server must be in online mode
  • publicBaseUrl must be configured

Note

On IPv6-only hosts, add -Djava.net.preferIPv6Addresses=true to the server JVM arguments. Java prefers IPv4 addresses by default, so outbound requests to auth providers will fail even when the providers are reachable over IPv6.

The remaining configuration options documentation follows:

apiRoot

apiRoot is the relative path under publicBaseUrl where the Yggdrasil/auth API is mounted.

For example, if publicBaseUrl = "play.example.com:25565" and apiRoot = "auth", the effective API root becomes http://play.example.com:25565/auth.

apiRoot must be a relative path such as auth or auth/v2. It must not be configured as a full URL. If it is left empty, the auth API is mounted directly at the base URL root.

publicPagePath

publicPagePath is the mount path of the public website served by Wawel Auth.

If it is set to /, the website is served from the root of the public HTTP server. If it is set to something like /info, the website moves there instead, if you wish to keep the root path free for something else.

publicInfoApiPath

publicInfoApiPath is the path of the public JSON endpoint used by the bundled landing page to display server information.

By default, it is a relative path, so it is resolved under publicPagePath. For example, with publicPagePath = "/" and publicInfoApiPath = "__server-info", the endpoint is served at /__server-info. If publicPagePath = "/info", the same setting becomes /info/__server-info.

Set publicInfoApiPath to an empty string to disable it.

Caution

Make sure that apiRoot and publicPagePath do not conflict.

server-address

This is the game server address used by clients. Used only for the public page info for now.

skinDomains

skinDomains is the list of domains from which clients should accept texture URLs.

If your local Wawel Auth provider serves skins or capes, the domain used for those texture URLs must be allowed here, otherwise clients may reject them. In most setups, you only need the server's own host, and when publicBaseUrl is configured, Wawel Auth automatically adds the effective API root host to skinDomains at runtime. You can also add extra domains manually, for example if textures are served from a separate CDN. Use domain names only, not full URLs.

meta

meta contains public-facing metadata used by Wawel Auth when presenting the server to users and tools. It controls the optional homepage link, optional registration link, and the public description shown on the bundled website. It also contributes metadata to the Yggdrasil API root response. The configurable fields are serverHomepage, serverRegister, and publicDescription.

features

features groups provider feature flags. The available fields are legacySkinApi, noMojangNamespace, and usernameCheck.

At the moment, only usernameCheck changes server behavior: when enabled, local usernames are validated against registration.playerNameRegex during registration and local account creation. legacySkinApi and noMojangNamespace are currently metadata-only flags used by Yggrdasil/authlib API consumers.

registration

registration controls who can create local Wawel Auth accounts and what defaults newly created local profiles receive. The main field is policy, which can be OPEN, INVITE_ONLY, or CLOSED. playerNameRegex defines the allowed username pattern for local registration when features.usernameCheck is enabled. defaultUploadableTextures defines which texture types local accounts are allowed to upload. Allowrd options: skin and cape.

invites

Currently only holds one config option concerning invites: invites.defaultUses. Defines how many times an invite can be used to create a local account.

textures

Different texture size and dimension related settings. Contains the following fields:

  • maxSkinWidth, maxSkinHeight
  • maxCapeWidth, maxCapeHeight
  • maxFileSizeBytes (handles skins, non-animated capes, and elytras)
  • allowElytra (enables elytra texture uploads and profile publication)
  • allowAnimatedCapes
  • maxCapeFrameCount
  • maxAnimatedCapeFileSizeBytes

Note

Despite setting high limits in this section, files larger than http.maxContentLengthBytes will still be rejected.

tokens

  • tokens.maxPerUser: Maximum number of active access tokens a single user may hold at once. An access token is created for a client on login, for example in a launcher.
  • tokens.sessionTimeoutMs: Time window in which the server has to verify a join session, in milliseconds.

rateLimits

rateLimits controls app-level limits for public authentication endpoints. This is separate from nginx or firewall rate limiting and still applies when Wawel Auth is reached directly.

  • enabled: Enables or disables Wawel Auth rate limiting.
  • adminLoginAttempts and adminLoginWindowSeconds: Failed admin login attempts per client IP.
  • passwordIpAttempts, passwordSubjectAttempts, and passwordWindowSeconds: Failed password checks per client IP and per account.
  • tokenIpAttempts and tokenWindowSeconds: Token refresh/validate/invalidate requests per client IP.
  • registrationIpAttempts, registrationSubjectAttempts, and registrationWindowSeconds: Registration attempts per client IP and per username.

http

http contains transport settings and limits for Wawel Auth's HTTP server.

  • httpsEnabled: Enables HTTPS on the unified Minecraft/HTTP port. Default: true.
  • readTimeoutSeconds: Controls how long a plain HTTP connection may sit idle while a request is being read.
  • tlsHandshakeTimeoutSeconds: Controls how long a same-port HTTPS connection may spend in the TLS handshake.
  • maxContentLengthBytes: Limits the maximum HTTP request body size.

These settings only apply after Wawel Auth detects HTTP or HTTPS traffic. The Minecraft protocol branch keeps the normal Minecraft networking behavior.

admin

admin controls the built-in admin panel and its authentication. enabled turns the /admin UI and /api/wawelauth/admin/* endpoints on or off, token or tokenEnvVar provide the login secret, and sessionTtlMs controls how long an authenticated admin web session remains valid.

Admin login and authenticated admin API calls require HTTPS. Same-port HTTPS is controlled by http.httpsEnabled.

Tip

Using an environment variable is recommended in a real setup.

Server Keypair

When the local provider runs for the first time, Wawel Auth generates an RSA-4096 keypair and stores it as config/wawelauth/data/private.der and config/wawelauth/data/public.der (the private key is restricted to owner-only permissions on POSIX systems). The private key signs profile properties such as textures, and the public key is published in the Yggdrasil API root response as signaturePublickey, so clients can verify those signatures. This keypair is separate from the HTTPS certificate used by the admin web UI. If one of the two key files goes missing or becomes unreadable, the server refuses to start; delete both files to regenerate a fresh keypair.

Rotating the keypair affects clients. Wawel Auth clients identify a server's local provider by its public key fingerprint, not its address, so after a rotation the server shows up as a new, untrusted provider: players have to trust it again, and a fresh provider entry is created on the client while existing accounts stay bound to the old one.

Scoped Commands

Player-list management commands that need unambiguous identity are provider-scoped with Wawel Auth: /command player@provider. This applies to whitelist, op/deop, ban, and pardon commands.

Examples: /op player@elyby, /ban player@elyby, /pardon player@elyby

Plain player names only resolve when the exact matching player is online. Use player@provider for stable offline lookups.

local, localauth, wawelauth, or self are valid local account aliases.

Clone this wiki locally