Skip to content

Latest commit

 

History

History
106 lines (68 loc) · 5.26 KB

File metadata and controls

106 lines (68 loc) · 5.26 KB
title Security
description Permission gates, BotStaff ACL, setup authorization, and ticket close rules for doubt-bot
This page reflects security behavior on **[doubt-bot](https://github.com/Doubt-Productions/doubt-bot)** `main` (TypeScript / PostgreSQL). Legacy [Doubt-Discord-Bot](https://github.com/Doubt-Productions/Doubt-Discord-Bot) may differ until cutover.

Slash command permissions

Guild slash commands use discordx guards and Discord permission checks where implemented:

Surface Gate
/setup @Guard(ManageGuildOnly) — Manage Server
/rank reset, /rank set Runtime check for Manage Server
Setup components (welcome, tickets, JTC) denyUnlessManageGuild() in src/utils/setupGuard.ts

Other commands (economy, /ping, /help, /afk, …) do not set Discord default_member_permissions unless added in future ports.

After permission changes

Restart the bot after deploying code that changes slash metadata so bot.initApplicationCommands() on ready re-syncs guild commands.

Developer eval sandbox

/eval and other legacy devOnly utilities from Doubt-Discord-Bot are not shipped in doubt-bot yet. When ported, they should remain developer-only (DEVELOPER_DISCORD_IDS) and run inside a restricted VM sandbox (timeout, blocked identifiers such as process, require, fs, child_process, …) — matching the legacy safeEval.js behavior.

Until eval is ported, do not expose arbitrary code execution on production bots.

Keep `DEVELOPER_DISCORD_IDS` limited to trusted operator accounts.

Ticket close authorization

Ticket close is enforced in src/utils/ticketAuth.ts and the ticket-close button handler.

A member may close a ticket only if any of the following is true:

  1. They have Manage Channels on the guild.
  2. They have the configured ticket staff role (Setup.ticketStaffRoleId).
  3. They are the ticket opener (their user ID has an allow View Channel overwrite on the ticket channel).

Everyone else receives an ephemeral denial. Opening a ticket uses the panel select menu and modal (ticket-modal); members who can see the panel can open a ticket subject to the one-open-ticket check.

Setup wizard authorization

/setup requires Manage Server via ManageGuildOnly.

Follow-up setup interactions call denyUnlessManageGuild() on welcome, ticket, and JTC components. The helper setupComponentFilter() exists to bind collectors to the initiating user where message collectors are used; welcome message text is collected through a modal, not a MessageCollector.

Global bot staff ACL

Staff-only commands use @Guard(StaffOnly) in src/guards/accessGuards.ts. Privilege is checked with canUseStaffCommands() in src/services/botStaffService.ts against PostgreSQL — not guild roles.

Privilege source of truth

Layer Role
BotStaff Postgres table (discordId) ACL — who may pass StaffOnly
DEVELOPER_DISCORD_IDS Developers always pass staff gates
bot-staff badge (UserBadge → reserved Badge) Display-only; never grants command access

The reserved badge key is bot-staff. /badge rejects reserved keys and lookalikes (bot_staff, botstaff, …). Management is via /botstaff (developers only).

Fail-closed behavior

StaffOnly denies users who are neither developers nor in BotStaff. There is no fallback to legacy moderation.staffRoles.

If BotStaff is empty, staff-only commands fail until operators run /botstaff add or import rows via yarn migrate:mongo.

Who can manage staff

Only developers (DeveloperOnly guard) may run /botstaff add, remove, list, or migrate. Each add records addedBy and addedAt; removals write BotStaffRemoval audit rows.

Cutover order (operators)

Apply Postgres **migrations before** writing BotStaff data or running `/botstaff`. `/botstaff migrate` only re-syncs badges for existing rows — it does not create staff from legacy config.
  1. yarn prisma:migrate:deploy on the target database.
  2. Import staff (Mongo migrator and/or /botstaff add).
  3. Run /botstaff migrate if badge display is out of sync.
  4. Verify with /botstaff list.

Badge administration

/badge subcommands are @Guard(StaffOnly) — bot staff or developers. Reserved badges cannot be created, updated, or deleted through /badge. Granting the 🛡️ mark for staff is always through /botstaff, not manual badge grants.

Defense in depth

Surface Primary gate
/setup and setup components Manage Server (ManageGuildOnly / denyUnlessManageGuild)
Ticket close button Opener, ticket staff role, or Manage Channels
/botstaff Developer allowlist
StaffOnly commands (e.g. /badge) Developer allowlist or BotStaff Postgres ACL
Reserved bot-staff badge Locked in /badge; synced via /botstaff
/eval (legacy) Not available on doubt-bot until ported

Message Content Intent

Regression tests in doubt-bot assert the client intent list excludes Message Content. AFK uses mention metadata only (src/events/afkCheck.ts). Do not enable Message Content Intent for standard deployments.