Skip to content

feat: add default NetworkPolicies for RHDH operator operands [RHIDP-16475] - #3394

Draft
rm3l wants to merge 9 commits into
redhat-developer:mainfrom
rm3l:RHIDP-16475--implement-base-networkpolicies-for-rhdh-operator-operands
Draft

feat: add default NetworkPolicies for RHDH operator operands [RHIDP-16475]#3394
rm3l wants to merge 9 commits into
redhat-developer:mainfrom
rm3l:RHIDP-16475--implement-base-networkpolicies-for-rhdh-operator-operands

Conversation

@rm3l

@rm3l rm3l commented Aug 24, 2026

Copy link
Copy Markdown
Member

Description

Add default NetworkPolicies for all RHDH Operator operands (backend and PostgreSQL pods), enforcing least-privilege pod communication by default per the NetworkPolicies ADR.

Backend pods get 6 always-on policies:

  • default-deny (ingress + egress)
  • DNS egress (53, 5353 UDP+TCP)
  • HTTPS + K8s API egress (443, 6443 TCP)
  • PostgreSQL egress (5432 TCP, podSelector-scoped to the DB)
  • metrics ingress (9464 TCP from openshift-monitoring)
  • router ingress (7007 TCP; platform-aware: uses OCP-specific policy-group.network.openshift.io/ingress label on OpenShift, empty namespaceSelector on vanilla Kubernetes)

PostgreSQL pods get 3 policies (only when local DB is enabled):

  • default-deny (ingress + egress)
  • DNS egress
  • backend ingress (5432 TCP, podSelector-scoped to the backend)

Orchestrator flavour adds 4 namespace-wide policies for SonataFlow components, moved from plugin-deps/sonataflow.yaml to flavours/orchestrator/networkpolicy.yaml so they participate in the standard flavour merge mechanism. These use podSelector: {} and are flagged with a TODO for future tightening to SonataFlow-specific labels.

All policies are label-scoped to the specific RHDH instance (rhdh.redhat.com/app: backstage-<cr-name> for backend, rhdh.redhat.com/app: backstage-psql-<cr-name> for PostgreSQL). Users can extend with additive NetworkPolicy resources in the same namespace.

Which issue(s) does this PR fix or relate to

PR acceptance criteria

  • Tests
  • Documentation

How to test changes / Special notes to the reviewer

  1. Deploy the operator from this branch to an OCP cluster
  2. Create a regular Backstage CR; verify 9 NetworkPolicies are created (6 backend + 3 DB)
  3. Create an Orchestrator-flavoured Backstage CR; verify 13 NetworkPolicies are created (6 base + 4 orchestrator + 3 DB)
  4. Verify RHDH is reachable via Route
  5. Verify metrics scraping works
  6. Verify DB connectivity works
  7. On a non-OCP cluster, verify the router ingress policy uses empty namespaceSelector instead of the OCP-specific label
  8. Verify that deleting the Backstage CR cleans up all NetworkPolicies (owner references)
  9. Create a Backstage CR with enableLocalDb: false; verify no DB NetworkPolicies are created

rm3l added 4 commits August 24, 2026 10:40
…6475]

Ship default-deny with selective-allow NetworkPolicies for both backend
and database pods. Backend policies (always-on) cover DNS egress,
HTTPS egress, PostgreSQL egress, metrics ingress, and router ingress.
Database policies (conditional on local DB) cover DNS egress and
backend ingress. On OpenShift, the router ingress policy uses the
policy-group.network.openshift.io/ingress namespace selector; on
vanilla Kubernetes it allows from any namespace.

Assisted-by: Claude
The networking.k8s.io/networkpolicies permission is now granted via the
main manager-role ClusterRole (generated from the kubebuilder RBAC
marker in backstage_controller.go). The separate grant in the
sonataflow plugin RBAC is redundant.

Assisted-by: Claude
Move the 4 namespace-wide orchestrator NetworkPolicies from
plugin-deps/sonataflow.yaml to the orchestrator flavour at
default-config/flavours/orchestrator/networkpolicy.yaml. This lets
them participate in the standard flavour merge mechanism.

Guard setMetaInfo so it only fills the rhdh.redhat.com/app podSelector
label when the placeholder key already exists; policies with
podSelector: {} (namespace-wide) keep their original scope.

Assisted-by: Claude
The orchestrator flavour NPs use podSelector: {} (namespace-wide),
which weakens per-component ingress isolation for RHDH backend and
DB pods in the same namespace. Add a TODO to review and scope them
to SonataFlow-specific labels.

Assisted-by: Claude
@rm3l

rm3l commented Aug 24, 2026

Copy link
Copy Markdown
Member Author

/build-images

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.82353% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 65.18%. Comparing base (1d3a9b5) to head (c58f6ba).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
pkg/model/networkpolicy.go 98.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3394      +/-   ##
==========================================
+ Coverage   63.97%   65.18%   +1.20%     
==========================================
  Files          38       40       +2     
  Lines        2365     2450      +85     
==========================================
+ Hits         1513     1597      +84     
- Misses        702      703       +1     
  Partials      150      150              
Flag Coverage Δ
nightly ?
unittests 65.18% <98.82%> (+1.20%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
internal/controller/backstage_controller.go 0.00% <ø> (ø)
pkg/model/db-networkpolicy.go 100.00% <100.00%> (ø)
pkg/model/runtime.go 78.88% <ø> (ø)
pkg/model/networkpolicy.go 98.00% <98.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown
Contributor

Image build failed

See workflow run for details: https://github.com/redhat-developer/rhdh-operator/actions/runs/32708255907

Triggered by @rm3l

rm3l added 4 commits August 24, 2026 11:18
The backstage.io profile used in CI does not ship networkpolicy.yaml or
db-networkpolicy.yaml manifests. Guard the NP count assertions behind
os.Stat checks so the test passes for any profile.

Assisted-by: Claude
The rhdh profile ships NP manifests, so the "create default rhdh" test
should verify that backend and DB NetworkPolicies are created.

Assisted-by: Claude
NetworkPolicy assertions are now in the rhdh-profile test, which always
has the NP manifests available. The generic test runs under the
backstage.io profile, which does not ship NP config.

Assisted-by: Claude
…ent-base-networkpolicies-for-rhdh-operator-operands
@rm3l

rm3l commented Aug 24, 2026

Copy link
Copy Markdown
Member Author

/build-images

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

PR images built successfully!

Images are available for testing:

  1. Operator: quay.io/rhdh-community/operator:2.0.0-pr-3394-c58f6ba
  2. Bundle: quay.io/rhdh-community/operator-bundle:2.0.0-pr-3394-c58f6ba
  3. Catalog: quay.io/rhdh-community/operator-catalog:2.0.0-pr-3394-c58f6ba

Also available with PR number tag:

  • quay.io/rhdh-community/operator:2.0.0-pr-3394
  • quay.io/rhdh-community/operator-bundle:2.0.0-pr-3394
  • quay.io/rhdh-community/operator-catalog:2.0.0-pr-3394

Triggered by @rm3l

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant