Skip to content

Audit command visibility: add default_permissions to hide commands from unauthorized users #201

@karaktaka

Description

@karaktaka

Problem

Commands that require specific Discord permissions are visible to all users in the slash command picker, even when they lack the permissions to use them. Invoking such a command results in a runtime error instead of the command being hidden entirely.

Expected Behavior

  • Admin-only commands should be hidden from users who don't have the required permissions
  • /ping should remain universally visible and be accessible in guilds (confirm DM availability is intentional)
  • /rolemanage assign and /rolemanage remove should stay visible to everyone (their permission model is custom, not based on Discord permissions)

Current Behavior

Several modules rely solely on @app_commands.checks.has_permissions(...) (runtime check) without @app_commands.default_permissions(...) (visibility control). This means commands appear for everyone but fail at invocation.

Audit

Modules WITH default_permissions

Module Decorator Effect
Admin (class) default_permissions(administrator=True) Hidden from non-admins
Admin /ping default_permissions() Visible to everyone (override)
ReactionRole default_permissions(manage_roles=True) Hidden without manage_roles
LeaveMsg default_permissions(administrator=True) Hidden from non-admins

Modules MISSING default_permissions

Module Runtime Check Notes
Moderation kick_members, manage_messages, moderate_members Needs default_permissions — e.g. moderate_members=True or similar
RoleManage manage_roles on allow/deny/list only ⚠️ Tricky — see below

RoleManage: split permission model

/rolemanage is a GroupCog where commands have two different audiences:

  • Admin commands (allow, deny, list): require manage_roles — for setting up role mappings
  • User commands (assign, remove): NO Discord permission required — checks at runtime whether the invoking user holds a configured "source role"

Problem: Discord's default_permissions applies at the group level, not per-subcommand. Setting default_permissions(manage_roles=True) on the class would hide assign/remove from the very users who need them.

Possible approaches:

  1. Leave the group visible to everyone and accept that allow/deny/list are visible-but-unusable for non-admins (current behavior)
  2. Split into two groups: /rolemanage-config (admin) and /rolemanage (user)
  3. Rely on server admins to configure per-command visibility via Discord's Server Settings → Integrations panel
  4. Accept option 1 but improve the error message when a non-admin tries allow/deny/list

Additional Questions

  • /ping in DMs: Currently /ping is NOT guild_only — it works in DMs. Is this intentional?
  • Decorator propagation: default_permissions on a regular Cog may not propagate to individual commands (same issue as guild_only — see refactor: replace regular Cog with GroupCog where possible #196). Verify propagation for each module type after changes.

Related

Acceptance Criteria

  • All modules with runtime has_permissions checks also have matching default_permissions for visibility (where applicable)
  • Decide on approach for rolemanage split permission model
  • Decide whether /ping should remain available in DMs
  • Verify default_permissions propagation for both Cog and GroupCog subclasses
  • Test that unauthorized users no longer see restricted commands in the slash command picker

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions