Security & Transparency
Server admins trust a bot with their roles and their members. Here's exactly how we protect both.
🔐 Zero-Trace verification
- Passwords are entered only in private Discord pop-ups (modals) or a private verification thread, never typed into a chat channel or a normal DM, so there's nothing in message history to leak.
- Stored only as scrypt hashes with a unique random salt and a deliberately memory-hard setting (about 64 MiB per check), compared in constant time.
- Wrong guesses are limited and locked out per member for 15 minutes, even across restarts.
- If a member doesn't verify in time, their roles are saved and replaced with a quarantine role, and given back exactly on a correct password. Quarantined members disappear from public leaderboards until they verify.
🛡️ Gatekeeper role protection
- Admins mark roles that only verified members may hold. If anyone (a moderator, another bot, an integration) adds one to an unverified or quarantined member, the bot removes it immediately and logs who did it.
- Store roles can be locked to buyers only in the same way.
- The bot never hands out a role with administrator or moderation powers, or one above its own. This is checked when it's configured and again every time.
- It never pings @everyone, @here or roles.
💰 Escrow-backed economy
- Every coin movement is written in the same database transaction as its ledger entry, so balances can't drift from their history.
- Bets and buy-ins are held in escrow. If the bot restarts mid-game, every player gets back exactly what they had at the last safe point, so coins are never lost or created.
- One write lock serialises balance changes: double-clicks can't double-spend.
- There's no button, for server admins or for us, to set or edit a member's balance. Coins only move through games, rewards, transfers and store purchases or refunds, each recorded in the ledger.
The dashboard
- Login only through Discord OAuth2, so we never handle your Discord password. Access is re-checked live with Discord about every minute, so losing a role locks you out quickly.
- Granular moderator permissions: each moderator role gets only the tools you tick; destructive ones (like nuking a channel) are off by default, and every change is in the audit log.
- Every form is protected by a CSRF token and same-origin checks; cookies are signed, HttpOnly, Secure and SameSite.
- A strict Content-Security-Policy: the site runs no JavaScript at all, and everything shown is HTML-escaped.
- Login, password and change requests are rate-limited.
Payments
- Checkout and card management happen on Stripe's own pages. Card numbers never reach our servers.
- Plan changes come only from Stripe webhooks whose signatures we verify, each processed once, with the plan decided by the price paid, never by anything a browser sends.
Data minimisation
- The bot doesn't request access to message content.
- Member lists live in memory only, and are dropped for servers inactive for 60 days.
- Proof images for leaderboard submissions go to your server's own review channel, not our database.
- Custom bot tokens are encrypted with AES-256-GCM and never shown again.
Honest limits
No system is perfectly secure. Our code is tested extensively, including targeted attack scenarios, but has not yet had an independent third-party audit. Discord itself isn't end-to-end encrypted: Discord can read messages on its platform, whatever any bot does.
Report a vulnerability
Found a security issue? Email support@castrosbot.theinkwell.dev with the details. Please give us a reasonable time to fix it before sharing it publicly, and don't access other people's data or disrupt the service while testing. We appreciate responsible reports.