How to verify a header to validate an API key

1. My Caddy version (caddy -version):

Caddy version: v1.0.4

2. How I run Caddy:

I run Caddy on an Alpine Docker container, with custom config files for API proxying. I’m intending to run this setup on a ECS Fargate infrastructure to replace an AWS API Gateway/Lambda setup.

a. System environment:

Docker Alpine latest

b. Command:


c. Service/unit/compose file:


d. My complete Caddyfile:

(keep in mind this won’t be the definitive config, I’m just working on a PoC)


:8080 {
    status 200 /health
    log stdout

    import ./Caddyfile.users


proxy /test {
    without /test

3. The problem I’m having:

I’m migrating from AWS API Gateway to a Docker setup, and I wanted to use Caddy as an API manager of sorts. Right now I’ve got that going on, but I need to validate API keys inside Caddy (since they cannot be validated in the microservices).

Since it’s a API Gateway migration, we need to keep it compatible with current users, so I need to validate that a custom header (X-API-Key) has a specific value (which could be static, or read from the environment).

I cannot find anything like that anywhere, so I was wondering if maybe I had to write a plugin for it?

4. Error messages and/or full log output:


5. What I already tried:

  • Basic Auth
  • JWT

6. Links to relevant resources:


Hi @krashprocess, welcome to the Caddy community!

You can set up a form of authentication just by, for example, issuing a 403 to requests that don’t have that header. Also, the Caddyfile is capable of reading environmental variables, so checking against a static value or an env var is possible.

What kind of behaviour do you want to see if a request fails this check?

Hello! Thanks for the reply.

Basically if a request has an incorrect API key in the header, or has no header at all, I’d like to reply with a 403 Forbidden. If the request has a correct API key it’d just continue the request.

I just cannot figure how to do this :frowning:. I’ve seen you can have if conditions in rewrite, but I cannot seem to find something similar outside the rewrites.

Thanks again!!

No worries!

The trick is that you can combine the rewrite with something else, like status. These kinds of “rewrite hacks” enable some handy functionality in Caddy v1.

Something like this would work:

  rewrite {
    if {>X-API-Key} not {$API_KEY_ENV_VAR}
    to /forbidden
  status 403 /forbidden

So we’re rewriting to a path we’re then explicitly instructing Caddy to issue an otherwise-empty 403 response for.

1 Like

Amazing, it does exactly what I needed!!!

Thank you very much! Hope you have an amazing day!

1 Like

This topic was automatically closed after 180 days. New replies are no longer allowed.