Security

Who can reach what

Every way into this estate from outside it, what guards each one, and the three places where that guard is deliberately switched off.

Scope HQ production and the Cloudflare edgeVerified 8 October 2026Owner Infrastructure

1There are exactly two ways in

Nothing in the HQ cluster is reachable from the internet directly. There is no external load balancer and no port forwarding; 10.20.100.237 is an internal address. Traffic arrives by one of two paths, and which one a hostname uses determines what protects it.

internal visitor on the LAN or VPN → internal DNS → 10.20.100.237 (Traefik) → the application public visitor on the internet → Cloudflare edge → Access policy → tunnel → Traefik → the application

The public path is an outbound connection established by cloudflared from inside the cluster. Nothing listens for inbound connections at the perimeter, which is why there is no firewall rule to review for these services — the control is the Access policy, not a packet filter.

The internal path bypasses Access entirely

A visitor on the LAN reaches Traefik directly and never passes a Cloudflare Access policy. For a hostname that resolves internally to 10.20.100.237, Access protects it from the internet and from nobody else. Whether that is acceptable depends on the application, but it should be a decision rather than a surprise — and it means an application’s own authentication is what actually protects it from staff.


2Cloudflare Access applications

As listed in Zero Trust → Access → Applications on 8 October 2026. All are self-hosted applications.

ApplicationDestinationPolicies
DC BAR DOCSdocs.dcbar.orgAllow_Access + 1
ArgoCDprod-argocd.dcbar.orgAllow_Access + 1
prod-argocdprod-argocd.dcbar.org/api/webhookGitHub Webhook Bypass
Portainerprod-portainer.dcbar.orgAllow_Access + 1
Keycloaklogin.dcbar.org/realms/master/* + 1 domainAllow_Access + 4
nominationsnominations.dcbar.org/adminAllow_Access + 1
MEP EMSmep.dcbar.orgAllow_Access + 1
CMS Accesscms.dcbar.orgAllow IP Ranges to Bypass Auth + 1
CMS Staging Accesscmsstg.dcbar.orgAllow IP Ranges To Bypass Auth + 1
hello-world-tim.dcbar.orghello-world-tim.dcbar.orgAllow_Access + 1

Note the shape of the nominations entry: the policy covers /admin only. The rest of the nomination portal is public, which is correct for a portal members use — but it means path matters, and an application that later serves something sensitive outside /admin gains no protection from this entry.

An application existing is not the same as it being restricted

Every row above is an application with a policy attached, but the policy names are not the policy contents. Allow_Access could select an Entra group, an email domain, or everyone. Open each one and confirm what it actually matches before treating this table as evidence of anything.


3The three deliberate holes

Each of these is there for a reason. Each is also a place where the usual control does not apply, so each needs to be understood rather than assumed.

The Argo CD webhook

prod-argocd.dcbar.org/api/webhook has a GitHub Webhook Bypass policy, which is necessary — GitHub cannot complete an Access login. The question is what the bypass is scoped to. Restricted to GitHub’s published IP ranges it is reasonable; open to everyone it is an unauthenticated endpoint that triggers syncs, reachable by anyone who knows the URL.

The CMS IP range bypasses

cms.dcbar.org and cmsstg.dcbar.org both allow specified IP ranges to skip authentication. IP-based rules age badly: the ranges were correct when written, and nothing re-checks them. A range that has been reassigned becomes someone else’s access; a range that has changed becomes a lockout. Neither failure announces itself.

The office network reads docs without authenticating

docs.dcbar.org carries a second policy that bypasses authentication for specified IP ranges, including the networks the estate itself sits on. A request from prod-k8s-master-01 is answered with the page and no challenge at all.

That is reasonable for topology documentation and convenient for anyone diagnosing something at three in the morning. It is worth re-reading as a decision now that this site also carries a credential inventory and a map of every access control in the estate: on the office network, those are readable by anyone who reaches the hostname, authenticated or not.

It also makes the site hard to test honestly

A curl from inside the bypass range returns 200 whether or not Access is working, so it cannot distinguish a working policy from an absent one. Test from outside — a phone on mobile data — or the result tells you nothing. This is the same trap as the split-horizon DNS check: the convenient vantage point is the one that cannot see the thing being tested.

support.dcbar.org is public by design

Published through the HQ tunnel on 6 October with no Access application. That was deliberate — it is a public support portal — but it means the application’s own authentication is the only gate, and it is worth re-stating whenever its scope changes.


4What the applications trust

Access tells you who a visitor is. The proxy chain tells an application where they came from, and getting that wrong defeats rate limiting and corrupts audit trails.

Traefik extends the forwarded chain only for traffic arriving from the pod network, and only on the web entrypoint:

--entryPoints.web.forwardedHeaders.trustedIPs=10.244.0.0/16

10.244.0.0/16 contains the cloudflared pods. websecure trusts nothing, which is correct for traffic arriving directly on the LAN — a visitor there cannot forge their own address.

Via the tunnelDirect on the LAN
Proxies ahead of the application42
CF-Connecting-IPPresentAbsent
Who sets the client addressCloudflare edgeTraefik
A hostname can have two different chain lengths at once

support.dcbar.org is reached over the tunnel from the internet and directly from the LAN. An application trusting a fixed hop count will mis-attribute one of those paths: too high and a visitor can forge their own apparent address by sending the header themselves, which defeats sign-in rate limiting and writes attacker-chosen addresses into the audit trail. Trusting by CIDR rather than by depth is the durable answer. Where a count must be used, err low — too low merely makes visitors share a rate-limit bucket.


5Open questions

Recorded here because they are unresolved, not because they are unimportant.