Skip to content

fix(workspaces): exempt private peers from basic auth - #7

Merged
pcfreak30 merged 2 commits into
developfrom
fix/external-auth-private-peer-bypass
Sep 20, 2026
Merged

pcfreak30 merged 2 commits into
developfrom
fix/external-auth-private-peer-bypass

Conversation

@pcfreak30

@pcfreak30 pcfreak30 commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

Adds the RFC 1918 and ULA private ranges to the Caddy @external bypass so workspace Basic Auth applies only to public-address peers, matching the protect-from-the-internet threat model.

A request hairpinned through the published port from inside the deployment's Docker network arrives with the bridge gateway as its TCP peer (remote_ip 172.18.0.1) and previously got 401; exports that probe the workspace's public URL anonymously (Cast's export probe and capture) now reach the site without credentials. The bypass still keys on the real TCP peer via remote_ip, never on spoofable forwarding headers. Matcher verified with caddy validate/caddy adapt (2.11.4) to compile to a single not remote_ip matcher with all ranges.


fix(workspaces): exempt private peers from basic auth

Summary

This PR widens the HTTP Basic Auth bypass for the PHP-Caddy workspace image so that not only loopback traffic (127.0.0.1, ::1) but also private-network traffic (RFC 1918 / ULA ranges) is exempt from authentication.

What changed

  • Caddyfile auth exemption (images/php-caddy/Caddyfile): the existing loopback-only bypass was extended to also cover private address ranges:
    • 10.0.0.0/8
    • 172.16.0.0/12
    • 192.168.0.0/16
    • fc00::/7
  • Basic Auth remains enforced on all requests coming from external/public-address peers.
  • The bypass still keys on Caddy's remote_ip matcher — the real TCP peer — and does not trust spoofable forwarding headers.
  • Documentation (AGENTS.md, README.md, images/php-caddy/README.md) was updated to reflect the new "external vs. private-network" auth model and the rationale for the broader bypass.

Purpose

The workspace often receives in-deployment traffic that arrives hairpinned through the published port with a private-network peer IP (for example, a service inside the Docker network calling the workspace's public URL via wp_remote_get, such as Cast's anonymous export probe). Previously these requests were treated as "non-loopback" and required Basic Auth credentials, even though they originate from the deployment's own network.

The intent is to keep the workspace protected from the public internet while allowing internal/private-network consumers to reach it without credentials. The comment in the Caddyfile clarifies the threat model: TLS and public ingress already terminate on a private-network peer (the Coolify proxy), so the auth boundary is "protect from the internet," not "protect from the deployment's own network."

Risk note

One critical review finding was raised: widening the bypass to the entire RFC1918/ULA private space means any LAN/VPC host that can reach the published port will bypass Basic Auth, not just the deployment's own bridge network. This is an intentional trade-off per the documented threat model, but it should be acknowledged when merging.

- hairpinned in-network requests (bridge gateway peer) hit 401
- widen @external from loopback to RFC1918/ULA private ranges
- bypass still keys on real TCP peer via remote_ip only
- align image README, repo README and AGENTS auth contract docs
@kody-ai

This comment has been minimized.

# auth setup step; missing/invalid WORKSPACE_AUTH_* fails the container
# at start, so this block is always populated when Caddy runs.
@external not remote_ip 127.0.0.1 ::1
@external not remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 fc00::/7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Security critical

The @external matcher exempts the entire RFC1918/ULA address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7) from HTTP Basic Auth, allowing any co-located container or LAN/VPC host that can reach the published port to access the full WordPress backend without credentials — a boundary far broader than the stated need. Scope the auth bypass to the actual bridge/proxy CIDR via a build/deploy-time configurable env value pinned to the narrow bridge-gateway CIDR, so only in-deployment peers bypass auth while external hosts still require credentials.

# scope to the deployment's actual bridge/proxy CIDR (injected via env) instead of all RFC1918/ULA
@external not remote_ip 127.0.0.1 ::1 {$WORKSPACE_EXEMPT_CIDRS}
Prompt for LLM

File images/php-caddy/Caddyfile:

Line 65:

The @external matcher exempts the entire RFC1918/ULA address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7) from HTTP Basic Auth, allowing any co-located container or LAN/VPC host that can reach the published port to access the full WordPress backend without credentials — a boundary far broader than the stated need. Scope the auth bypass to the actual bridge/proxy CIDR via a build/deploy-time configurable env value pinned to the narrow bridge-gateway CIDR, so only in-deployment peers bypass auth while external hosts still require credentials.

Suggested Code:

# scope to the deployment's actual bridge/proxy CIDR (injected via env) instead of all RFC1918/ULA
@external not remote_ip 127.0.0.1 ::1 {$WORKSPACE_EXEMPT_CIDRS}

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

@kody-ai kody-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- host-published-peer requests are private-range now exempt, so the
  old external-401 assertions passed spuriously
- attach web to a TEST-NET-1 (192.0.2.0/24) bridge and run the
  public-peer 401/401/200 cases from a container on that network
- add private-network peer -> 200 no-credentials case
- keep spoofed-XFF assertion, run from the public peer
@kody-ai

kody-ai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug ✅
Performance ✅
Security ✅
Business Logic ✅

Access your configuration settings here.

​

@pcfreak30
pcfreak30 merged commit f8af366 into develop Sep 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant