17 KiB
ShaCraft Launcher — agent context
Purpose and scope
Cross-platform desktop launcher for the ShaCraft Minecraft network. It is a
Tauri 2 application: React/Vite is the UI and Rust owns all filesystem,
network and process-adjacent work. Profiles are Aeronautics (Minecraft 1.21.1, NeoForge 21.1.248, Java 21)
and Minigames (Minecraft 26.2, Fabric 0.19.5, Java 25). See the Minigames
integration record below and docs/release-0.1.6.md for publication evidence.
This repository owns the launcher only. The server-side API and published
payload are in /root/shacraft on the ShaCraft host; see
docs/launcher-architecture.md before changing an integration boundary.
Non-negotiable boundaries
- Launcher-managed payload is limited to ShaCraft-owned configuration and approved modpack files. Never make arbitrary URLs, shell commands, or local paths controllable by a remote manifest.
- Do not add private keys, OAuth secrets,
.envvalues, player data, or built artifacts to Git.
Trust model
- The only supported remote profile manifest endpoints are the fixed
https://shacraft.ru/api/launcher/v2/profiles/aeronautics/signed-manifestandhttps://shacraft.ru/api/launcher/v2/profiles/minigames/signed-manifest. The read-only Aeronautics player-count endpointhttps://shacraft.ru/api/online/aocis also hardcoded inremote.rs; it is display-only and is never allowed to influence downloads or launching. - The response is an Ed25519 envelope.
src-tauri/src/remote.rsverifies its embedded public key andkeyIdbefore parsing the payload. src-tauri/src/manifest.rsthen validates paths, SHA-256, sizes, HTTPS and allowed ShaCraft hosts. Do not weaken this whitelist.src-tauri/src/profile.rsdownloads to a temporary sibling file, verifies size + SHA-256, and atomically replaces only launcher-managed files.- This ShaCraft manifest is the only source of truth for which
Minecraft version / NeoForge version / Java major a profile needs
(
Manifest.minecraft) and for mod/config files. It never supplies a URL for the game itself — seedocs/game-trust-boundary.mdfor the four independent, hardcoded-host trust domains (Mojang, NeoForge, Microsoft, Adoptium) that install and run the actual game. Do not let manifest data control a URL in any of those domains. - ShaCraft accounts:
src-tauri/src/shacraft_account.rstalks only to the hardcodedhttps://shacraft.ruorigin. Passwords are never persisted. The revocable session token is stored locally with mode 600 on Unix and never passed to Java. The new admission flow uses fixed POST endpoints/api/launcher/v2/admission/nicknameand/api/launcher/v2/admission/tickets; redirects are rejected. Neither the manifest nor the webview can select their origin or URL. - Free nicknames are claimed directly for the authenticated account. Existing player names are reserved server-side and assigned by an administrator; deleting a website account must not make an existing player's name free.
- After installation,
admission.rsgenerates an ephemeral Ed25519 key with the OS CSPRNG. The backend binds its public key to a one-use ticket, current account session, canonicalaocnickname and server access. Only that returned nickname selects launch identity;settings.jsonis never a fallback. Ticket and PKCS#8 private key go only in the final Java child's environment (SHACRAFT_ADMISSION_TICKET,SHACRAFT_ADMISSION_PRIVATE_KEY). Never put them in global environment, argv/argfiles, settings, logs or IPC. A fresh launch obtains a fresh ticket; there is no shared launcher secret. - Once admission is enforced on Aeronautics, its server mod verifies the
challenge/proof before world entry, and server-side whitelist enforcement
remains a final access boundary. Replace LoginSystem only as part of the
validated
aocrollout; other servers are unaffected. Old launchers without admission proof will be rejected after enforcement. This authenticates an account's permission, not the integrity of an unmodified launcher binary. - Application updates are a separate trust domain from Minecraft profiles.
The only channel is
https://shacraft.ru/launcher/updates/stable.json. Both release metadata and the installer need a valid Minisign signature under the separate updater public key embedded intauri.conf.json. Never reuse the profile signing key, accept unsigned metadata, or allow IPC to select an update URL, key, version, installer argument or destination. Downloads require HTTPS without redirects on exactshacraft.ru, below/downloads/shacraft-launcher/<signed-version>/, and are bounded to 256 MiB. Stable versions must increase. The native layer owns every candidate. - Linux self-update supports AppImage and an installed
sha-craft-launcherdeb. AppImage preserves executable permissions and uses same-directory atomic replacement after verification. Deb selects only the signedlinux-x86_64-debentry; retain legacylinux-x86_64AppImage metadata for installed 0.1.3 clients. Never silently switch installation formats. - Deb elevation uses only
/usr/bin/pkexec --disable-internal-agentand the root-owned installed/usr/bin/shacraft-launcher --shacraft-install-deb. This early helper mode never starts GTK/Tauri or account/network code. It receives bounded metadata/package bytes over stdin, not paths or commands, and re-verifies both signatures with the embedded key as root. Before the fixed dpkg installation, require exact package name, architecture and signed version, root-only staging and monotonic installed-package version; pass--refuse-downgradeto dpkg to close concurrent-update races. No system password collection, sudo fallback or permissive polkit policy is allowed. Cancellation, denied authorization and a busy package manager stay distinct. Windows/macOS use the pinned Tauri installer implementation; the vendored updater change only exposes construction from already verified metadata to avoid a second, unbounded remote JSON request. See its patch notes. Installation holds game/install/account permits until restart. The game permit lasts until the tracked Java child exits. These are process-local guards; another launcher process is not a cross-process lock. - The updater signing private key stays outside Git on the operator's local machine; CI receives no production key. Publish only verified packages, public signatures and signed feed. Updater signatures are separate from Windows Authenticode and macOS code signing/notarization.
Layout
src/main.tsx— React entrypoint;src/App.tsxcomposes the screen.src/components/— presentational UI;src/hooks/— lifecycle/settings/account.src/services/native.ts— typed IPC and event subscriptions; keep schemas aligned with Rust.src/services/async.ts— serialized writes, single-flight account restore and listener disposal.src/state/— tested reducers.- Native filesystem/network/process operations never belong in the web layer.
src-tauri/src/— native commands and security-sensitive logic.lib.rs— module/command registration only;commands/holds adapters for account/game/host/preferences/profiles. Unsigned sync/inspect IPC was removed; only verified remote manifests may drive profile mutations.operations.rs— process-local install/account permits owned by workers. The account permit covers ticket issuance through Java spawn, preventing local logout/account switching from racing that handoff.storage.rs— unique same-directory atomic writes, owner-only Unix files.trusted_http.rs— HTTPS and exact-host redirect policy per game provider.download.rs— shared verified-download helper (temp file, hash, atomic rename, progress callback);manifest.rs/profile.rs(ShaCraft mods) andmojang.rs/neoforge.rs/runtime.rs(the game itself) all build on this rather than each rolling their own.mojang.rs— vanilla Minecraft trust boundary + the genericinheritsFromversion-JSON merge (shared with NeoForge's profile).neoforge.rs— runs NeoForge's official installer headlessly.runtime.rs— Java 21 auto-provisioning via Eclipse Adoptium.msa.rs— Microsoft/Xbox/Minecraft Services login; seeMSA_CLIENT_ID's doc comment before touching login — it is currently a placeholder pending ShaCraft's own Azure AD app registration and Minecraft-API approval.shacraft_account.rs— local ShaCraft login/registration, session and nickname claim/admission API; legacy link commands remain for compatibility.admission.rs— ephemeral key generation, strict ticket response validation, canonical identity and child-only admission environment.launch.rs— builds and spawns the actualjavaprocess; admission secrets must remain outside its argument substitution and JVM argfile paths.updater.rs,commands/updater.rs— authenticated release metadata, bounded package download, platform installation and guarded restart.deb_updater.rs— installed-package checks, one system authentication prompt and the bounded, signature-verifying non-GUI root helper.
src-tauri/src/settings.rs— durable local preferences; maintain backward compatibility with already-written JSON.docs/manifest-v1.md— signed manifest envelope and payload contract (mods/config only).docs/game-trust-boundary.md— the Mojang/NeoForge/Microsoft/Adoptium trust domains used to install and run the game itself..github/workflows/check.yml— push/PR UI checks and Linux Rust tests..github/workflows/build.yml— main-push/manual cross-platform CI artifacts; updater signing is explicitly disabled there. Local release signing and atomic feed publication are documented indocs/launcher-updates.md.
Verification
Run from repository root:
npm ci
npm test
npm run build
(cd src-tauri && /home/emil/.cargo/bin/cargo test)
npm run tauri:dev
tauri:dev is for local desktop testing. A successful web build alone does
not prove Tauri commands work.
See PLAN.md for known gaps. Never label browser preview or unit tests as
a successful cold game install / Microsoft OAuth / Windows/macOS beta test.
The admission implementation has local unit/UI checks and unsigned Linux
0.1.2 AppImage/deb packages built on Ubuntu 26.04. Older Ubuntu compatibility
has not been tested. The backend/mod rollout is active on Aeronautics as of
2026-09-10. Real isolated NeoForge admission tests and a production rejection
without the mod passed; these do not certify a full production modpack join.
The server has a required early duplicate-login guard so unauthenticated
connections cannot evict an already-online UUID. The client mod pins the actual
socket to 135.106.154.86:25567. See architecture and server rollout records.
Working conventions
- Keep UI copy in Russian; code, identifiers and errors may remain English.
- Prefer a small vertical slice with tests over unused abstractions.
- Existing working-tree changes belong to the user unless this task created
them. Inspect
git statusbefore staging. - Update this file and
docs/launcher-architecture.mdwhenever the trust model, endpoint contract, storage layout, or release workflow changes.
Cross-platform release 0.1.5 (2026-09-10)
Published Windows x64 EXE/MSI, macOS aarch64 and x86_64 DMG/app.tar.gz,
and Linux x64 AppImage/DEB on https://shacraft.ru/help#launcher. The signed
stable feed includes all platforms plus the legacy/exact Linux aliases.
CI source b43fc610c4, successful Actions run
https://github.com/emil28092005/shacraft-launcher/actions/runs/34512683651.
An initial non-Linux borrow/move compilation error in updater target selection
was fixed before the final build. Native tests: Windows70, macOS74 per arch,
Linux84; UI tests pass on all four runners. Local checks verify macOS bundle
version/CPU type, Linux package identity and every artifact signature. Public
HTTPS downloads of all eight artifacts match local SHA-256. Website418 tests
plus48 subtests pass; only backend recreated, game containers unchanged.
Updater signatures use the existing operator-held key, never uploaded to CI or
server. Windows installers have no Authenticode signature; macOS is not Apple
notarized. Native CI tests and packaging do not certify full Minecraft installs
or desktop updater/restart behavior on Windows/macOS. Older unsupported clients
need a manual installation of the current release. Previous releases immutable.
Admission client menu 0.1.1 (2026-09-11)
The signed Aeronautics payload now contains admission mod 0.1.1 at the existing
managed path mods/shacraft-admission-0.1.0.jar to prevent duplicate mod IDs on
upgrade. SHA-256: faa9ae13cb0f2d93c03dae26ab36ae20d3fb6b66c89c09254b16808d6b183f89.
From the title screen (and vanilla safety acknowledgement), Multiplayer connects
to fixed 135.106.154.86:25567. Cancel/errors return to TitleScreen; transitions
from other screens do not auto-connect. Client-only registration, protocol 1 and
one-use admission remain unchanged. Running game server was not restarted.
Linux Java 21 build and 8 mod tests pass. An opt-in native live test verifies
signed-manifest retrieval and download/repair/restoration of the admission jar
only in a temporary directory. Mac 0.1.5 connection failure remains unclassified
pending exact error/log; this is not a verified macOS fix or desktop UI test.
Minigames integration (2026-09-13, published in 0.1.6)
- Native profile mapping is fixed: aeronautics → aoc; minigames → minigames. Both display/claim the canonical existing aoc nickname. The backend enforces the current shared aoc subscription and whitelist for Minigames as well. Ticket requests and responses remain bound to the selected server; never accept an aoc ticket as a Minigames ticket.
fabric.rsadds independent exact HTTPS domainsmeta.fabricmc.netandmaven.fabricmc.net. It verifies profile identity/parent/main class, bounded metadata, portable Maven coordinates, hashes and sizes before the existing atomic library installer. Unknown loaders now fail manifest validation.- Minigames launches with a native-owned Quick Play endpoint
135.106.154.86:25568. The manifest cannot choose a game destination. admission-client/owns the small client-only Fabric 26.2 companion. Its configuration-phase proof usesminigamesin the existing Ed25519 transcript, verifies the actual socket, canonical nickname and nonce, and signs once per process. Only a fresh launch can retry a consumed ticket. Java receives only the ephemeral ticket and private key in its child environment, never the website session/password. Keep server verification on Paper before world entry with an early duplicate UUID guard.- The standalone Paper admission adapter and backend remain server-project responsibilities. Do not put map/SMASH source into this launcher repository.
- Production updater publication requires a separately built, monotonically newer launcher release and existing operator signatures. Source tests or a client jar alone do not update installed 0.1.5 launchers.
Launcher 0.1.6 was built from 799fa692 on codex/launcher-updater; divergent
main remains unchanged. All four native CI builds, UI/native checks and 18
publisher signature tests pass. The unchanged Fabric companion completed a
real Minecraft 26.2 → Paper configuration handshake with a synthetic account;
its CI artifact is byte-identical. All eight public packages and the stable
feed were signed with the existing local updater key and verified through
public HTTPS downloads. See docs/release-0.1.6.md and its committed receipt.
This records successful release/admission verification, not a Windows/macOS
cold install or OS signing/notarization certification.
Server migration — launcher 0.1.7 (2026-09-17)
Minigames Quick Play now uses the fixed native endpoint shacraft.ru:25568.
It no longer pins the retired server IP in the application binary. The Fabric
admission client accepts the new actual socket IP 135.106.219.182 and retains
135.106.154.86 for the temporary forwarding path; unrelated hosts and ports
remain rejected. The server published updated signed companion manifests.
The migration's full-platform packages are published from
codex/server-migration-20260917. Existing 0.1.6 installers still connect to the
old IP and need that forwarding path until upgraded. Version 0.1.7 uses a newly generated operator-held updater key and the fixed
https://shacraft.ru/launcher/updates/stable-v2.json channel. It requires one
manual installation. Preserve stable.json at the last old-key release; never
replace it with new-key metadata. Subsequent v2-channel releases use the new
key, kept only at /home/emil/.local/share/shacraft-updater/production.key.
All eight public HTTPS downloads, their signatures and the signed v2 feed were
verified after publication. See docs/release-0.1.7.md and its publication
receipt for provenance, checks and the limits of platform verification.