Skip to content

Two-factor authentication ​

A second factor for the staff: a code from an authenticator app that has to be given before you may play.

Who it applies to ​

Everybody with the permission appeltools.command.twofactor. Everybody else is never touched by it — no code, no map, nothing.

A staff member who has the permission:

  • may not move, chat, run a command, take damage, open his inventory or touch something until he has verified himself;
  • gets a map with a QR code the first time he joins, in the first slot of his hotbar;
  • has to run /verify <code> with the code of his authenticator app.

The verification is remembered for a few days for the address he joined with, so he is not asked for a code every day.

Setting it up ​

There are two ways.

The automatic way ​

The first time a staff member joins, the plugin sets the account up for him: a secret is generated, a map with the QR code is drawn and put in the first slot of the hotbar, and the staff member is told to scan it.

The item that was in that slot is not thrown away: the plugin remembers it and gives it back when the verification goes through.

The manual way ​

/2fasetup

The permission is appeltools.command.twofactor andappeltools.command.twofactor.setup. The command also answers to /twofactorsetup and /enroll2fa.

It shows the secret and the link that an authenticator app can read. Use it when the map cannot be scanned — a phone in front of a monitor does not always work.

Verifying ​

/verify 123456

The permission is appeltools.command.twofactor andappeltools.command.twofactor.verify. The command also answers to /2faverify and /twofactorverify.

What happensWhat you see
The code is right"Verified. Have fun."
The code is wrong"That code is not right. Try the next one."
You have no account yet"You have no two-factor account yet. Run /2fasetup first."
The secret cannot be read"The secret of your account could not be read. Ask an admin to reset your two-factor."

The code changes every thirty seconds, so a code that was refused a moment ago may work now.

TIP

/verify is the one command that works before the verification. So is /2fasetup.

The messages ​

Every line that the two-factor shows is a message, so you can change it in messages.yml — the section is called two-factor:

yaml
two-factor:
  held: "<red>You have to verify yourself before you can do anything."
  held-verify: "<gray>Run <white>/verify <your code><gray> to verify yourself."
  held-setup: "<gray>No account yet? Run <white>/2fasetup<gray> to get your secret first."
  chat-refused: "<red>You have to verify yourself before you can chat."
  enrolled: "<yellow>Your two-factor account has been set up."
  enrolled-scan: "<gray>Scan the map that was given to you with your authenticator app, then run <white>/verify <your code>."
  enrolled-setup: "<gray>If you cannot scan the map, run <white>/2fasetup<gray> to get the secret."
  setup-done: "<white>Your two-factor account has been set up."
  setup-failed: "<red>Your two-factor account could not be set up. Ask an admin for help."
  setup-scan: "<gray>Scan the map with your authenticator app, or add the account by hand:"
  setup-secret: "<yellow>Secret: <white>{SECRET}"
  setup-link: "<yellow>Link: <white>{LINK}"
  setup-verify: "<gray>Now run <white>/verify <your code><gray> to verify yourself."
  verified: "<green>Verified. Have fun."
  wrong-code: "<red>That code is not right. Try the next one."
  no-account: "<red>You have no two-factor account yet. Run <white>/2fasetup<red> first."
  no-secret: "<red>The secret of your account could not be read. Ask an admin to reset your two-factor."
  reset-done: "<green>The two-factor account of <white>{PLAYER}<green> was reset. He has to set it up again."
  disabled: "<red>The two-factor authentication is switched off on this server."

The section is on the proxy — that is where the two-factor lives. The backend has four messages of its own, in its own two-factor section: the ones that the reset command shows.

TIP

{SECRET}, {LINK} and {PLAYER} are placeholders. See the messages page for the rest.

The trusted address ​

After a successful verification the address the staff member joined with is trusted for a few days:

yaml
two-factor:
  trusted-ip-days: 3

While the address is trusted, no code is asked. When the address changes — a new home, a new network — the code is asked again.

The trusted addresses are stored in the database, next to the accounts.

The configuration ​

The key lives on the proxy, because that is where the secrets are:

yaml
two-factor:
  enabled: true
  server-key: ""
  trusted-ip-days: 3
KeyDefaultWhat it does
two-factor.enabledtrueThe two-factor is switched on.
two-factor.server-key""The key the secrets are encrypted with. Leave it empty and the proxy writes a random key into the file.
two-factor.trusted-ip-days3How many days an address stays trusted.

The backend has its own two-factor.enabled and two-factor.trusted-ip-days. The backend only enforces it — the proxy owns the state.

WARNING

The server-key is what keeps the secrets of your staff safe in a dump of the database. Leave it empty and the plugin writes a random key for you — but keep a copy of the file, because the secrets cannot be read without that key. Change the key and every secret in the database becomes unreadable, so every staff member has to set the account up again.

When somebody loses the device ​

The account of a player can be reset. The next time he joins, a new secret is generated and a new map is drawn.

WhereCommandPermission
In game/atp 2fa reset <player>appeltools.command.admin and appeltools.command.twofactor.reset
On Discord/2fa-reset <player>a Discord role — see the Discord page

TIP

A staff member who already has an account does not get a map on every join — only the first time. The map would put the secret of the account in the world, and that is exactly what the setup is for.

Built with VitePress.