auth used to receive the player's Minecraft access token and call the Mojang profile API with it. It's replaced with the flow vanilla online-mode servers use:
auth_challenge(username) -> serverId
The username is validated: 1–16 characters of [A-Za-z0-9_].
The server returns a random 160-bit hex server id and stores {username, serverId} as this connection's pending challenge.
The client calls POST sessionserver.mojang.com/session/minecraft/join with its token and the server id. The token only goes to Mojang.
auth_verify() -> User
The server takes the pending challenge, which is single-use, and calls GET sessionserver.mojang.com/session/minecraft/hasJoined?username=…&serverId=….
Mojang returns the verified profile, and the player is logged in as before (session map, get_put).
A 204 from Mojang means the join didn't happen, and gives "Session not verified by Mojang".
The old auth is removed, not kept alongside, so there's a single implementation. Clients on 0.1.0-beta2 get "Unknown method: auth" and fail to sign in (see Rollout).
Version manifest
GET /versions returns:
{"supported":["0.1.0-beta3"],"deprecated":[]}
The lists come from the comma-separated SUPPORTED_VERSIONS and DEPRECATED_VERSIONS env vars, read at startup. The defaults are 0.1.0-beta3 supported and nothing deprecated.
Both variables are exposed in compose.yaml, so they can be edited in Coolify.
Clients on a deprecated version are warned but still connect. Clients on neither list are warned and don't connect.
Other
reqwest gains the query feature, which 0.13 moved behind a feature flag.
rand 0.9 is added for the server id.
Testing
Local server, driven over a raw WebSocket and HTTP:
/versions returns the configured lists.
The old auth gets "Unknown method: auth".
An invalid username gets "Invalid username".
auth_verify without a challenge gets "No pending challenge".
auth_challenge then auth_verifywithout a Mojang join gets "Session not verified by Mojang". That was a real hasJoined call.
Retrying the verify gets "No pending challenge" (single use).
The Saturn client (1.21.11, real account via DevAuth) against this server:
supported: the full flow. The client joined at Mojang, and the server logged Authenticated Kr4ight (…).
deprecated: warned, then connected.
unsupported: warned, and made no WebSocket connection.
Rollout
Deploying this breaks 0.1.0-beta2 clients immediately, and they don't know about the manifest. Deploy it together with the 0.1.0-beta3 client release. The pasted Coolify compose has no environment: block, but the built-in default (0.1.0-beta3 supported) covers it. Add SUPPORTED_VERSIONS / DEPRECATED_VERSIONS in Coolify to change the lists later.
Server half of saturnclientmc/saturnclient#7. The client half is saturnclientmc/common (mojang-session-auth).
## Summary
### Authentication without the access token
`auth` used to receive the player's **Minecraft access token** and call the Mojang profile API with it. It's replaced with the flow vanilla online-mode servers use:
1. **`auth_challenge(username) -> serverId`**
- The username is validated: 1–16 characters of `[A-Za-z0-9_]`.
- The server returns a random 160-bit hex server id and stores `{username, serverId}` as this connection's pending challenge.
2. **The client** calls `POST sessionserver.mojang.com/session/minecraft/join` with its token and the server id. The token only goes to Mojang.
3. **`auth_verify() -> User`**
- The server takes the pending challenge, which is single-use, and calls `GET sessionserver.mojang.com/session/minecraft/hasJoined?username=…&serverId=…`.
- Mojang returns the verified profile, and the player is logged in as before (session map, `get_put`).
- A `204` from Mojang means the join didn't happen, and gives "Session not verified by Mojang".
The old `auth` is **removed**, not kept alongside, so there's a single implementation. Clients on `0.1.0-beta2` get "Unknown method: auth" and fail to sign in (see Rollout).
### Version manifest
`GET /versions` returns:
```json
{"supported": ["0.1.0-beta3"], "deprecated": []}
```
- The lists come from the comma-separated `SUPPORTED_VERSIONS` and `DEPRECATED_VERSIONS` env vars, read at startup. The defaults are `0.1.0-beta3` supported and nothing deprecated.
- Both variables are exposed in `compose.yaml`, so they can be edited in Coolify.
- Clients on a deprecated version are warned but still connect. Clients on neither list are warned and don't connect.
### Other
- `reqwest` gains the `query` feature, which 0.13 moved behind a feature flag.
- `rand` 0.9 is added for the server id.
## Testing
Local server, driven over a raw WebSocket and HTTP:
- `/versions` returns the configured lists.
- The old `auth` gets "Unknown method: auth".
- An invalid username gets "Invalid username".
- `auth_verify` without a challenge gets "No pending challenge".
- `auth_challenge` then `auth_verify` **without a Mojang join** gets "Session not verified by Mojang". That was a real `hasJoined` call.
- Retrying the verify gets "No pending challenge" (single use).
The Saturn client (1.21.11, real account via DevAuth) against this server:
- **supported:** the full flow. The client joined at Mojang, and the server logged `Authenticated Kr4ight (…)`.
- **deprecated:** warned, then connected.
- **unsupported:** warned, and made no WebSocket connection.
## Rollout
Deploying this breaks `0.1.0-beta2` clients immediately, and they don't know about the manifest. Deploy it together with the `0.1.0-beta3` client release. The pasted Coolify compose has no `environment:` block, but the built-in default (`0.1.0-beta3` supported) covers it. Add `SUPPORTED_VERSIONS` / `DEPRECATED_VERSIONS` in Coolify to change the lists later.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replace `auth` (which received the player's Minecraft access token) with
the vanilla online-mode flow, so the token never reaches this server:
- auth_challenge: validate the username and return a random one-time
server id
- the client calls Mojang's session `join` with its token and that id
- auth_verify: confirm the join with Mojang's `hasJoined` and log the
player in
Add GET /versions returning {"supported": [...], "deprecated": [...]}
from the SUPPORTED_VERSIONS / DEPRECATED_VERSIONS env vars (defaults:
0.1.0-beta3 supported), exposed in compose.yaml.
Refs saturnclientmc/saturnclient#7
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Server half of saturnclientmc/saturnclient#7. The client half is saturnclientmc/common (mojang-session-auth).
Summary
Authentication without the access token
authused to receive the player's Minecraft access token and call the Mojang profile API with it. It's replaced with the flow vanilla online-mode servers use:auth_challenge(username) -> serverId[A-Za-z0-9_].{username, serverId}as this connection's pending challenge.POST sessionserver.mojang.com/session/minecraft/joinwith its token and the server id. The token only goes to Mojang.auth_verify() -> UserGET sessionserver.mojang.com/session/minecraft/hasJoined?username=…&serverId=….get_put).204from Mojang means the join didn't happen, and gives "Session not verified by Mojang".The old
authis removed, not kept alongside, so there's a single implementation. Clients on0.1.0-beta2get "Unknown method: auth" and fail to sign in (see Rollout).Version manifest
GET /versionsreturns:SUPPORTED_VERSIONSandDEPRECATED_VERSIONSenv vars, read at startup. The defaults are0.1.0-beta3supported and nothing deprecated.compose.yaml, so they can be edited in Coolify.Other
reqwestgains thequeryfeature, which 0.13 moved behind a feature flag.rand0.9 is added for the server id.Testing
Local server, driven over a raw WebSocket and HTTP:
/versionsreturns the configured lists.authgets "Unknown method: auth".auth_verifywithout a challenge gets "No pending challenge".auth_challengethenauth_verifywithout a Mojang join gets "Session not verified by Mojang". That was a realhasJoinedcall.The Saturn client (1.21.11, real account via DevAuth) against this server:
Authenticated Kr4ight (…).Rollout
Deploying this breaks
0.1.0-beta2clients immediately, and they don't know about the manifest. Deploy it together with the0.1.0-beta3client release. The pasted Coolify compose has noenvironment:block, but the built-in default (0.1.0-beta3supported) covers it. AddSUPPORTED_VERSIONS/DEPRECATED_VERSIONSin Coolify to change the lists later.🤖 Generated with Claude Code
Replace `auth` (which received the player's Minecraft access token) with the vanilla online-mode flow, so the token never reaches this server: - auth_challenge: validate the username and return a random one-time server id - the client calls Mojang's session `join` with its token and that id - auth_verify: confirm the join with Mojang's `hasJoined` and log the player in Add GET /versions returning {"supported": [...], "deprecated": [...]} from the SUPPORTED_VERSIONS / DEPRECATED_VERSIONS env vars (defaults: 0.1.0-beta3 supported), exposed in compose.yaml. Refs saturnclientmc/saturnclient#7 Co-Authored-By: Claude Opus 5.5 <[email protected]>