{
	admin off
	email {$ACME_EMAIL:adrianodalpastro@tielogic.com}
	auto_https {$AUTO_HTTPS:on}

	# Plugin mholt/caddy-ratelimit
	order rate_limit before basicauth

	# Trusted proxies: rispetta X-Forwarded-For quando dietro reverse proxy
	# (es. Traefik). Default = solo private ranges.
	servers {
		trusted_proxies static {$TRUSTED_PROXIES:private_ranges}
	}
}

{$LISTEN:cerbero-mcp.tielogic.xyz} {
	log {
		output stdout
		format json
	}

	# ───── Security headers ─────
	header {
		Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
		X-Content-Type-Options "nosniff"
		X-Frame-Options "DENY"
		Referrer-Policy "no-referrer"
		-Server
	}

	# ───── IP allowlist su endpoint write ─────
	# WRITE_ALLOWLIST: CIDR space-separated (es. "1.2.3.4/32 5.6.7.0/24").
	# Default 127.0.0.1/32 — fail-closed se non configurato.
	@writes_blocked {
		path_regexp ^/mcp-[a-z]+/tools/(place_|cancel_|set_|close_|transfer_|amend_|switch_)
		not remote_ip {$WRITE_ALLOWLIST:127.0.0.1/32 ::1/128 172.16.0.0/12}
	}
	respond @writes_blocked "forbidden: source ip not in allowlist" 403

	# ───── Rate limit ─────
	# Reads: 60 req/min/IP, writes: 10 req/min/IP (sliding window).
	rate_limit {
		zone reads {
			match {
				not path_regexp ^/mcp-[a-z]+/tools/(place_|cancel_|set_|close_|transfer_|amend_|switch_)
			}
			key {remote_ip}
			events 60
			window 1m
		}
		zone writes {
			match {
				path_regexp ^/mcp-[a-z]+/tools/(place_|cancel_|set_|close_|transfer_|amend_|switch_)
			}
			key {remote_ip}
			events 10
			window 1m
		}
	}

	# ───── Reverse proxy ─────
	handle_path /mcp-deribit/* {
		reverse_proxy mcp-deribit:9011
	}
	handle_path /mcp-bybit/* {
		reverse_proxy mcp-bybit:9019
	}
	handle_path /mcp-hyperliquid/* {
		reverse_proxy mcp-hyperliquid:9012
	}
	handle_path /mcp-alpaca/* {
		reverse_proxy mcp-alpaca:9020
	}
	handle_path /mcp-macro/* {
		reverse_proxy mcp-macro:9013
	}
	handle_path /mcp-sentiment/* {
		reverse_proxy mcp-sentiment:9014
	}

	# Landing page statica
	handle {
		root * /srv
		file_server
	}
}
