Skip to content

DUNDER-252: add SSRF_ALLOWED_IP_RANGES as a helm chart value - #93

Merged
jasonopslevel merged 2 commits into
mainfrom
jason/dunder-252-ssrf
Sep 10, 2026
Merged

jasonopslevel merged 2 commits into
mainfrom
jason/dunder-252-ssrf

Conversation

@jasonopslevel

Copy link
Copy Markdown
Contributor

What

Adds opslevel.ssrfAllowedIpRanges to the self-hosted chart, rendered into the opslevel configmap as SSRF_ALLOWED_IP_RANGES.

Linear: DUNDER-252

Why

As of 2026.8.13 the app blocks server-side requests to private, loopback, link-local and cloud-metadata addresses. Self-hosted operators whose custom actions or custom integrations poll an internal endpoint have to allow-list it, and until now the only way to set the var was to patch the configmap by hand.

Contract

Verified against app/lib/http_clients/ssrf_safe.rb in the app repo rather than assumed:

  • parse_allowed_ip_ranges splits on ,, strips whitespace, and runs each entry through IPAddr.new — so the value takes a YAML list and joins it with commas. Bare IPs and CIDRs both work; invalid entries are logged and skipped rather than failing boot.
  • Default is [], rendering the empty string the app already treats as "allow nothing" — no behavior change when unset.
opslevel:
  ssrfAllowedIpRanges:
    - 10.0.0.0/8
    - 172.16.5.4

renders SSRF_ALLOWED_IP_RANGES: '10.0.0.0/8,172.16.5.4'.

Notes for review

  • The value sits at the opslevel level rather than under web, since workers and the scheduler make these outbound requests too. All six workloads (web, 4 workers, scheduler) consume it via envFrom and carry a checksum/config annotation, so an upgrade that changes it rolls them.
  • No chart tests, which the ticket's review comment asked for. This repo has no test convention — no templates/tests/, no helm-unittest dep, and the Taskfile only runs helm lint + replicated release lint. Adding tests means introducing a framework, which felt like a bigger call than this ticket; happy to wire up helm-unittest separately if we want it.
  • Unrelated: MR !20129 in the app repo shares this ticket's title but only fixes a missing time: field on a changie entry. There's no app-side work pending — the SSRF feature already shipped.

Testing

helm lint passes. Rendered with helm template both ways: '' by default, '10.0.0.0/8,172.16.5.4' when set.

Self-hosted operators whose custom actions or custom integrations poll an
internal endpoint need to allow-list it -- the app blocks private, loopback,
link-local and cloud-metadata addresses by default. Until now the only way to
set SSRF_ALLOWED_IP_RANGES was to patch the configmap by hand.

The app parses the var as a comma-separated list of IPs/CIDRs
(HttpClients::SsrfSafe.parse_allowed_ip_ranges), so the value takes a YAML list
and joins it. It defaults to [], which renders the empty string the app already
treats as "allow nothing" -- no behavior change when unset.

The value sits at the opslevel level rather than under web, since the workers
and scheduler make these outbound requests too; all six workloads pick it up
via envFrom and carry a checksum/config annotation, so an upgrade rolls them.
A stale replicated-1.2.0.tgz from a manual `helm pull` has been sitting
untracked in the repo root since March 2025, showing up in every `git status`.

Anchored as /*.tgz rather than *.tgz on purpose: the subchart tarballs under
charts/opslevel/charts/ are vendored and tracked, and a blanket pattern would
hide future dependency bumps (which land under a new filename) from git status.

Also ignores /downloads, which `task pull-self-hosted` untars into.
@jasonopslevel
jasonopslevel merged commit 4881a91 into main Sep 10, 2026
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.

2 participants