Discourse signing parameters in webhooks

Hey. I would like to use Discourse webhooks for when a user is created or updated, but I would like to be able to trust the data sent over by Discourse. Any way we could have at a public-private key support, or at least a symmetric secret key, that I can use to verify the signed payload? Can we have some standard framework for signing all the payloads and a standard PHP implementation, say, to serialize and verify the signature?

Facebook does it when it sends over the information about a user. This would allow other software to integrate with Discourse users and other objects.

Does the Webhook Secret key come close to what you are looking for? Here’s how the WP Discourse plugin verifies it against the Webhook Secret that gets set on WordPress:

public function verify_discourse_webhook_request( $data ) {
	$options = $this->get_options();
	// The X-Discourse-Event-Signature consists of 'sha256=' . hamc of raw payload.
	// It is generated by computing `hash_hmac( 'sha256', $payload, $secret )`.
	$sig = substr( $data->get_header( 'X-Discourse-Event-Signature' ), 7 );
	if ( $sig ) {
		$payload = $data->get_body();
		// Key used for verifying the request - a matching key needs to be set on the Discourse webhook.
		$secret = ! empty( $options['webhook-secret'] ) ? $options['webhook-secret'] : '';

		if ( ! $secret ) {

			return new \WP_Error( 'discourse_webhook_configuration_error', 'The webhook secret key has not been set.' );
		}

		if ( hash_hmac( 'sha256', $payload, $secret ) === $sig ) {

			return $data;
		} else {

			return new \WP_Error( 'discourse_webhook_authentication_error', 'Discourse Webhook Request Error: signatures did not match.' );
		}
	}

	return new \WP_Error( 'discourse_webhook_authentication_error', 'Discourse Webhook Request Error: the X-Discourse-Event-Signature was not set for the request.' );
}
3 Likes