Security
Report vulnerabilities privately through GitHub Security Advisories, never as a public issue. The full policy is in SECURITY.md.
What Dispatch promises
If you can break one of these, it is a finding.
Webhooks are verified over raw bytes. HMAC-SHA256 with a timing-safe compare, and a length check first — timingSafeEqual throws on a mismatch, and that throw is itself an oracle. The verifier never sees a re-serialised payload.
Commands require write access. /dispatch runs only for OWNER, MEMBER, or COLLABORATOR. A command must be alone on its line, and commands inside markdown quotes are ignored — otherwise quoting someone's comment would execute it.
Pull request code is never executed. Metadata is read through the API. Nothing is checked out, built, or evaluated from a contributor's branch.
Redaction happens before state leaves the process, including into recorded fixtures. The recorder asks the provider what it actually sent rather than recording what it was handed.
Installation keys are encrypted at rest with AES-256-GCM under a master key that lives in the environment, never in the database.
Destructive actions require opt-in. close, lock, minimize and convert_to_discussion are suppressed unless named in allowDestructive, and no shipped default enables one.
Out of scope
- The model being wrong. Miscalibration is a quality bug — open a normal issue with
dispatch evaloutput. - Dependency advisories with no exploitable path through Dispatch.
- A
pull_request_targetworkflow that someone added a checkout step to. That is documented as a repository takeover in three places.
Hardening a deployment
- Pin the Action to a commit, not a moving tag
- Stay on
mode: shadowuntildispatch evalshows calibration you believe - Leave
allowDestructiveempty unless you have a reason - Set
budget.maxRequestsPerDayso a runaway loop has a ceiling - Self-host the App if issue text must not leave your infrastructure