---
title: "Secure Caddy APIs with API Key Authentication"
description: "Secure your Caddy API using a shared secret."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/go/caddy/secure-header"
framework: "Caddy"
language: "Go"
authStrategy: "shared secret header"
pageType: use-case
---

# Secure Caddy APIs with API Key Authentication

Secure your Caddy API using a shared secret.

## How Zuplo Handles It

Put Zuplo in front of your Caddy backend to authenticate API keys and forward a shared secret header so your origin only accepts traffic from Zuplo.

## Caddy Backend Code

```go
package main

import (
	"crypto/subtle"
	"fmt"
	"net/http"
	"os"

	"github.com/caddyserver/caddy/v2"
	"github.com/caddyserver/caddy/v2/modules/caddyhttp"
)

// SharedSecretMiddleware is a Caddy middleware for securing routes with a shared secret
type SharedSecretMiddleware struct{}

// ServeHTTP method to implement the shared secret validation
func (SharedSecretMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
	secret := r.Header.Get("X-Shared-Secret")
	expectedSecret := os.Getenv("SHARED_SECRET")

	if expectedSecret == "" {
		http.Error(w, "Server configuration error", http.StatusInternalServerError)
		return nil
	}

	if secret == "" {
		http.Error(w, "No secret provided", http.StatusUnauthorized)
		return nil
	}

	if subtle.ConstantTimeCompare([]byte(secret), []byte(expectedSecret)) != 1 {
		http.Error(w, "Invalid secret", http.StatusUnauthorized)
		return nil
	}

	return next.ServeHTTP(w, r)
}

// CaddyModule returns the Caddy module information
func (SharedSecretMiddleware) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "http.handlers.shared_secret",
		New: func() caddy.Module { return new(SharedSecretMiddleware) },
	}
}

// ProtectedHandler demonstration of a protected endpoint
func ProtectedHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	fmt.Fprintln(w, `{"message": "Access granted"}`)
}

// init the module
func init() {
	caddy.RegisterModule(SharedSecretMiddleware{})
}

func main() {
	// Caddy should be configured to use this middleware for specific routes
	http.HandleFunc("/protected", ProtectedHandler)
}
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
