Skip to content

Harden Helm deployment defaults - #589

Merged
delete-cloud merged 3 commits into
mainfrom
feat/helm-deploy-hardening
Jun 13, 2026
Merged

delete-cloud merged 3 commits into
mainfrom
feat/helm-deploy-hardening

Conversation

@delete-cloud

@delete-cloud delete-cloud commented Jun 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add a dedicated unprivileged ServiceAccount and disable ServiceAccount token mounting/service links in the agent pod
  • add default NetworkPolicy coverage with DNS plus public HTTPS egress and private-range exclusions
  • add optional Gateway API HTTPRoute rendering with explicit gateway and hostname requirements
  • document shared/public-cluster deployment prerequisites in the Phase 2 k8s runbook

Tests

  • uv run pytest tests/deploy/test_helm_chart.py -v
  • helm template coding-agent ./helm
  • helm lint ./helm
  • uv run ruff check tests/deploy/test_helm_chart.py
  • uv run ruff format --check tests/deploy/test_helm_chart.py

Summary by CodeRabbit

  • Documentation

    • Updated Kubernetes deployment runbook with comprehensive guidance on ServiceAccount configuration, NetworkPolicy, and Gateway API setup
  • New Features

    • Added Kubernetes NetworkPolicy support with configurable ingress/egress rules and presets for DNS and HTTPS connectivity
    • Added Gateway API HTTPRoute support for public route management
    • Enhanced ServiceAccount configuration with token mounting and RBAC controls

@coderabbitai

coderabbitai Bot commented Jun 13, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@delete-cloud, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 33 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8747ba07-f39a-4c8b-af93-ffdde5e5b6c2

📥 Commits

Reviewing files that changed from the base of the PR and between c1388e6 and f4511cb.

📒 Files selected for processing (4)
  • coding-agent/docs/deployment/phase2-k8s.md
  • coding-agent/helm/templates/networkpolicy.yaml
  • coding-agent/helm/values.yaml
  • coding-agent/tests/deploy/test_helm_chart.py
📝 Walkthrough

Walkthrough

This PR adds comprehensive Kubernetes security and networking resources to the Helm chart, including ServiceAccount isolation (no RBAC, no token mounting), NetworkPolicy with configurable ingress/egress rules (DNS, public HTTPS with private range exclusions), and optional HTTPRoute for Gateway API routing. Pod spec now explicitly sets these security fields. Tests validate all defaults and customization paths, and the operator runbook provides deployment guidance with Helm examples.

Changes

Kubernetes Security & Networking

