How FYY Premium protects license keys, users, and infrastructure.
Owner (OWNER_ID in .env)
|
+-- Full access to all commands
+-- Can add/remove admins
+-- Can set admin role
+-- Can send /panel
|
v
Admin (added via /addadmin or has admin role)
|
+-- Key management (add, delete, extend, blacklist)
+-- Username management (add, remove, reset)
+-- HWID management (blacklist, unblacklist)
+-- User management (whitelist, delete, info)
+-- Panel "Reset Users" button
|
v
Member
|
+-- Redeem Key (via panel button)
+-- Get Role (via panel button)
+-- Check Status (via panel button)
+-- Get Script (via panel button)
Every /check API request passes through 7 security gates:
| # | Gate | Check | On Fail |
|---|---|---|---|
| 1 | Parameter Validation | All required fields present | MISSING_PARAMS |
| 2 | Key Existence | Key exists in database | INVALID_KEY |
| 3 | Blacklist | Key not blacklisted | BLACKLISTED |
| 4 | Expiry | Key not expired | EXPIRED |
| 5 | HWID Blacklist | Device not globally banned | HWID_BLACKLISTED |
| 6 | HWID Binding | Device matches bound HWID (or first-time) | HWID_MISMATCH |
| 7 | Username Verify | Username registered or auto-bindable | USERNAME_NOT_FOUND |
A request only reaches business logic if all 7 gates pass.
- All bot replies are ephemeral — only the requesting user sees them
- Keys never appear in public channel messages
- Error messages never leak other users' data
- Keys stored uppercase — prevents case-sensitivity bypasses
- HWIDs stored uppercase — same rationale
- Usernames stored lowercase for comparison, original case preserved for display
- Environment variables validated once at boot
- Config object
Object.freeze()'d after validation — prevents runtime mutation - Missing required variables throw at startup rather than runtime
- MongoDB reconnects up to 5 times with exponential backoff
- Graceful shutdown (SIGINT/SIGTERM) ensures clean DB disconnect
- Unhandled rejections logged via Winston, process exits cleanly on fatal
- Key sharing — HWID lock prevents a key working on multiple devices
- Credential scraping — Ephemeral messages prevent key leaks via screenshot/log
- Brute-force redemption — Key format
FYY-XXXXX-XXXXX-XXXXXuses 17 random alphanumeric chars (entropy > 2^88) - Stolen keys — HWID binding means a stolen key won't work until admin resets
- Banned reverse engineers — HWID blacklist globally bans a device regardless of which key they use
- Source code leak — if the server source is leaked, attackers can bypass validation entirely
- MongoDB credential leak — direct DB access bypasses all application-layer security
- Physical device cloning — if an attacker clones a legitimate user's HWID exactly, they bypass HWID lock
- Discord account takeover — compromised admin Discord account = compromised system
- Man-in-the-middle — HTTPS is required in production; HTTP alone allows response tampering
The .env file is the single source of truth for secrets:
| Variable | Sensitivity | Storage |
|---|---|---|
DISCORD_TOKEN |
Critical | .env only |
MONGODB_URI |
Critical | .env only |
API_KEY (admin endpoints) |
High | .env only |
CLIENT_ID |
Low | .env or hardcoded |
GUILD_ID |
Low | .env or hardcoded |
OWNER_ID |
Low | .env |
.env is excluded via .gitignore. CI/CD platforms inject secrets as environment variables, never as committed files.
All security-relevant events are logged to:
- Winston file —
logs/app.logwith structured JSON - Discord webhook (optional) — admin-configured channel receives embeds for:
- Key redemption
- HWID mismatch attempts
- Blacklist hits
- Admin actions (add/remove admin, blacklist)
See also: API.md for endpoint auth, COMMANDS.md for admin commands.