# Accounts on an offline server

> A password, a question on Discord, or both — three ways to prove a name is yours where Mojang cannot.

Source: https://stygion.eu/docs/keystone/accounts
Updated: 2026-10-09

A server in offline mode never asks Mojang anything, so **whoever types a name
gets that name** — including yours. This module closes that. Do not switch it on
for a server in online mode: Mojang has already done the work, and asking again
is only a nuisance.

All of it is in `accounts.toml` or on the Settings screen in the editor. Off
until you say otherwise.

## Held, not moved

Somebody who has not proved themselves **stays where they joined**: nothing can
hurt them and nothing they say reaches anybody. There is no lobby world to keep
and no teleport whose destination can be forgotten after a crash.

```
accounts.require = true
```

That is the switch: without it nobody is asked to prove anything and the module
just sits there.

## Three ways to prove it

**A password.**

```
/register <password> <password again>
/login <password>
/password <old> <new>
```

`accounts.least-length` is the shortest password this server accepts. Length is
the one rule worth having — asking for a capital and a digit gets you `Passw0rd`
and nothing else.

**A question on Discord** (`accounts.ask-on-discord`, on). Anybody with a linked
[Discord](/docs/keystone/discord) account gets a direct message: somebody is
joining as you, from where, two buttons. Nothing to remember.

**Protecting bought names** (`accounts.protect-bought-names`, off). A name that
belongs to a real Minecraft account cannot be taken here by somebody who did not
buy it — they are shown `screens.name-not-yours`. `keystone accounts allow
<name>` lets one through when you know it is fine.

## Time and tries

| Setting | What it does |
|---|---|
| `accounts.remember-for` | How long the same machine is let in without asking again — a password and a Discord confirmation alike. Default `1d`; zero turns it off. |
| `accounts.must-prove-within` | How long somebody has before they are disconnected. Default `2m`. |
| `accounts.most-tries` | How many wrong passwords before they are disconnected (default 5). They can reconnect, but past that many on one name from one place each further try waits twice as long as the last (from 30 seconds, at most an hour). It is there to make guessing slow, not to punish. |
| `accounts.hold-name-for` | How long a name is closed after its owner answers **No, that is not me** on Discord. Default `15m`. |

**"The same machine" is not an IP address.** What the database stores is a
*place* — a one-way token under a key your server made for itself. The same
computer still reads as the same computer, and nobody, us included, can turn it
back into an address.

Confirming on Discord is remembered like a password: somebody who confirmed from
this place is not asked at every join. A remembered sign-in ends when the Discord
link is removed or moved, on a ban, a password change, `keystone accounts forget`,
or "that is not me". A place two accounts have proved themselves from — a shared
house, every player behind a proxy — is never remembered.

**Until somebody has proved who they are, they hold nothing.** On an offline-mode
server a name is all an operator's identity is, so a held player has no operator
rights, no group and no permission, and the game drops every packet from them
except the few that keep the connection up and carry `/login`: no chat, no
blocks, no inventories.

Guessing passwords costs time, and cannot lock the owner out: a name has a budget
of ten wrong passwords an hour from places it has never been used from, and then
passwords from those places rest for the hour; the owner's usual place is not held
to it, and the question on Discord is never held back. A place guessing at many
names is slowed, never locked. Somebody joining as you over and over no longer
pings you every time: one question a minute and five an hour from one place.

## Running it

```
keystone accounts                      # how many have a password, who is waiting, who was refused
keystone accounts forget <player>      # remove a password so they set a new one
keystone accounts allow <name>         # let one bought name through, once
keystone accounts attempts <name>      # who was refused at this door, and why
```

The permission is `keystone.accounts.admin`.

**`forget` is the only password recovery there is, and it is deliberately a
person's decision.** On a server with no email addresses, "I forgot my password"
and "I am pretending to be them" arrive looking exactly alike.

## The screens

`screens.name-held` and `screens.name-not-yours` in `operations.toml` — what
somebody reads when a name is closed or belongs to an account that was bought.
Both take `{player}`, `{left}` and `{appeal}`.
