Skip to content

SecureWebhookToken/swt

Repository files navigation

SecureWebhookToken (SWT)

GitHub Tag Go Report Card GitHub go.mod Go version Coverage Go Reference License: MIT

SecureWebhookToken is an Internet-Draft for sending secure Webhooks, based on the JWT standard. See Documentation for more details.

Install

go get github.com/SecureWebhookToken/swt

Examples

Client / Server

package main

import (
	"fmt"
	"log/slog"
	"net/http"

	"github.com/SecureWebhookToken/swt"
)

const (
	issuer = "https://example.com"
	url    = "http://localhost:8080/webhook"
)

// WARNING: This is a weak secret for demonstration purposes only!
// In production, use a strong, randomly generated secret key.
// Generate one with: openssl rand -base64 32
var secretKey = []byte("INSECURE-EXAMPLE-SECRET-DO-NOT-USE-IN-PRODUCTION")

func main() {
	go startServer()

	// Valid webhook request
	swtReq := swt.Request{
		URL:    url,
		Issuer: issuer,
		Event:  "send.stars",
		Data:   []byte(`{"username": "me", "stars": "567"}`),
	}

	req, err := swtReq.Build(secretKey)
	if err != nil {
		slog.Error(fmt.Errorf("error building request: %w", err).Error())
		return
	}

	httpClient := &http.Client{}
	res, err := httpClient.Do(req)
	if err != nil {
		slog.Error("Error executing request", "error", err)
		return
	}

	slog.Info("Successfully executed request", "status", res.StatusCode)

	// Invalid issuer webhook request
	swtReq = swt.Request{
		URL:    url,
		Issuer: "issuer",
		Event:  "send.stars",
		Data:   []byte(`{"username": "me", "stars": "567"}`),
	}

	req, err = swtReq.Build(secretKey)
	if err != nil {
		slog.Error(fmt.Errorf("error building request: %w", err).Error())
		return
	}

	httpClient = &http.Client{}
	res, err = httpClient.Do(req)
	if err != nil {
		slog.Error("Error executing request", "error", err)
		return
	}

	slog.Info("Successfully executed request", "status", res.StatusCode)
}

func startServer() {
	handler, err := swt.NewHandlerFunc(secretKey, func(token *swt.SecureWebhookToken, data []byte) error {
		slog.Info("Successfully received token: " + token.String())

		//Validate issuer
		if token.Issuer() != issuer {
			return fmt.Errorf("invalid issuer")
		}

		slog.Info("Successfully received webhook data: " + string(data))

		return nil
	}, nil)
	if err != nil {
		slog.Error("Failed to create handler", "error", err)
		return
	}

	http.Handle("/webhook", handler)

	slog.Error("Server error", "error", http.ListenAndServe(":8080", nil))
}

About

Go implementation of the Secure Webhook Token (SWT), an Internet-Draft for sending secure Webhooks, based on the JWT standard.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors