Files
minecraft-account-manager/docs/architecture.md
T

3.1 KiB

Architecture

Services

Web application

The Next.js application owns user onboarding, account management, admin configuration, server-side Minecraft profile validation, sessions, and the HTTP API used by Discord and Velocity integrations.

User authentication begins with an opaque, short-lived, single-use token created for a Discord user. Only a cryptographic hash of the token is persisted. Admin authentication is a separate Keycloak OIDC flow and requires the minecraft-account-manager-admin role.

Discord bot

The bot creates private login links in response to /register and /account. Discord user IDs are the canonical Discord identity; mutable usernames are snapshots only. Nickname updates target the guild selected in admin settings.

Velocity plugin

Velocity sends the authenticated Java UUID, current username, source IP, server ID, request ID, and occurrence time. The API matches UUID first. Username fallback is allowed only when the stored account has no UUID, after which UUID and canonical username are updated.

The decision is fail closed. Unknown players, invalid responses, expired requests, authentication failures, and unavailable API responses are denied with the configured registration message.

Trust boundaries

  • Browser input is untrusted. Minecraft profile resolution occurs on the server.
  • Forwarded IP headers are accepted only from configured reverse proxies.
  • Discord IDs come from bot-authenticated requests or one-time-code records, not browser fields.
  • Velocity requests will use per-server credentials, timestamps, and request IDs to support authentication and replay prevention.
  • Session and one-time-code values are random and stored only as hashes.
  • Exact IP addresses are sensitive data and require an explicit retention policy before production deployment.

Database invariants

  • A Discord user ID maps to one user.
  • An active Minecraft UUID or case-insensitive username maps to one account.
  • A user has at most one active primary Minecraft account.
  • Removed accounts are soft deleted to retain audit history.
  • Audit events are CloudEvents-shaped, append-only application records.
  • published_at reserves an outbox-style path for later Kafka publishing.

IP intelligence

IP observations and cached classifications are modeled independently from any provider. Until a provider is configured, addresses remain unknown; the application must not claim that VPN checks occurred. When enabled, account creation can require a clear classification and record denied attempts as events.

Event naming

Events use reverse-DNS names beneath games.minecraft.account-manager, including:

  • games.minecraft.account-manager.ui.accessed
  • games.minecraft.account-manager.auth.magic-link.consumed
  • games.minecraft.account-manager.minecraft-account.added
  • games.minecraft.account-manager.minecraft-account.removed
  • games.minecraft.account-manager.discord.nickname.updated
  • games.minecraft.account-manager.network.vpn-blocked
  • games.minecraft.account-manager.game.login.allowed
  • games.minecraft.account-manager.game.login.denied