Security Auditing
Relevant source files
The following files were used as context for generating this wiki page:
Security Auditing in kamal-proxy encompasses the systematic review and enforcement of access controls, encrypted communication, and request validation. The system is designed to protect upstream targets by intercepting requests at the proxy level to apply authentication, IP filtering, and rate limiting before traffic reaches the application layer.
The scope of security auditing covers TLS/certificate handling, request parsing, header forwarding, ACME protocols, and the security of the underlying Unix socket used for RPC communication. Key focus areas include ensuring that sensitive credentials never cross the RPC socket in plaintext and that internal proxy probes (such as TLS on-demand checks) are exempt from standard security challenges to prevent service deadlock.
Sources: .claude/commands/security.md, internal/server/service.go:420-435, ROADMAP.md:38-50
Authentication and Access Control
Basic Authentication
The proxy supports per-service HTTP Basic Authentication. A critical security property of this implementation is that credentials are hashed on the CLI side using salted SHA-256 before being transmitted over the RPC socket or stored in state files. This ensures that no plaintext passwords exist within the proxy's memory or persistent storage.
Sources: internal/server/basic_auth_test.go:207-215, internal/cmd/deploy.go:193-205, ROADMAP.md:38-42
IP Allow and Deny Lists
Access can be restricted using CIDR-based allow and deny lists. The proxy evaluates these rules against the connecting peer's address. If the peer is identified as a trusted proxy (via --trusted-proxy), the proxy instead evaluates the X-Forwarded-For chain. Deny rules are processed before allow rules; an address present in both is rejected with a 403 Forbidden.
Sources: internal/server/service.go:119-130, internal/server/deny_list_service_test.go:61-75, ROADMAP.md:43-46
Request Processing Flow
The following diagram illustrates the sequence of security checks performed during a service request.
The security check order ensures that blocked networks are refused before expensive operations (like TLS redirection) or credential solicitation occurs.
Sources: internal/server/service.go:530-560, internal/server/deny_list_service_test.go:80-100, internal/server/basic_auth_test.go:230-245
TLS and Certificate Management
kamal-proxy manages TLS certificates through a SANCertManager that supports SAN batching (up to 100 domains) and DNS-01/HTTP-01 ACME challenges.
Security Boundaries in Provisioning
The proxy implements a hard allowlist for certificate provisioning to prevent rate-limit exhaustion attacks:
- Synchronous Provisioning: Only for deploy-registered hosts.
- Asynchronous Issuance: For dynamic domains learned at runtime.
- Refusal: Any other server name is refused to prevent scanners from burning ACME quotas.
Sources: internal/server/san_cert_manager.go:285-305, ROADMAP.md:52-55
Mutual TLS (mTLS)
The system supports mTLS by requiring client certificates signed by a specific CA bundle via the --tls-client-ca-path flag. When configured, this turns on ClientCAs validation in the tls.Config for the service's hosts.
Sources: internal/server/service.go:88-91, internal/cmd/deploy.go:48
| Feature | Configuration Flag | Security Impact |
|---|---|---|
| Basic Auth | --basic-auth | CLI-side hashing (SHA-256) prevents plaintext exposure in RPC/State. |
| IP Deny List | --deny-ip | Rejects malicious CIDRs before authentication or rate limiting. |
| mTLS | --tls-client-ca-path | Validates client identity via X.509 certificate chain. |
| Internal Exemption | N/A (Internal Context) | Prevents proxy probes from locking themselves out of security checks. |
| Sources: internal/server/service.go:80-150, internal/cmd/deploy.go:40-100, internal/server/basic_auth_test.go:375-385 |
Secure Persistence and State Management
The proxy maintains its state (services, targets, and certificates) in a .state file. To protect sensitive metadata and certificate digests, the proxy enforces strict filesystem permissions.
- File Permissions: The state file is created with permissions that prevent it from being world-readable (
0o600). - Atomic Writes: Updates to the state file use a temporary file and an atomic rename to prevent corruption or partial state exposure.
Sources: internal/server/basic_auth_test.go:355-370, internal/server/san_cert_manager.go:616-630
This flow ensures that even if the RPC socket is intercepted or the state file is accessed by an unauthorized local user, the original credentials remain secure.
Sources: internal/cmd/deploy.go:195-205, internal/server/basic_auth_test.go:360-370, internal/server/san_cert_manager.go:620-630
Request Header Security
The proxy provides fine-grained control over request and response headers to mitigate information leakage and enforce security policies.
- Header Removal: Operators can strip headers like
Serveror internal application headers before they reach the client using--remove-response-header. - Authorization Stripping: For services protected by proxy-level Basic Auth, the proxy automatically strips the
Authorizationheader before forwarding the request to the target to prevent credential leakage to the backend. - SSRF Protection: Internal probes (like TLS on-demand checks) are restricted from following redirects to prevent Server-Side Request Forgery.
Sources: internal/server/basic_auth_test.go:275-290, internal/server/dynamic_domains_test.go:270-290, ROADMAP.md:65-75
Security auditing in kamal-proxy is a multi-layered approach that prioritizes the protection of credentials, the resilience of the ACME provisioning system, and the strict isolation of internal traffic from external security constraints. By enforcing hashing at the edge (CLI) and strict filtering at the entry point (Proxy), the system maintains a robust security posture for all upstream services.