Skip to content

Security & safe defaults

Status Stable · Last verified 2026-07-12 · API v10 · Source Interactions security

Security here is not a chapter at the end — it’s the default. The repository-level policy (secret handling, disclosure) lives in SECURITY.md; this page is the developer-facing guidance.

Credential Blast radius if leaked Rotate via
Bot token Full control of the bot user Portal → Bot → Reset Token
Client secret Impersonate your app in OAuth2 Portal → OAuth2 → Reset Secret
Webhook URL Post to that channel as the webhook Delete/recreate the webhook
Public Key Not secret — it verifies inbound requests n/a

Never commit them, never put secrets in client-side code, never log them. Store in environment variables or a secrets manager. If one leaks, rotate first — that’s what actually stops the bleeding — then clean up.

If you receive interactions over an HTTP endpoint, you must verify each request’s signature or Discord will disable your endpoint:

  1. Read X-Signature-Ed25519 and X-Signature-Timestamp from the headers.
  2. Verify the Ed25519 signature over timestamp + rawBody using your app’s Public Key.
  3. Reject with 401 if verification fails (including bad hex, missing headers, or a stale timestamp outside a short replay window).
  4. Cap body size before buffering (the example uses 256 KiB413).
  5. Respond to the initial PING (type 1) with a PONG (type 1).

[!CAUTION] Verify the raw body You must verify against the exact bytes Discord sent, before any JSON parsing or body transformation re-serializes them. A framework that parses the body first (changing whitespace/key order) will make valid requests fail and may tempt you to skip verification — don’t. The interaction-endpoint example reads the raw body correctly, enforces a replay window, and rejects oversized bodies.

Discord runs automated security checks, deliberately sending invalid signatures; if your endpoint ever accepts one, Discord removes your interactions URL and notifies you.

  • Prefer webhooks (no token, no intents) for post-only needs.
  • Enable no privileged intents unless a feature truly needs them; below/above the 2026 user-count threshold the rules differ.
  • Request minimal OAuth2 scopes; compute an explicit permission bitfield instead of granting Administrator.
  • Scope tokens per environment (separate dev/prod apps).
  • Don’t request MESSAGE_CONTENT, email, or guilds unless you use them.
  • Cache the least you can; message content and member data are sensitive.
  • Have a deletion story for user data you store (and disclose it).
  • Rate-limit and validate all interaction inputs (never trust option values or custom IDs blindly — they can be crafted).
  • Use state + redirect_uri validation in OAuth2 to block CSRF/open redirects.
  • Idempotency: interactions can be retried; make handlers safe to run twice.

This atlas does not provide working self-bots, user-token automation, scraping of private endpoints for production, ban-evasion, or spam/mass-DM tooling. Automating a user account violates Discord’s Terms of Service and can get accounts and apps banned. Where such topics appear, they are labeled platform boundary and described for defensive understanding only. See SECURITY.md §4.