Layer / File(s) Summary
ServiceAccount Configuration
coding-agent/helm/templates/_helpers.tpl, coding-agent/helm/templates/serviceaccount.yaml, coding-agent/helm/values.yaml (lines 33–40)
Adds coding-agent.serviceAccountName helper that selects between chart fullname or "default" based on creation flag. ServiceAccount template conditionally renders with token mounting disabled, name, and labels.
NetworkPolicy Configuration
coding-agent/helm/templates/networkpolicy.yaml, coding-agent/helm/values.yaml (lines 41–72)
Introduces NetworkPolicy template with conditional ingress (port + optional selectors + extra rules) and egress (DNS rules, public HTTPS to 0.0.0.0/0 excluding private ranges, extra rules). Values configure defaults and allow operator customization.
HTTPRoute Gateway API Configuration
coding-agent/helm/templates/httproute.yaml, coding-agent/helm/values.yaml (lines 73–78)
Adds HTTPRoute template with enabled-by-default false, validates required parentRefs and hostnames, renders PathPrefix routing rule to service backend. Values allow disabling or enabling with explicit gateway/hostname config.
Pod Spec Security Fields
coding-agent/helm/templates/deployment.yaml
Deployment pod spec now sets serviceAccountName, automountServiceAccountToken, and enableServiceLinks from chart values, integrating the ServiceAccount and networking configurations.
Kubernetes Security & Routing Tests
coding-agent/tests/deploy/test_helm_chart.py (helpers at lines 65–72, runtime contract extension at lines 142–144, comprehensive suite at lines 161–349)
Test helpers locate rendered ServiceAccount and NetworkPolicy resources. Runtime contract test verifies pod spec uses service account name, disables token automounting, and disables service links. New test suite validates ServiceAccount defaults without RBAC, NetworkPolicy ingress/egress constraints and customization, HTTPRoute disabled-by-default with validation failures, and successful renders.
Deployment Runbook & Operator Guidance
coding-agent/docs/deployment/phase2-k8s.md
Documents chart behavior (dedicated ServiceAccount without RBAC, enableServiceLinks=false, default NetworkPolicy with allow/exclude ranges, optional HTTPRoute). Operator checklist covers CNI enforcement, resource limits on shared clusters, Gateway API setup. Example helm install/upgrade commands include --set-json for CORS, CPU/memory requests/limits, and optional flags for HTTPRoute parentRefs/hostnames and NetworkPolicy custom egress rules.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hopped through Kubernetes pods,
Secured them with NetworkPolicy codes,
Service accounts now safe from wild tokens,
HTTPRoute gateways await to be woken,
Security defaults, a well-fitted cloak! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "Harden Helm deployment defaults" directly and accurately summarizes the main change: adding security-focused defaults (unprivileged ServiceAccount, token mounting disabled, NetworkPolicy, HTTPRoute support) to the Helm deployment templates and values.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/helm-deploy-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
coding-agent/docs/deployment/phase2-k8s.md (1)

141-150: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't use the orbstack overlay in the cluster install example.

