Skip to content

๐Ÿ” Permissions & Caps

This page explains who can use Magikal bot commands, how access is checked, and where role permissions are configured.

The short version: Discord permissions control what Discord allows, while Magikal caps control what the bot allows.

Quick answer

Most staff-only bot access is controlled by capability roles.

Admins can map Discord roles to caps like admin, moderator, events, recruitment, and helper using /roles.


๐Ÿงญ Quick version

Magikal does not rely on one single permission system.

It uses a few layers together:

Layer Plain-English meaning
๐Ÿ‘‘ Discord permissions Native Discord powers like Administrator, Manage Guild, Manage Messages, Ban Members, and Manage Channels
๐Ÿท๏ธ Magikal caps Bot-level capability roles such as admin, moderator, events, recruitment, and helper
๐Ÿ”’ Owner-only tools Commands only the bot owner can run, such as command dumps and deep diagnostics
๐ŸŽฏ Feature allowlists Extra feature-specific access, such as /ship allowed roles
๐Ÿ“š Help visibility Controls what appears in public/staff/admin help panels

Important

Help panels and documentation only show what users should see.

Real permission checks must happen inside the bot command code.


๐Ÿงฑ Permission layers

Think of command access like a stack of gates.

Layer What it does Example
Discord permissions Checks native Discord power Administrator, Manage Messages, Ban Members
Magikal caps Checks mapped staff roles admin, moderator, events
Bot owner checks Locks commands to owner only !dump_commands
Feature allowlists Adds feature-specific access /ship allowed roles
Help visibility Controls what help panels display Public, Moderator, Admin tabs

Security rule

A command must never rely on help visibility alone.

If a user should not run a command, the command itself must deny them.


๐Ÿท๏ธ Capability roles

Magikal caps are friendly names for staff responsibilities.

The core permission helper lives in:

bot/utils/perms.py

Current core caps listed there:

Cap Plain-English meaning
admin Full bot/server configuration access
moderator Moderation and staff command access
events Event management access
recruitment Recruitment/application access
helper General helper/staff support access
member Member-level marker

The main helper functions are:

Helper What it is for
slash_require_caps(...) Adds a Magikal cap check to slash commands
prefix_require_caps(...) Adds a Magikal cap check to text/prefix commands
gate_check(...) Performs the actual access check
extract_caps_from_checks(...) Lets the help/audit tools detect command caps
send_deny(...) Sends a clean permission denied message

๐Ÿ‘‘ Admin bypass

A user passes most Magikal cap checks if they have either:

Discord Administrator
OR configured Magikal admin role
OR the specific required cap role

So if a command requires moderator, these users can run it:

User type Can run it?
Discord Administrator โœ…
Configured Magikal admin role โœ…
Configured Magikal moderator role โœ…
Normal member โŒ

Why admin bypass exists

Admin bypass prevents staff from locking themselves out of configuration commands.


๐Ÿ› ๏ธ Managing role mappings

Role/capability mapping is handled by:

bot/cogs/roles_config.py

Main slash command group:

/roles

Current role mapping commands:

Command What it does
/roles show Shows current cap โ†’ role mapping
/roles set Sets a Discord role for a cap
/roles clear Clears a cap role
/roles export Exports the mapping as JSON

These commands require both:

@app_commands.default_permissions(administrator=True)
@slash_require_caps("admin")

That means Discord should treat them as admin-level commands, and Magikal also checks the admin cap.


๐Ÿงฉ Current configurable caps

roles_config.py currently exposes these choices in /roles set:

Capability Visible in /roles set
admin โœ…
moderator โœ…
events โœ…
recruitment โœ…
finance โœ…
helper โœ…

Known issue: finance cap mismatch

roles_config.py exposes finance, and banking.py uses slash_require_caps("finance").

But the core CAPS set in bot/utils/perms.py does not currently include finance.

Until that is reviewed, a command requiring finance may fall back to the default moderator requirement.

Do not rely on finance-only access until this is fixed and tested.


โš ๏ธ Unknown cap fallback

The current gate filters out unknown cap names.

If no valid cap remains, it falls back to:

moderator

Example:

slash_require_caps("finance")

If finance is not recognised by the core CAPS set, the real requirement may become:

moderator

Adding new caps

When adding a new cap, add it everywhere it belongs.

Do not add a cap to one cog and forget the core permission helper.


๐Ÿค– Slash command permissions

Slash commands usually use Magikal caps like this:

@slash_require_caps("admin")
@app_commands.command(name="example", description="Example admin command")
async def example(self, interaction: discord.Interaction):
    ...

Many slash commands also use native Discord visibility permissions:

@app_commands.default_permissions(administrator=True)

or:

@app_commands.default_permissions(manage_guild=True)

Good slash command pattern

Use Discord permissions for native command visibility.

Use Magikal caps for the actual bot-level access rule.


๐Ÿ’ฌ Prefix/text command permissions

Prefix commands use:

@prefix_require_caps("admin")

or:

@prefix_require_caps("moderator")

Common live examples:

Cog Common cap
admin_config.py admin
moderation.py moderator and admin
tempvc_v2.py admin
basic.py admin

Some prefix commands also use native Discord checks:

@commands.has_permissions(...)
@commands.bot_has_permissions(...)

