Skip to content

Releases: PotenFYR-Studios/AuthCore

AuthCore - Latest Development Build

Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Sep 05:14

Development build of AuthCore 1.0.0
Commit: a13c848 - built 2026-09-12 17:22 UTC

One merged changelog for the whole 1.0.0 line - every feature, fix and hardening
pass that ever shipped under a 1.0.0* label lives in this single section
(the separate alpha.1-alpha.5 entries were folded in; nothing was lost).

Build, mixin & proxy-gate hardening (2026-09-06)

Build-time remap errors fixed (all 4 Cannot remap warnings gone)

  • startSleeping lobby restriction: the Either-returning overload never existed on any
    supported version; unified to the void overload that exists on every version.
  • Elytra block: startFallFlying was removed from the mappings long ago (the injection
    silently never ran); it now injects updateFallFlying, the per-tick glide driver, which
    also extends the elytra + jump lobby restrictions to the 1.16-1.18 range.
  • Mount block: startRiding(Entity,Z) was replaced by a 3-arg overload in 1.21.9; the mixin
    now injects the 1-arg final entrypoint (present on every version) plus the era-specific
    force overload, so mount blocking actually runs on 1.19-1.21 instead of silently no-oping.
  • Deop tracking: the GameProfile -> NameAndId API swap happened in 1.21.9, not 26.x;
    the stonecutter cut point was corrected and the handler now uses @Coerce so the same
    jar's bytecode never references the 1.21.9-only NameAndId type.

Runtime mixin crashes fixed (host matrix back to green)

  • ServerPlayNetworkHandlerMixin legacy handlers and PlayerListOpMixin used Object
    handler parameters, which Mixin rejects at runtime (InvalidInjectionException) - the
    1.16-1.18 fabric legs and all 26.x legs failed as a result. Handlers now declare the
    exact packet types.

Startup banner fixed on log4j-era loaders

  • On runtimes without slf4j (1.16-1.18 Fabric/Forge) the entire banner printed literal
    {} placeholders instead of values. The fallback console logger now substitutes
    slf4j-style placeholders, so version, Minecraft version, database type and every
    security flag display correctly.

Proxy-gate bypass & spoofing hardening

  • Velocity/BungeeCord proxy gate: a gate error previously failed OPEN (unauthenticated
    players allowed through even with block-unauthenticated=true); it now fails CLOSED
    by default - deny unless the operator explicitly sets fail-closed=false.
  • Interop messages (AUTH_CHANGED) are no longer accepted from player connections -
    only backend-server senders are trusted, and messages are consumed so they can never
    be forwarded to clients.

CI: rolling latest-build release

  • Every main push that passes build + host tests now republishes the latest
    GitHub release: same-version uploads REPLACE the jars and regenerate the changelog
    notes; the stable v* tag release remains the "Latest" release.

Test suite grown to 180+ checks

  • New suites: proxy spoof-guard hardening, trusted-proxy source + CIDR validation,
    proxy-config parsing strictness, interop message parsing, proxy-side session cache.
  • Docker harness now verifies server-mode auto-detection and banner data correctness
    on every leg.

Detection hardening & bypass resistance (2026-09-05)

7-layer defense-in-depth stack

  • Layer 1 - Session Binding: per-server random 32-byte companion attestation key,
    generated on first boot, persisted to config/authcore/attestation.key, rotated on
    /authcore reload (invalidates all pending challenges). No hardcoded keys anywhere.
  • Layer 2 - Packet Sequence Validation: login packet state machine (HELLO → SETTINGS →
    READY) tracks every connection; anomalous sequences are logged as PACKET_SEQUENCE_ANOMALY.
    Stale entries are pruned on tick and on player leave.
  • Layer 3 - Behavioral Profiling: ClientGuard risk scoring now includes confusable-name
    detection (O(1) normalized-name index), concurrent-connection fingerprinting
    (CONCURRENT_FARM: ≥3 distinct usernames from same IP within 5s = +25 risk),
    look-pattern bot detection (camera rotation delta variance = +20), and observation-window
    entropy analysis (low timing variance = +15).
  • Layer 4 - Look-Pattern Analysis: tracks per-player look deltas (pitch/yaw changes
    between packets); computes coefficient of variation - bots have zero or perfectly regular
    patterns, humans have natural variation.
  • Layer 5 - Login Timing Distribution: IP-level login timestamp analysis (60s window,
    ≥3 samples); low coefficient of variation (< 0.15) flags bot-farm synchronized timers.
  • Layer 6 - Concurrent Connection Fingerprinting: ClientGuard.checkConcurrentFarm
    tracks distinct usernames per IP within a 5-second window and attaches CONCURRENT_FARM
    (+25) to the joining player's profile.
  • Layer 7 - Login Intelligence: device fingerprint (SHA-256 of IP + country), new-IP /
    new-country alerts (+15 risk), 2FA code rate limiting via RateLimiter.tryMfa (5
    attempts/minute per IP + account).

