Redacting Vaultwarden access_token parameter with Caddy

1. The problem I’m having:

I am trying to make my vaultwarden docker container instance more secure by following this hardening guide. Specifically I am trying to follow the part of the guide that advises to redact the value of the access_token parameter in the access.log file for caddy. I run caddy, vaultwarden and another service all as docker containers. However when I try to add this suggestion from Chat GPT to add to my Caddyfile:

format filter {
			wrap json
			fields {
				request>uri redact {
					query access_token
				}
			}
		}

I get errors when I run the command docker logs -f caddy which can be seen below. I think the issue is related to the caddy binary I’m using but I have to use this specific caddy binary because it has support for DNS challenges and duckdns domains. I have added further details in the appropriate sections.

2. Error messages and/or full log output:

docker logs -f caddy:
{"level":"info","ts":1735148027.6933646,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: parsing caddyfile tokens for 'log': getting module named 'caddy.logging.encoders.filter.redact': module not registered: caddy.logging.encoders.filter.redact, at /etc/caddy/Caddyfile:55
{"level":"info","ts":1735148030.4536636,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: parsing caddyfile tokens for 'log': getting module named 'caddy.logging.encoders.filter.redact': module not registered: caddy.logging.encoders.filter.redact, at /etc/caddy/Caddyfile:55
{"level":"info","ts":1735148032.3835313,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}

3. Caddy version:

caddy version:
v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

file caddy binary:
caddy: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, Go BuildID=d2CUgHd5v5KarbWhll50/spUmDDdeK-sOxRIzlMTs/ODBKUlz7E8KeiCtYfzIm/dhB6KAm-bEo07d_o6xDW, stripped

4. How I installed and ran Caddy:

Followed this guide and installed Linux arm64 caddy-dns/duckdns caddy binary:

a. System environment:

Host OS is a Raspberry Pi 4B running Raspberry Pi OS kernal version:
6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux

docker version:
27.4.1

b. Command:

c. Service/unit/compose file:

docker compose file:

services:
  caddy:
    container_name: caddy
    image: caddy:2
    restart: always
    ports:
      - 80:80
      - 443:443
      - 443:443/udp # Needed for HTTP/3.
    volumes:
      - /usr/local/bin/caddy:/usr/bin/caddy  
      - /usr/local/bin/Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-config:/config
      - ./caddy-data:/data
      - /opt/docker_secrets/caddy:/run/secrets:ro
    env_file:
      - /opt/docker_env/caddy/caddy.env
    environment:
      - DUCKDNS_TOKEN=<redacted>

  unifi-network-application:
    container_name: unifi-network-application
    image: lscr.io/linuxserver/unifi-network-application:latest
    restart: unless-stopped
    ports:
      #- 8443:8443
      - 3478:3478/udp
      - 10001:10001/udp
      - 8080:8080
      - 1900:1900/udp #optional
      #- 8843:8843 #optional
      #- 8880:8880 #optional
      #- 6789:6789 #optional
      #- 5514:5514/udp #optional
    volumes:
      - ./unifi-network-application/config:/config
      - ./unifi-network-application/data:/data
    env_file:
      - /opt/docker_env/unifi/unifi.env
    environment:
      - MONGO_PASS=<redacted>

  unifi-db:
    container_name: unifi-db
    image: mongodb-raspberrypi4-unofficial-r7.0.0:latest
    restart: unless-stopped
    volumes:
      - ./unifi-db/data:/data/db
      - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro

  vaultwarden:
    container_name: vaultwarden
    image: vaultwarden/server:latest
    restart: always
    volumes:
      - ./vw-data:/data # the path before the : can be changed
    env_file:
      - /opt/docker_env/vaultwarden/vaultwarden.env
    environment:
       - ADMIN_TOKEN=<redacted>

caddy.env file for compose file:

DOMAIN=<redacted>
LOG_FILE=/data/access.log

d. My complete Caddy config:

Caddyfile:

*.{$DOMAIN} {
	tls {
		dns duckdns {$DUCKDNS_TOKEN}
	}

	# Logs configuration (optional, adjust as necessary)
	log {
		level INFO
		output file {$LOG_FILE} {
			roll_size 10MB
			roll_keep 10
		}
	}

	# Default reverse proxy to a generic service if no specific service matches
	reverse_proxy service_default:80
}

# Vaultwarden Service
vaultwarden.{$DOMAIN} {
	reverse_proxy vaultwarden:80
	log {
		level INFO
		output file {$LOG_FILE} {
			roll_size 10MB
			roll_keep 10
		}
		format filter {
			wrap json
			fields {
				request>uri redact {
					query access_token
				}
			}
		}
	}
}

unifi.{$DOMAIN} {
	reverse_proxy unifi-network-application:8443 {
		transport http {
			tls_insecure_skip_verify
		}
	}

	# Add an optional redirect rule for "http://unifi.<your-domain>"
	#redir https://unifi.{$DOMAIN} permanent

	log {
		level INFO
		output file {$LOG_FILE} {
			roll_size 10MB
			roll_keep 10
		}
	}
}

unifi.{$DOMAIN}:8443 {
	redir https://unifi.{$DOMAIN} permanent
}

5. Links to relevant resources:

Do not ask LLM for knowledge because they aren’t good at it.

Always refer to the official documentation because it’s, well, official:

So your config would look something like this:

format filter {
	wrap json
	fields {
		request>uri query {
			delete access_token
		}
	}
}

Thank you for your answer. I checked out the documentation and in the end adapted this example:

example.com {
   log {
   	format filter {
   		request>headers>Cookie cookie {
   			replace session REDACTED
   			delete secret
   		}
   	}
   }
}

It now replaces the access token with the string ‘REDACTED’. Thank you for pointing me in the right direction.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.