๐Ÿงฐ Native Discord permission checks

Native Discord permissions still matter.

Examples found in live cogs:

Check Typical use
commands.has_permissions(manage_messages=True) Purge/message tools
commands.has_permissions(manage_channels=True) Lock, unlock, slowmode
commands.has_permissions(ban_members=True) Ban and softban
commands.has_permissions(manage_roles=True) Role tools
commands.is_owner() Owner-only diagnostics/export
app_commands.default_permissions(...) Slash command visibility

Bot permissions matter too

A user having permission is not enough.

The bot also needs permission to perform the action.

Example:

@commands.bot_has_permissions(manage_messages=True)

๐Ÿ”’ Owner-only commands

Some commands are restricted to the bot owner.

Examples:

Command/source Purpose
!dump_commands Exports the live command tree to _exports/
diag_storage.py Owner-only storage/Redis diagnostics
command_dump.py Command inventory export

Owner-only rule

Owner-only tools should stay owner-only.

These commands can expose internal bot structure or operational details.


๐ŸŽฏ Feature-specific gates

Some features have extra access rules beyond the main cap system.

Example: Star Citizen ship tools.

Feature Storage/helper
/ship role allowlist get_ship_roles, add_ship_role, remove_ship_role
command role gates get_command_roles, add_command_role, remove_command_role

These are feature-specific and should also be explained on the relevant feature page.


๐Ÿ“š Help panel visibility

Help visibility is generated by:

bot/cogs/help_auditor.py
bot/cogs/help_panel.py

Main registry file:

data/help_registry.json

The help auditor checks:

  • slash commands
  • prefix commands
  • default Discord permissions
  • command checks
  • Helper 2.0 capability tags
  • explicit public allowlist

Help panels are not security

Help panels decide what users see.

Command checks decide what users can actually run.


๐ŸŒ Public command allowlist

Public help visibility is allowlist-driven.

Examples currently include:

Public command
!ping
!whoami_public
!help
!commands
/ping
/help
/info
/ship
/market
/item
/commodity
/refinery audits
/refinery capacities
/refinery methods
/refinery yields
/rsi profile

Public help rule

A command should not appear as public unless it is explicitly safe for normal members.

Unknown commands should default away from public visibility.


๐Ÿ‘ฅ Help audience buckets

The help system groups commands into broad audiences.

Audience Plain-English meaning
User Public/member-safe commands
Moderator Staff, helper, event, recruitment, finance-style commands
Admin Admin/config/owner-style commands

Capability tags influence the bucket.

Cap Help audience
admin Admin
moderator Moderator
events Moderator-style staff bucket
recruitment Moderator-style staff bucket
helper Moderator-style staff bucket
finance Moderator-style staff bucket in help auditor logic

๐Ÿงพ Help panel commands

Help panel commands live in:

bot/cogs/help_panel.py

Useful commands:

Command Purpose
/help_panel Posts the role-aware help panel
/help_role Shows help for a specific staff role/capability
/handbook Posts the staff handbook
/help_admin_panel Posts the admin help panel
/help_moderator_panel Posts the moderator help panel
/help_public_panel Posts the public help panel
/help_events_panel Posts the events help panel
/help_recruitment_panel Posts the recruitment help panel
/help_finance_panel Posts the finance help panel
/help_helper_panel Posts the helper help panel

๐Ÿงช Testing a permission change

When adding or changing command access, test the real behaviour.

Good permission test

  1. Test as an admin.
  2. Test as a user with the mapped cap role.
  3. Test as a normal member without the cap.
  4. Confirm the command denies correctly.
  5. Confirm the help panel matches the real access.
  6. Check logs for errors.

For slash command visibility, also check whether Discord shows/hides the command as expected.


โž• Adding a new capability

Before adding a new cap such as finance, support, or market:

  1. Add it to CAPS in bot/utils/perms.py.
  2. Add it to /roles set choices if it should be configurable.
  3. Add it to role mapping display/export.
  4. Update help_auditor.py audience mapping.
  5. Update help_panel.py filtering/panel support if needed.
  6. Update documentation.
  7. Test that users with only that role can use the intended commands.
  8. Test that users without that role are denied.

Do not add cap names in only one place

A cap name used in a command decorator must exist in the core cap system.

Otherwise the command may fall back to a different permission requirement.


๐Ÿšจ Red flags

Stop and review if:

  • a command uses slash_require_caps("something") but that cap is not in CAPS
  • a command modifies Discord state but has no Discord permission check
  • a command saves config but has no admin cap
  • a command appears in public help but should be staff-only
  • a command is hidden from help but still usable by normal users
  • a command uses only frontend/help visibility as a gate
  • a new feature creates its own permission system instead of using caps
  • role IDs are hardcoded
  • raw Discord IDs are logged

โœ… Final checklist

Before calling a permission change done:

  • command appears only for expected users where Discord supports visibility
  • command denies correctly when a user lacks the cap
  • command works for configured cap role
  • admin bypass works
  • non-admin/non-cap user cannot use it
  • help panel visibility matches real access
  • logs do not expose raw Discord IDs
  • docs are updated

๐Ÿง  Rule

Permissions should be enforced by the bot, mapped through clear capability roles, reflected in help panels, and documented from the current live files.