Base64 and URL encoding/decoding of headers or placeholders

1. Caddy version (caddy version):

v2.3.0

2. How I run Caddy:

a. System environment:

Docker

b. Command:

caddy run --config /etc/caddy/Caddyfile --adapter caddyfile --watch

c. Service/unit/compose file:

services:
  caddy:
    container_name: caddy
    build:
      context: caddy-build/.
      args:
        - CADDY_VERSION=${CADDY_VERSION}
    logging: *default-logging
    restart: always
    networks:
      - proxy
    environment:
      DOMAINNAME: "${DOMAINNAME}"
    ports:
      - "80:80/tcp"
      - "443:443"
      - "2019:2019"
    command: ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile", "--watch"]
    volumes:
      - "./certs:/certs" # file provider directory
      - "./caddy/data:/data"
      - "./caddy/Caddyfile:/etc/caddy/Caddyfile"  # to mount custom Caddyfile

d. My complete Caddyfile or JSON config:

{
	debug
	# auto_https off
}

localhost

header Authorization {system.os}:{scheme}:{tls_cipher}
respond "OK" 200

3. The problem I’m having:

I would like to be able to base64 encode and decode values to be used in request headers (and other places). One example would be to get a username from a JWT cookie and from that create a basic auth header to then send to a downstream server. E.g.

oldhost.example.com {
	route {
		jwt
		header Authorization "{http.auth.user.id}:mystaticpassword" # Need to base64 this value
		reverse_proxy oldhost:80
	}
}

If this functionality doesn’t exist I’m assuming I’d have to write a plugin (calling it alter, or mutate) that can encode/decode headers specifically, or maybe even placeholders?

Otherwise it might be a natural fit for https://github.com/caddyserver/caddy/blob/master/modules/caddyhttp/headers/headers.go? However I think adding another option to encode/decode would break the existing config syntax?

A long shot, would it be possible to extend placeholders with Jinja-like filters? E.g. {http.auth.user.id | base64}.

4. Error messages and/or full log output:

5. What I already tried:

6. Links to relevant resources:

https://jinja.palletsprojects.com/en/2.11.x/templates/#filters

Caddy already supports templating via the template directive:

Which uses Go’s text/template package plus all of these Sprig functions (including b64enc which is what you’d want):

But templates are only for response bodies.

Maybe the easiest thing for you to do is make a plugin which is basically a straight copy of the header handler but which passes your value through that templating system first.

I’m not sure such a feature would be accepted in Caddy itself since it’s a pretty niche requirement and would likely hurt performance unless it was opt-in somehow, but making it opt-in would add needless complexity.

1 Like

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