Documentation menu

Reference

Security model

What a transfer ticket proves, what Link protects against, and what it doesn't.

Hytale moves a player by telling their game to connect to another server, with up to 4 KB of data attached. That data travels through the player’s game, so the server on the other end can’t trust it on its own.

Link puts a signed ticket in that data. It says: the network sent this player from this server to that server, and it is valid for 30 seconds.

What the target checks

Before it treats a connection as a transfer, the target checks that the ticket:

  1. is signed with the network secret (HMAC-SHA256),
  2. names this server as the target,
  3. names this player,
  4. has not expired, allowing 10 seconds of clock difference between servers,
  5. has not been used before on this server.

When every check passes, the log shows:

sw-2Output
[Link] ticket from lobby-1 for Steve: signed, addressed here, 29s left, first use

When one fails, the log says Refused a transfer ticket from <player>, and the connection is handled as a direct join. Link doesn’t say which check failed, because the player could be the one testing it.

What this protects against

  • A player can’t create a ticket, change one, or give theirs to someone else.
  • A player can’t use a ticket for another server than the one it was made for.
  • A player can’t use the same ticket twice.
  • With requireTicket, a player can’t skip the lobby by connecting to a game server’s address.

What it doesn’t

Every server in the network signs with the same secret. So every server can admit any player to every other server. That is fine when you run all the servers yourself.

It also means that anyone who gets the secret can make tickets for your whole network. That includes:

  • a server that is hacked, or runs a plugin you don’t trust,
  • a leaked Redis password or Cloudflare token,
  • a copy of link.json from a shared-file network.

If that happens, change the secret, then restart every server:

  • Shared file: empty secret, start one server to generate a new one, and copy the file everywhere.
  • Redis: delete the <namespace>:secret key and change the Redis password.
  • Cloudflare: the secret is stored in the Durable Object, so a redeploy keeps it. Deploy a new registry under a new name with a new token, and point your servers at it.

Servers you don’t fully trust

If some servers are run by other people, you need a central signer that holds a separate key for each server, so one server can’t make tickets for another. Link doesn’t do that: it is built for a network you run yourself.

Something wrong or missing on this page? Open an issue on GitHub.