This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
devopscritical PriorityID: caddy-on-demand-tls-rate-limiting

Caddy 2 Hardened On-Demand TLS with Ask Endpoint Validation and HTTP/3 Proxying

Enforces secure On-Demand TLS configuration in Caddy 2 by mandating an authenticated internal 'ask' endpoint and edge rate limiting. Prevents Let's Encrypt Certificate Authority rate-limit exhaustion, disk exhaustion, and denial-of-service attacks driven by arbitrary SNI spoofing. Ensures proper HTTP/3 reverse proxy configuration with UDP 443 exposure and downstream connection sanitization.

Prohibited Anti-Pattern: Unrestricted On-Demand TLS Without Ask Verification and Inadequate Rate Limiting

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Caddy 2 Hardened On-Demand TLS with Ask Endpoint Validation and HTTP/3 Proxying - Enforces secure On-Demand TLS configuration in Caddy 2 by mandating an authenticated internal 'ask' endpoint and edge rate limiting. Prevents Let's Encrypt Certificate Authority rate-limit exhaustion, disk exhaustion, and denial-of-service attacks driven by arbitrary SNI spoofing. Ensures proper HTTP/3 reverse proxy configuration with UDP 443 exposure and downstream connection sanitization.
globs: Caddyfile, **/Caddyfile, **/caddy/*.conf, src/**/caddy*.ts, src/api/tls-check/**/*.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/caddy-on-demand-tls-rate-limiting"
---

# Caddy 2 Hardened On-Demand TLS with Ask Endpoint Validation and HTTP/3 Proxying

> **Severity**: CRITICAL | **Category**: devops
> **Anti-Pattern Warning**: Unrestricted On-Demand TLS Without Ask Verification and Inadequate Rate Limiting

## System Constraints
You are a Principal Software Architect and DevOps Security Engineer enforcing Caddy 2 infrastructure invariants. You must prohibit any Caddy On-Demand TLS configuration that lacks a strict internal 'ask' endpoint or lacks L4/L7 rate-limiting controls. Mandate hardened HTTP/3 reverse proxy directives, domain validation semantics, and robust protection against CA rate-limit exhaustion.

## Strict Guidelines
- Engineers MUST ALWAYS declare an explicit internal 'ask' URL inside the global 'on_demand_tls' block when 'on_demand' is enabled.
- Engineers MUST NOT expose the 'ask' endpoint to the public internet; it MUST resolve strictly via private networking or localhost loopback.
- The 'ask' endpoint MUST return HTTP 200 strictly for pre-registered, tenant-verified domain names, and HTTP 400/403/404 for all unknown, malformed, or unauthorized hostnames.
- Services MUST implement rate limiting on the 'ask' endpoint and edge ingress to guard against automated SNI flooding attacks attempting CA resource exhaustion.
- Caddy infrastructure configurations MUST explicitly configure UDP port 443 alongside TCP port 443 in firewall and container definitions to maintain valid HTTP/3 QUIC negotiation.
- Upstream reverse proxy directives MUST correctly forward standard proxy headers ('X-Forwarded-For', 'X-Forwarded-Proto', 'X-Forwarded-Host') and preserve HTTP/3 Alt-Svc headers without header tampering.

## Bad vs Good Implementations
### TypeScript Ask Endpoint Domain Verification Handler

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Approving any supplied domain unconditionally enables an attacker to send arbitrary SNI headers in TLS handshakes. Caddy will dynamically request certificates from Let's Encrypt for malicious or non-existent domains until CA rate limits are triggered and server storage is exhausted.
```typescript
import { Request, Response } from 'express';

// Flawed: Permits arbitrary hostnames, leading to Let's Encrypt CA limit exhaustion
export async function handleCaddyTlsAsk(req: Request, res: Response): Promise<void> {
  const domain = req.query.domain as string;
  if (domain) {
    // DANGEROUS: Approves any requested domain string
    res.status(200).send('OK');
    return;
  }
  res.status(400).send('Missing domain');
}
```