Fail-closed security defaults

  • Proxy support is hard-disabled when trusted-proxies is empty (was a warning, now a
    startup block via SecurityConfiguration.enforce).
  • Redis-backed proxy auth gate defaults to fail-closed (fail-closed = true in
    ProxyConfig) - Redis unreachable blocks proxy-authenticated connections instead of
    allowing them.
  • Session token TTL enforcement: tokens expire after 24 hours regardless of session timeout,
    preventing indefinite session fixation.

Performance & robustness

  • Batch GeoIP lookups: IPs are collected over a 500ms window and resolved in parallel,
    bounded by a 4-permit semaphore - eliminates thundering herd under join floods.
  • Detection state integrity: PACKET_SEQUENCES map is pruned on tick (expired + disconnected
    connections); all detection maps have cardinality bounds and self-pruning.
  • Web panel CORS support: OPTIONS preflight handler + Access-Control-Allow-Origin headers
    on every response; CORS headers also set on error paths.

Test coverage

  • Security test suite expanded with 12 new test cases: attestation key generation/rotation,
    concurrent-farm detection, look-pattern inner classes, login timing null-safety, packet
    sequence tracking null-safety, and 2FA rate limiter integration.

Test-infra overhaul & harness fixes (2026-08-28)

  • Temurin-based Docker verification: the host-test harness runs on the official
    eclipse-temurin JRE images (17/21/25,
    one per Minecraft version group) and boots the whole matrix IN PARALLEL - one
    container per MC/loader combination. New test/docker/ (Dockerfile + self-
    provisioning entrypoint + parallel runner), test/build.sh (builds all 7 variants
    with no local JDK needed) and test/run-security-tests.sh (bash port of the
    standalone security suite). Old tools/host-tests, tools/security-tests,
    scripts/ and their workflows removed.
    test/build.sh (builds all 7 variants inside the official eclipse-temurin JDK image with
    no local JDK needed) and test/run-security-tests.sh (bash port of the
    standalone security suite). Old tools/host-tests, tools/security-tests,
    scripts/ and their workflows removed.
  • Minecraft version detection fixed on Forge/NeoForge: Compat.getGameVersion()
    relied on SharedConstants.getCurrentVersion().getName() via reflection - method
    names are SRG-renamed on Forge runtimes, so the startup banner printed
    Minecraft : unknown (and falsely warned "not in the officially tested set").
    Now resolves through FML's non-obfuscated VersionInfo (Forge static accessor;
    NeoForge's FMLLoader.getCurrentOrNull().getVersionInfo()), with the Mojang
    reflection kept as last resort.
  • Versioned documentation site: a common main page (index.html: downloads,
    quick start, FAQ) plus per-release doc sets under docs/<version>/, cross-linked
    through a shared version bar (docs/assets/nav.js + docs/versions.json) and
    deployed by the recreated .github/workflows/pages.yml - the existing
    authcore.potenfyr.in/docs/<version>/... URLs are preserved.
  • Parallel Docker host tests, never stuck: the whole (version × loader) smoke/
    verify matrix boots in parallel containers; server state lives in named Docker
    volumes (Windows 9p bind mounts stalled the Forge/NeoForge installers), the
    installer runs under a hard timeout and every test has an outer kill deadline.
  • Premium-detection hardening on 1.18.2: Compat.serverUsesAuthentication could
    miss the mojmap method name and default to "online", routing cracked players through
    the wrong auth flow. Now tries isOnlineMode/getOnlineMode/usesAuthentication
    plus an onlineMode field fallback before defaulting.
  • IDEA: broken fabric-only run configurations replaced with Gradle-based
    Build all variants configs driving the new buildAll/testAll/dockerTest
    aggregate tasks (all loaders × all ranges in one pass).

Security-audit & CI pass (2026-08-26)

