Skip to content

Caddy JWT Authentication

Beau Barker edited this page Nov 5, 2025 · 13 revisions

Authenticating in the API gateway means you can protect endpoints such as static files or custom services.

Create a JWT Secret

Note

Caddy can share the JWT secret with PostgREST.

Generate a secret:

openssl rand -base64 32

Important

caddy-jwt requires the secret to be base64 encoded.

Put the secret in the environment file:

app/.env

# JWT secret used by both Caddy and PostgREST
JWT_SECRET=(your secret)

Add the secret to the Compose file:

app/compose.yaml

caddy:
  environment:
    JWT_SECRET: ${JWT_SECRET:?}

Install caddy-jwt

Build Caddy with caddy-jwt, a Caddy module that facilitates JWT authentication:

app/caddy/Dockerfile

FROM caddy:2-builder AS builder

RUN xcaddy build \
  --with github.com/ggicci/[email protected]

FROM caddy:2

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

# Copy our Caddyfile into the image
COPY Caddyfile /etc/caddy/Caddyfile

Build the image:

docker compose build caddy

Caddyfile

Split your Caddyfile into public and JWT-protected sections. The private routes require a valid access token:

app/caddy/Caddyfile

{$CADDY_SITE_ADDRESS}

# --- Public routes ---

# PostgREST's OpenAPI endpoint
handle_path /rest/ {
  reverse_proxy http://postgrest:3000
}

# --- JWT protected routes ---

route {

  jwtauth {
    sign_key {env.JWT_SECRET}
    sign_alg HS256
    from_cookies access_token
    from_header Authorization
  }

  # Set the Authorization header from the Cookie header
  # Only if it's not already set
  @noHeader not header Authorization *
  request_header Authorization "Bearer {cookie.access_token}" # fallback to cookie

  # .. Private endpoints ..

}

Restart Caddy for the changes to take effect:

docker compose up -d --force-recreate caddy
Clone this wiki locally