A production-ready Go service that receives authentication webhooks from Supabase/GoTrue and processes user events (signup, update, delete) for Email, Apple ID, and Google ID providers.
- Standard Webhooks signature verification (used by Supabase)
- Prometheus metrics for monitoring
- Structured JSON logging with emoji indicators
- Graceful shutdown handling
- Kubernetes-ready with HPA, PDB, and health checks
- Horizontally scalable
Set the following environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
WEBHOOK_SECRET |
Yes | - | Standard Webhooks secret (base64, optionally prefixed with whsec_) |
DATABASE_URL |
Yes | - | PostgreSQL connection string |
PORT |
No | 8080 | HTTP server port |
METRICS_PORT |
No | 9090 | Prometheus metrics port |
LOG_LEVEL |
No | info | Log level (debug, info, warn, error) |
# Set required environment variables
export WEBHOOK_SECRET=your-secret-here
export DATABASE_URL=postgres://user:pass@localhost:5432/dbname?sslmode=disable
# Run locally
make run
# Run tests
make test
# Build binary
make build
# Build Docker image
make docker-build| Endpoint | Description |
|---|---|
POST /webhook/auth |
Receives auth webhooks from Supabase |
GET /healthz |
Liveness probe |
GET /readyz |
Readiness probe |
GET /metrics |
Prometheus metrics (port 9090) |
The service expects webhooks in the Supabase/GoTrue format:
{
"type": "INSERT",
"table": "users",
"schema": "auth",
"record": {
"id": "user-uuid",
"email": "[email protected]",
"providers": ["google"]
}
}This service uses Standard Webhooks for signature verification, which is the same specification used by Supabase.
Required headers:
webhook-id- Unique message identifierwebhook-timestamp- Unix timestamp (seconds)webhook-signature- HMAC-SHA256 signature in formatv1,<base64-signature>
The signature is computed as: base64(HMAC-SHA256(${webhook-id}.${webhook-timestamp}.${body}, secret))
Timestamps older than 5 minutes are rejected to prevent replay attacks.
The service expects a user_profiles table:
CREATE TABLE user_profiles (
id UUID PRIMARY KEY,
email TEXT,
provider TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);# Review and update secrets
vim infra/kubernetes/secret.yaml
# Deploy with kustomize
kubectl apply -k infra/kubernetes/
# Or apply individually
kubectl apply -f infra/kubernetes/namespace.yaml
kubectl apply -f infra/kubernetes/Key Prometheus metrics:
auth_webhooks_received_total- Total webhooks received by event typeauth_webhooks_processed_total- Successfully processed webhooksauth_webhook_errors_total- Processing errors by typeauth_webhook_duration_seconds- Processing latency histogramauth_webhook_signature_failures_total- Failed signature verificationsauth_webhook_active_connections- Current active connections
# Format code
make fmt
# Run linter
make lint
# Run tests with coverage
make test-cover
# Run tests with race detector
make test-race