#### Production Standard (Correct)
> **Standard**: Validates source IP to prevent external tampering, strictly parses and sanitizes the requested domain name using regex schemas, and verifies domain tenancy against a trusted storage backend before returning HTTP 200.
```typescript
import { Request, Response } from 'express';
import { z } from 'zod';

const domainQuerySchema = z.object({
  domain: z.string()
    .trim()
    .toLowerCase()
    .max(253)
    .regex(/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/)
});

interface DomainValidator {
  isDomainAuthorized(domain: string): Promise<boolean>;
}

export function createCaddyAskHandler(validator: DomainValidator) {
  return async function handleCaddyTlsAsk(req: Request, res: Response): Promise<void> {
    // Reject requests originating outside internal trusted loopback/VPC
    const clientIp = req.socket.remoteAddress;
    if (clientIp !== '127.0.0.1' && clientIp !== '::1' && !clientIp?.startsWith('10.')) {
      res.status(403).setHeader('Content-Type', 'text/plain').send('Forbidden');
      return;
    }

    const parseResult = domainQuerySchema.safeParse(req.query);
    if (!parseResult.success) {
      res.status(400).setHeader('Content-Type', 'text/plain').send('Invalid domain format');
      return;
    }

    const { domain } = parseResult.data;
    const isAuthorized = await validator.isDomainAuthorized(domain);

    if (isAuthorized) {
      res.status(200).setHeader('Content-Type', 'text/plain').send('OK');
      return;
    }

    res.status(403).setHeader('Content-Type', 'text/plain').send('Domain unauthorized');
  };
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Caddy 2 Hardened On-Demand TLS with Ask Endpoint Validation and HTTP/3 Proxying

Caddy 2 Hardened On-Demand TLS with Ask Endpoint Validation and HTTP/3 Proxying defines an industrial-grade behavioral standard for devops engineering. Enforces secure On-Demand TLS configuration in Caddy 2 by mandating an authenticated internal 'ask' endpoint and edge rate limiting. Prevents Let's Encrypt Certificate Authority rate-limit exhaustion, disk exhaustion, and denial-of-service attacks driven by arbitrary SNI spoofing. Ensures proper HTTP/3 reverse proxy configuration with UDP 443 exposure and downstream connection sanitization. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Unrestricted On-Demand TLS Without Ask Verification and Inadequate Rate Limiting Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftUnrestricted On-Demand TLS Without Ask Verification and Inadequate Rate LimitingCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS declare an explicit internal 'ask' URL inside the global 'on_demand_tls' block when 'on_demand' is enabled.

Engineers MUST ALWAYS declare an explicit internal 'ask' URL inside the global 'on_demand_tls' block when 'on_demand' is enabled.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT expose the 'ask' endpoint to the public internet

Engineers MUST NOT expose the 'ask' endpoint to the public internet; it MUST resolve strictly via private networking or localhost loopback.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

The 'ask' endpoint MUST return HTTP 200 strictly for pre-registered, tenant-verified domain names, and HTTP 400/403/404 for all unknown, malformed, or unauthorized hostnames.

The 'ask' endpoint MUST return HTTP 200 strictly for pre-registered, tenant-verified domain names, and HTTP 400/403/404 for all unknown, malformed, or unauthorized hostnames.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST implement rate limiting on the 'ask' endpoint and edge ingress to guard against automated SNI flooding attacks attempting CA resource exhaustion.

Services MUST implement rate limiting on the 'ask' endpoint and edge ingress to guard against automated SNI flooding attacks attempting CA resource exhaustion.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Caddy infrastructure configurations MUST explicitly configure UDP port 443 alongside TCP port 443 in firewall and container definitions to maintain valid HTTP/3 QUIC negotiation.

Caddy infrastructure configurations MUST explicitly configure UDP port 443 alongside TCP port 443 in firewall and container definitions to maintain valid HTTP/3 QUIC negotiation.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Upstream reverse proxy directives MUST correctly forward standard proxy headers ('X-Forwarded-For', 'X-Forwarded-Proto', 'X-Forwarded-Host') and preserve HTTP/3 Alt-Svc headers without header tampering.

Upstream reverse proxy directives MUST correctly forward standard proxy headers ('X-Forwarded-For', 'X-Forwarded-Proto', 'X-Forwarded-Host') and preserve HTTP/3 Alt-Svc headers without header tampering.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Caddy 2 Hardened On-Demand TLS with Ask Endpoint Validation and HTTP/3 Proxying critical for AI coding assistants?

Enforces secure On-Demand TLS configuration in Caddy 2 by mandating an authenticated internal 'ask' endpoint and edge rate limiting. Prevents Let's Encrypt Certificate Authority rate-limit exhaustion, disk exhaustion, and denial-of-service attacks driven by arbitrary SNI spoofing. Ensures proper HTTP/3 reverse proxy configuration with UDP 443 exposure and downstream connection sanitization. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Unrestricted On-Demand TLS Without Ask Verification and Inadequate Rate Limiting) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Caddy