Skip to main content
This page documents operator-facing security behavior from PR #130 on the Doubt Discord Bot main branch. It covers permission gates, sandboxing, and authorization checks — not every change in that PR (for example health-server bind address or intent trimming).

Slash command Discord permissions

Several slash commands set Discord default_member_permissions when registered. Discord hides these commands from members who lack the permission in the command picker. The bot also enforces the same permissions at runtime via userPermissions in the command validator. Commands without default_member_permissions (economy, general, info, utility /ping, and so on) remain visible to members who can use slash commands in the guild.

Syncing permission changes after deploy

Command registration runs when the bot becomes ready and syncs default_member_permissions to Discord via registerCommands.js.
After deploying code that changes slash-command permission requirements, restart the bot. Without a restart, members may still see stale permission visibility until the next ready-time sync.

Developer eval sandbox

/eval and the prefix alias ?eval (?e) run code in an isolated VM sandbox (safeEval.js). Both paths are developer-only — the user’s Discord ID must appear in the bot’s developers allowlist (config.moderation.developers). If the allowlist is missing or empty, eval is denied. All commands under devOnly/ are developer-only (fail-closed in devCommandValidator.js). Other developer commands (for example /badge) are allowlist-gated but do not use the eval sandbox.

Sandbox rules

Blocked identifiers are matched as whole words before execution. A match fails closed.
Eval is a developer convenience, not a general-purpose scripting surface. Keep the developers allowlist limited to trusted operator accounts.

Ticket close authorization

A member may close a ticket only if any of the following is true:
  1. They have the Manage Channels guild permission.
  2. They have the guild’s configured ticket support role (ticketData.Role).
  3. They are the ticket opener (detected via their View Channel overwrite on the ticket channel).
Everyone else receives an ephemeral denial. Opening a ticket from the panel is separate — members who can see the panel can open a ticket, subject to the usual one-open-ticket-per-user rule.

Setup wizard authorization

/setup requires Manage Server at both the Discord API level (default_member_permissions) and at runtime (userPermissions). Follow-up setup components (welcome and ticket flows) also require Manage Server via setupGuard.js. Channel and role picker collectors bind to the member who triggered that step — another member cannot answer those collectors, even if they also have Manage Server.

Defense in depth