This still layers helm/values-orbstack-kimi.yaml into the shared/public-cluster runbook, which conflicts with the warning above that Orbstack values are local-dev only. A reader can copy this verbatim and inherit unsafe defaults into a real cluster. Please switch this example to a production-safe overlay or document every override it depends on.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-agent/docs/deployment/phase2-k8s.md` around lines 141 - 150, The helm
example uses the local-dev Orbstack overlay (helm/values-orbstack-kimi.yaml)
which is unsafe for cluster installs; change the command to reference a
production-safe values file (for example replace helm/values-orbstack-kimi.yaml
with a production overlay like helm/values-production.yaml or
helm/values-k8s.yaml) or remove the -f flag and instead explicitly set every
production-safe override shown (server.auth.enabled,
server.allowUnauthenticated, image.* and resource limits/requests); if you keep
an overlay, update or add documentation listing every override that overlay
provides so readers know what defaults it changes.
🧹 Nitpick comments (1)
coding-agent/helm/templates/networkpolicy.yaml (1)

46-55: 💤 Low value

Consider conditionally rendering the except field.

The except field in the ipBlock (lines 50-51) is always rendered even if the list is empty. While except: [] is valid YAML, it would be cleaner to conditionally include the field only when the list is non-empty:

♻️ Optional refactor for cleaner YAML
         - ipBlock:
             cidr: {{ .Values.networkPolicy.egress.publicHttps.cidr | quote }}
+            {{- if .Values.networkPolicy.egress.publicHttps.except }}
             except:
               {{- toYaml .Values.networkPolicy.egress.publicHttps.except | nindent 14 }}
+            {{- end }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-agent/helm/templates/networkpolicy.yaml` around lines 46 - 55, The
ipBlock's except field is rendered even when
.Values.networkPolicy.egress.publicHttps.except is empty; update the
networkpolicy.yaml template so the ipBlock includes the except: block only when
the list has items by wrapping the existing "except: {{- toYaml
.Values.networkPolicy.egress.publicHttps.except | nindent 14 }}" rendering in a
conditional that checks the list (e.g., using an if with
.Values.networkPolicy.egress.publicHttps.except or the len function) so empty
arrays are not emitted while keeping the rest of the ipBlock and ports logic
under the existing .Values.networkPolicy.egress.publicHttps.enabled check.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@coding-agent/helm/templates/networkpolicy.yaml`:
- Around line 24-27: The template currently uses "{{- with
.Values.networkPolicy.ingress.from }}" which treats empty slices as falsy and
omits the "from:" field, changing NetworkPolicy semantics; change the template
to preserve empty-array semantics by either (A) replacing the with with an
explicit length check like "{{- if gt (len .Values.networkPolicy.ingress.from) 0
}}" to only render a populated from: block, or (B) use an "if" that treats empty
slices as truthy (e.g., "{{- if .Values.networkPolicy.ingress.from }}" is not
safe) — recommended fix: replace the "{{- with
.Values.networkPolicy.ingress.from }}" block with "{{- if or (not
.Values.networkPolicy.ingress.from) (gt (len .Values.networkPolicy.ingress.from)
0) }}" then render "from:" and the toYaml content so that an explicit empty
array (from: []) is emitted when provided, while still allowing omission when
the value is unset or null; update the "from:" rendering around the toYaml call
accordingly.
- Around line 12-18: The template currently renders spec.policyTypes even when
both .Values.networkPolicy.ingress.enabled and
.Values.networkPolicy.egress.enabled are false, producing an empty policyTypes
list; update the template to avoid this by gating rendering: either wrap the
entire NetworkPolicy resource in an if that checks
(.Values.networkPolicy.ingress.enabled or .Values.networkPolicy.egress.enabled)
so the resource is omitted when neither is enabled, or at minimum wrap the
spec.policyTypes section with that same conditional so policyTypes is omitted
when both are false; reference the existing symbols
.Values.networkPolicy.enabled, .Values.networkPolicy.ingress.enabled,
.Values.networkPolicy.egress.enabled and the spec.policyTypes block to locate
where to add the conditional.

---

Outside diff comments:
In `@coding-agent/docs/deployment/phase2-k8s.md`:
- Around line 141-150: The helm example uses the local-dev Orbstack overlay
(helm/values-orbstack-kimi.yaml) which is unsafe for cluster installs; change
the command to reference a production-safe values file (for example replace
helm/values-orbstack-kimi.yaml with a production overlay like
helm/values-production.yaml or helm/values-k8s.yaml) or remove the -f flag and
instead explicitly set every production-safe override shown
(server.auth.enabled, server.allowUnauthenticated, image.* and resource
limits/requests); if you keep an overlay, update or add documentation listing
every override that overlay provides so readers know what defaults it changes.

---

Nitpick comments:
In `@coding-agent/helm/templates/networkpolicy.yaml`:
- Around line 46-55: The ipBlock's except field is rendered even when
.Values.networkPolicy.egress.publicHttps.except is empty; update the
networkpolicy.yaml template so the ipBlock includes the except: block only when
the list has items by wrapping the existing "except: {{- toYaml
.Values.networkPolicy.egress.publicHttps.except | nindent 14 }}" rendering in a
conditional that checks the list (e.g., using an if with
.Values.networkPolicy.egress.publicHttps.except or the len function) so empty
arrays are not emitted while keeping the rest of the ipBlock and ports logic
under the existing .Values.networkPolicy.egress.publicHttps.enabled check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ff32ec6-22b0-4d31-bb5d-3f1a868afd57

📥 Commits

Reviewing files that changed from the base of the PR and between f62dee2 and c1388e6.

📒 Files selected for processing (8)
  • coding-agent/docs/deployment/phase2-k8s.md
  • coding-agent/helm/templates/_helpers.tpl
  • coding-agent/helm/templates/deployment.yaml
  • coding-agent/helm/templates/httproute.yaml
  • coding-agent/helm/templates/networkpolicy.yaml
  • coding-agent/helm/templates/serviceaccount.yaml
  • coding-agent/helm/values.yaml
  • coding-agent/tests/deploy/test_helm_chart.py

@delete-cloud
delete-cloud merged commit 1494724 into main Jun 13, 2026
2 checks passed
@delete-cloud
delete-cloud deleted the feat/helm-deploy-hardening branch June 13, 2026 05:15
@coderabbitai coderabbitai Bot mentioned this pull request Jun 13, 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.

1 participant