Servant combinators to facilitate writing GitHub webhooks.

Version on this page:
LTS Haskell 17.15:
Stackage Nightly 2022-02-07:
Latest on Hackage:

See all snapshots servant-github-webhook appears in

MIT licensed by Jacob Thomas Errington
Maintained by [email protected]
This version can be pinned in stack with:servant-github-webhook-,2754

Module documentation for


Build Status Hackage servant-github-webhook servant-github-webhook

This library facilitates writing Servant routes that can safely act as GitHub webhooks.


  • Dispatching to routes based on the type of repository event.
  • Automatic verification of request signatures.
  • Route protection expressed in the type system, so webhook routes and regular routes cannot be confused.

Why use servant-github-webhook?

A webhook server needs to be publicly hosted. How can legitimate requests sent by GitHub be distinguished from (malicious) requests sent by other clients?

When a webhook is configured on a repository, a secret key is added. This key is used by GitHub to compute a signature of the request body that it sends; this signature is included in the request headers. The routing combinators in servant-github-webhook compute the signature of the received request body using the same key, and check that the signature in the request headers matches. If it does, then the request is legitimate.


Revision history for servant-github-webhook – 2018-04-07

  • Include integration with github-webhooks package.
  • Code is adjusted for backwards-compatibility with GHC 7.10.
  • HasServer instances are updated for servant-0.13 or later, due to hoistServerWithContext. – 2018-02-03

  • Use constant-time equality to check signatures.
  • Add dynamic key capabilities. – 2017-12-25

  • Support GHC 8.2 / base 4.10.
  • Bump up version bound for github to 0.18. – 2017-08-06

  • Drop support for GHC <8.
  • Drop support for Servant <0.11.
  • Switch from Crypto package to cryptonite package.
  • Now servant-github-webhook builds with stack. – 2016-09-22

  • Pass reflected key index to the handler function for GitHubSignedReqBody. This allows for more generic handler functions, as they can determine programmatically which repository they are responding to. – 2016-09-13

  • Improve documentation (formatting and typos) and examples (remove unnecessary verbosity). – 2016-09-11

  • Generalize GitHubSignedReqBody combinator to GitHubSignedReqBody'' to allow for configuring multiple signing keys, on a per-route basis.
  • Make GitHubKey take a function instead of simply an IO action.
  • Reexport KProxy, to make writing Demote' instances easier. – 2016-09-10

Initial release.

  • Implement GitHubSignedReqBody combinator for automatic signature verification during routing.
  • Implement GitHubEvent combinator for dispatching to routes based on the webhook type.
  • Known issue: only one global GitHubKey can be used across all routes.