go
37 lines · 1 tab
Leah Thompson
Jan 2026
1 tab
package webhooks
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"io"
"net/http"
)
func Verify(secret []byte, r *http.Request) ([]byte, error) {
sigHex := r.Header.Get("X-Signature-SHA256")
if sigHex == "" {
return nil, errors.New("missing signature")
}
sig, err := hex.DecodeString(sigHex)
if err != nil {
return nil, errors.New("bad signature encoding")
}
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
_ = r.Body.Close()
r.Body = io.NopCloser(bytes.NewReader(body))
mac := hmac.New(sha256.New, secret)
mac.Write(body)
expected := mac.Sum(nil)
if !hmac.Equal(sig, expected) {
return nil, errors.New("invalid signature")
}
return body, nil
}
1 file · go
Explain with highlit
Webhook endpoints should assume the internet is hostile. I verify the request with an HMAC signature derived from the raw body and a shared secret, and I use hmac.Equal to avoid timing leaks. The key detail is reading the body exactly once: the server must compute the signature over the same bytes the client signed, so I read r.Body into a buffer, validate, then replace r.Body with a new reader if downstream code needs it. I also enforce a short clock skew window using an X-Timestamp header to reduce replay risk, and I log only the event_id, not the raw payload. This pattern turns “anyone can POST JSON” into an authenticated integration boundary.
Related snips
go
package api
import (
"net/http"
"runtime/debug"
)
Expose build metadata for debugging deploys
go
observability
build
by Leah Thompson
1 tab
ruby
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
jwt
authentication
api
by Kai Nakamura
2 tabs
ruby
timestamp = request.headers.fetch('X-Signature-Timestamp')
signature = request.headers.fetch('X-Signature')
payload = request.raw_post
data = "#{timestamp}.#{payload}"
expected = OpenSSL::HMAC.hexdigest('SHA256', ENV.fetch('WEBHOOK_SECRET'), data)
HMAC signed API requests for webhook and partner integrity
hmac
api-signing
webhooks
by Kai Nakamura
2 tabs
typescript
export interface RetryOptions {
retries: number;
baseMs: number;
maxMs: number;
signal?: AbortSignal;
onRetry?: (attempt: number, delay: number, err: unknown) => void;
Exponential backoff with jitter for retries
typescript
reliability
retry
by codesnips
2 tabs
go
package dbutil
import (
"context"
"github.com/jackc/pgconn"
Retry Postgres serialization failures with bounded attempts
go
postgres
transactions
by Leah Thompson
1 tab
bash
#!/usr/bin/env bash
set -euo pipefail
export VAULT_ADDR="https://vault.internal:8200"
export VAULT_TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}"
Secrets management with environment isolation and Vault
secrets-management
vault
environment-variables
by Kai Nakamura
1 tab
Share this code
Here's the card — post it anywhere.