Critical fixes

  • MySQL / PostgreSQL servers no longer brick at boot: the hard-coded SQLite DDL
    (AUTOINCREMENT, TEXT primary key) threw on both dialects, which set
    migrationBlocked = true and suspended login/register for the whole server. Table
    creation is now dialect-aware (AUTO_INCREMENT / BIGSERIAL / VARCHAR(36) keys).
  • Session-resume premature kick fixed: resuming a session re-ran login() without
    stopping the previous session's timeout task - the stale timer fired at the ORIGINAL
    deadline and kicked freshly-authenticated players. The old timer is now cancelled on
    every (re)login.
  • Direct-client IP spoofing closed: proxy IP forwarding accepted a BARE handshake
    address as a forwarded IP - but that field is client-controlled, so any modified client
    could claim an arbitrary IP (defeating rate limits, GeoIP, login intelligence and IP
    rules). Only the real NUL-separated proxy forwarding payload is trusted now.
  • ...
Read more

AuthCore v1.0.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 23:06

Hybrid mode, per-account login style & release hardening (latest)

Anti-float platform - mid-air logouts can never kick players in the limbo

  • A player who logs out mid-air (or underwater) used to be kicked by vanilla's
    "Flying is not enabled" floating check while standing in the limbo. AuthCore now
    places an invisible BARRIER platform under the limbo player (lobby.anti-float-platform,
    on by default); diving players are stood on a platform at the water/lava surface instead
    of being left submerged. The original block is restored shortly after the authentication
    flow completes (lobby.anti-float-platform-delay-ms, default 10 seconds) - never
    overwriting a block another player placed in the meantime.
  • Crash recovery for the limbo (already present, verified): the pre-limbo snapshot
    (exact position + dimension, inventory, effects, game mode, health/food/xp) is persisted
    at lock time; if the server (or the player's session) crashes mid-limbo, the snapshot is
    restored on the next join BEFORE the fresh lock, so after login the player always returns
    to the exact spot they were at their last disconnect - regardless of the admin-configured
    limbo location.
  • Movement lock hardened: with movement disabled, the per-tick limbo re-assert now
    snaps the player back at a 0.25-block drift (was 1.0) - on runtimes without the
    movement-cancel mixin (Fabric/Forge 1.16-1.21 without a mixin refmap) this is the only
    server-side lock, and it now holds the player essentially in place. Known limitation:
    on those runtimes the client can briefly ghost-walk up to the snap interval; the
    restriction is fully packet-level on NeoForge and every 26.x jar.

Server mode is always taken from server.properties - the config override is gone

  • The session.server-mode setting is removed entirely: the mod always reads the real
    online-mode from the running Minecraft server (MinecraftServer#usesAuthentication).
    Premium auto-login works the same on online AND offline-mode servers (on offline servers
    AuthCore re-runs the vanilla encryption handshake and verifies with the server's own
    Mojang session service - no external API calls; failures fall back to offline
    register/login, players are never blocked or kicked).
  • Online-mode servers get a startup warning to keep enable-secure-profile=false in
    server.properties, so clients without a secure chat profile (cracked/modded players)
    can still join and chat.

Hybrid servers: offline-mode players can join BOTH server modes

  • New allow-offline-players config (session.authentication, default true): with it on,
    offline (cracked) players can join and register/login on online-mode servers too -
    the login mixin intercepts offline-UUID clients on online-mode servers and runs them
    through vanilla's own offline accept flow (no Mojang session check, offline UUID kept;
    online-mode players still use their real UUID and the normal session verification).
    Fail-safe: on versions where the offline accept flow cannot be driven, vanilla's normal
    rejection takes over - nobody is stranded.
  • With allow-offline-players = false the server is online-mode-only everywhere: offline
    players are kicked with a clear message on arrival (join gate, before session resume /
    register / login), and on online-mode servers they are disconnected at login.

Premium auto-login respects its config on BOTH modes; auto-login players keep a null password

  • The premium-auto-login config (on by default) is now honored regardless of the server's
    mode. Auto-login players are NEVER given an auto-generated password - their stored
    password stays null (the old premium-auto-register random-password path is removed).
  • If auto-login is turned off (or a player switches to password login), verified online-mode
    players are treated like any standard account: because their password is null they are
    asked to /register on their next re-auth. Their online-mode status is preserved, so
    auto-login simply resumes when the config (or their mode choice) is switched back.

Per-account login style: players and admins can switch online/offline mode

  • New player command /account set-mode online|offline (permission authcore.user.setmode,
    level 0): switches the player's own account between automatic login and password login.
  • Switching to password login is smart about passwords: a player who ALREADY has a stored
    password keeps it and simply logs in with it (/login); only auto-login accounts with a
    null password are asked to /register a new one. The active session is destroyed either
    way so the change takes effect on the next join.
  • /authcore set-mode offline <player> no longer takes a password argument and follows the
    same rule (existing password kept / register when null). Both admin mode commands destroy
    the session too.
  • A player's own mode choice is honored on join: accounts explicitly set to password login
    are never auto-logged-in, even on an online-mode server where the session was verified.

Terminology: "premium"/"cracked" replaced project-wide

  • Non-user-facing text (console logs, debug output, admin commands, web panel labels, code
    comments, docs) now uses online-mode players and offline-mode players instead of
    "premium players" and "cracked players". Internal identifiers and the premium-auto-login
    config key stay unchanged for API/config compatibility.
  • Player-facing messages stay human: auto-login greets with "Welcome to the Server!", mode
    switches talk about "automatic login" / "password login" - no technical jargon anywhere
    in chat, titles or kick screens.

Limbo guard debug output

  • The per-join limbo guard report is now debug-level and formatted like the startup banner:
    one aligned row per guard (movement / chat / commands / block-break / block-use / item-use
    / item-drop / attacks, each allowed or LOCKED) plus a live lobby-usage line
    ("35% used (7/20)", "unlimited" when no cap).

Scale, race-condition safety & docs

  • Performance/scalability pass documented for 500k+ registered accounts and thousands of
    concurrent players: O(1) user lookups on every hot path, lazy DB loading, bounded
    self-cleaning caches, no resource spikes under join/login bursts (per-user throttles,
    rate limits, fixed-size daemon IO pool), race-condition-free concurrency (canonical
    single-User-per-account cache, synchronized DB access, volatile shared state,
    deduped join/leave hooks, atomic counters).
  • Docs re-skin: the hosted docs now use a black + red fortress-cyber theme with an enhanced
    sidebar table of contents (topic count, in-TOC scroll progress, back-to-top, glowing
    active states) and a wider, spread-out content layout; README and every docs page updated
    for the current behavior.

Limbo, performance & configuration overhaul

Limbo quality pass (no more screen vibration, no bypasses)

  • Anti-vibration movement correction: the client was snapped back on EVERY violating
    movement packet (up to 40 position packets/s → rubber-banding). Corrections are now
    distance- and throttle-based: lobby.movement-correction-radius (default 1.5 blocks) and
    lobby.movement-correction-interval-ms (default 600ms), the classic AuthMe feel
    (ghost-walk a little, one clean snap). Movement packets are still cancelled on every
    packet, so the server entity never leaves the anchor (no bypass).
  • Vehicle-movement bypass closed: handleMoveVehicle was uncovered: lobby players on
    boats/minecarts (or spoofing the packet) could move freely. Now cancelled + anchored like
    player movement.
  • Inventory lock without touching chat: the inventory is fully inert in the limbo
    (every slot click blocked and force-closed on interaction, including shift-clicks and
    armor equipping), while the chat input is NEVER interrupted, so /register and /login
    always work. A periodic force-close packet was tried and removed again: the client closes
    ANY screen (including chat) on a container-close packet, and there is no server-side
    signal for "inventory open"; click-based blocking is the only safe approach.
  • Attack-callback fix (the "can't hit mobs" bug): the fabric AttackEntityCallback
    listener was registered under the wrong method name (attack instead of interact),
    so the reflective proxy returned null for every attack and the fabric event cancelled
    ALL attacks for everyone, in and out of the lobby. One-line fix.
  • Server-side auth menu removed (chest menu + book input + /menu command): auth is
    purely chat-driven with clickable buttons; the menu system, its mixins and its command
    are deleted entirely.
  • Context-aware chat buttons: the login/register buttons build the EXACT command shape
    the player needs (password confirmation, 2FA code, captcha code) and show it in the
    action bar; no confusion about which auth factors apply.
  • Styling: clickable chat buttons are now underlined; the action bar gets the same
    drop-shadow as titles/subtitles.
  • Crash-safe limbo verified: the pre-limbo snapshot is saved at lock, restored before
    the fresh lock on rejoin after a crash, and deleted on clean unlock; the unlock lifts
    restrictions before any restore step so a failed restore can never keep a player stuck.

Performance pass (constant per-packet cost, bounded memory)

  • O(1) user lookups on every hot path: new User.getUser(UUID) / User.getUser(player)
    . a single map get, no string allocations, no scans, no DB, and all per-packet mixin guards
    (movement, clicks, chat, ticks, entity events, commands) now use it.
  • Indexed username lookups: precomputed lowercase names + a byLowerName index make
    lookUpByUsername mode O(1) too (previously a full-map scan with per-entry
    toLowerCase allocations).
  • Throttled cache touches: the last-access map put now happens at most once per minute
    per user instead of on every pac...
Read more