Skip to content

Publish Helm chart to GHCR - #16276

Open
Pavan19047 wants to merge 3 commits into
DefectDojo:devfrom
Pavan19047:feature/helm-oci-registry
Open

Pavan19047 wants to merge 3 commits into
DefectDojo:devfrom
Pavan19047:feature/helm-oci-registry

Conversation

@Pavan19047

Copy link
Copy Markdown

Publishes each Helm release to GHCR as an OCI artifact and adds the install command to the chart README.

Closes #16019.

Tests: not run.

Copilot AI balanced review requested due to automatic review settings October 9, 2026 07:44

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added the helm label Oct 9, 2026

@Maffooch Maffooch 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.

Adversarial review: Publish Helm chart to GHCR

Verdict: request-changes
Reviewed at: aa0c4e4 Profile: code-change (release workflows + Helm README)
Repo rules followed: origin/dev .claude/skills/review-pr/SKILL.md and .claude/skills/defectdojo-dev/SKILL.md (Helm/infra checklist), plus the generic review-pr skill

Attempts to break it

  1. Permission scope of the new top-level block in release-2-tag-docker-push.yml:17-19. gh api repos/DefectDojo/django-DefectDojo/actions/permissions/workflow returns default_workflow_permissions: write, so on base every job already has packages: write. The new block adds nothing the helm job needs, but it applies packages: write to every job and called workflow (tag, docker publish, digests, tag-as-latest, release-drafter, fetch-oas) and sets every other scope to none for all of them. zizmor (base vs PR diff) reports 2 new high-confidence excessive-permissions errors at lines 18 and 19. Blocker.
  2. Reusable-workflow permission ceiling. Release path: caller grants contents: write, packages: write, callee job (release-x-manual-helm-chart.yml:43-45) asks for the same, so it starts. Nightly path (release-nightly-dev.yml -> release-x-nightly.yml:75-82 -> helm chart) has no permissions block, so the repo default (write) covers the callee request. No break.
  3. Untrusted input in run:. The new step (release-x-manual-helm-chart.yml:82-87) passes the token through env and --password-stdin, never on the command line. ${{ env.chart_version }} is interpolated into the script; it comes from Chart.yaml at a maintainer-created tag, so not attacker-controlled, but zizmor flags it (help level) and "$chart_version" is the safe form. No break, nit.
  4. Third-party actions. No new uses: added. The helm CLI comes from the existing SHA-pinned azure/setup-helm@9bc31f4e... (v5.0.1). No break.
  5. OCI push target, hands-on. Ran the workflow's package step on the PR head (helm dependency update, helm package, same ls | cut | sed extraction) giving chart_version=1.9.56-dev, then helm push ./build/defectdojo-1.9.56-dev.tgz oci://localhost:35276/defectdojo --plain-http against a throwaway registry:2. Result: Pushed: localhost:35276/defectdojo/defectdojo:1.9.56-dev. So the real ref will be ghcr.io/defectdojo/defectdojo:<version>, matching the README command. No break.
  6. Unversioned install from the README. With only a -dev tag in the registry, helm show chart oci://.../defectdojo/defectdojo fails with "could not locate a version matching provided version string". After pushing 1.9.55 as well, unversioned resolves 1.9.55 and --devel resolves 1.9.56-dev. So the README command fails until the first stable release is pushed (and the package is public). Also, the nightly job will push x.y.z-dev charts to the same public path every day. Follow-up / maintainer decision.
  7. helm-docs fail-on-diff. Ran helm-docs 1.14.2 on a copy of helm/defectdojo from the PR head: generated README.md is identical to the committed one. No break.
  8. artifacthub.io/changes annotation check (test-helm-chart.yml:78-102). ct list-changed --config ct.yaml --target-branch dev lists helm/defectdojo, so the check runs. The PR does not touch Chart.yaml. The check would pass today only because the head is stale: the PR head annotation still holds a valkey entry from its merge base while origin/dev has "". After an update-branch the check fails. Precedent #16178 (same kind of README change) updated the annotation. Blocker per the repo Helm checklist.
  9. Release ordering. The GHCR push now runs before "Create release" and "Update Helm repository index" with no failure isolation. If the first push fails (package not linked to the repo, org package policy, an existing defectdojo package owned elsewhere), the GitHub release asset, the helm-charts index update, and release-drafter (which needs this job) are all skipped. The nightly will surface it first, but it will also kill the nightly prerelease and index update. Not a blocker; recommend moving the push after the index update or continue-on-error: true.
  10. actionlint on both workflows. Only SC2012/SC2086 (info) on the pre-existing package step (line 77); base reports the same 2. No break.

Blocking

  • .github/workflows/release-2-tag-docker-push.yml:17-19 Drop the workflow-level permissions block. It is not needed (repo default is write) and it widens packages: write to every job while zeroing all other scopes for the whole release chain, including release-drafter (reads PR labels; I did not verify whether pull-requests: none breaks it on a public repo). If explicit permissions are wanted, put contents: write + packages: write on the release-helm-chart job only, and contents: write on tag.
  • helm/defectdojo/Chart.yaml Add an artifacthub.io/changes entry for the chart change (README is packaged into the chart; see #16178). The CI check passes now only because the branch is behind dev.

Nice to have

  • release-x-manual-helm-chart.yml:82-87 Make the GHCR push non-fatal or move it after the index update, so a GHCR setup problem cannot block a release.
  • release-x-manual-helm-chart.yml:87 Use "./build/defectdojo-${chart_version}.tgz" instead of ${{ env.chart_version }}.
  • helm/defectdojo/README.md.gotmpl:20-28 (and README.md) The new paragraph sits between "published to the helm-charts branch" and "To use it, you can add our repo", so "it" now reads as the OCI artifact. "remain available for existing installations" frames charts.defectdojo.com as legacy, which conflicts with #16178, and the OCI path bypasses that endpoint. Maintainer decision on positioning.
  • Use a plain or bash fence instead of zsh to match the rest of the README.
  • docs/content/get_started/open_source/installation.md was updated alongside the README in #16178; this PR does not mention OCI there.
  • No milestone set (AGENTS.md: every new PR gets the earliest open future milestone).

Verified hands-on

  • Chart packaging, version extraction, and helm push to a local OCI registry produce <registry>/defectdojo/defectdojo:<version> (Helm v4.1.3).
  • Unversioned OCI install resolves only stable versions; fails when only -dev tags exist.
  • helm-docs regeneration matches the committed README.
  • ct list-changed flags the chart; annotation comparison done with yq against origin/dev.
  • actionlint and zizmor (offline), base vs PR.

Checked only statically

  • GitHub Actions permission inheritance for reusable workflows on both the release and nightly paths.
  • Token handling in the new step (env + --password-stdin, no echo).

Still needs verification

  • CI has not run: every pull_request workflow for this head is action_required (fork, needs maintainer approval). Required checks ruff-linting and Unit Tests Complete are missing.
  • GHCR side, which needs org admin access: whether a defectdojo package already exists in the org (anonymous token request returned 403, inconclusive), whether Actions in this repo may create or write it, and its visibility. A new package is likely private until an admin makes it public (unverified), in which case the README command fails for users.
  • Whether release-drafter works with pull-requests: none on this public repo.

@dryrunsecurity

dryrunsecurity Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

DryRun Security

This pull request contains multiple low-severity findings where the author 'Pavan19047' modified various sensitive codepaths in the 'dojo' directory without being on the allowed authors list. These issues are non-blocking and do not prevent the merge.

Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/api_v2/exception_handler.py (drs_d4c3f06a)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/api_v2/exception_handler.py' matches configured sensitive codepath pattern 'dojo/api_v2/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/apps.py (drs_f2fd01df)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/apps.py' matches configured sensitive codepath pattern 'dojo/apps.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/authorization/api_permissions.py (drs_9e6410e1)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/authorization/api_permissions.py' matches configured sensitive codepath pattern 'dojo/authorization/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/db_migrations/0299_finding_test_numsev_index.py (drs_74e282ca)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/db_migrations/0299_finding_test_numsev_index.py' matches configured sensitive codepath pattern 'dojo/db_migrations/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/db_migrations/0300_finding_upper_title_index.py (drs_1c9607b8)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/db_migrations/0300_finding_upper_title_index.py' matches configured sensitive codepath pattern 'dojo/db_migrations/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/endpoint/utils.py (drs_21f4a2d0)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/endpoint/utils.py' matches configured sensitive codepath pattern 'dojo/endpoint/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/finding/deduplication.py (drs_51a0ea29)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/finding/deduplication.py' matches configured sensitive codepath pattern 'dojo/finding/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/finding/helper.py (drs_a74a02c4)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/finding/helper.py' matches configured sensitive codepath pattern 'dojo/finding/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/finding/models.py (drs_18eda903)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/finding/models.py' matches configured sensitive codepath pattern 'dojo/finding/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/importers/base_importer.py (drs_15b33e69)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/importers/base_importer.py' matches configured sensitive codepath pattern 'dojo/importers/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/importers/default_importer.py (drs_78ba77e4)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/importers/default_importer.py' matches configured sensitive codepath pattern 'dojo/importers/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/importers/default_reimporter.py (drs_a483662c)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/importers/default_reimporter.py' matches configured sensitive codepath pattern 'dojo/importers/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/importers/import_lock.py (drs_6733e671)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/importers/import_lock.py' matches configured sensitive codepath pattern 'dojo/importers/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/importers/location_manager.py (drs_028bcb5d)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/importers/location_manager.py' matches configured sensitive codepath pattern 'dojo/importers/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/tasks.py (drs_52a1c8c5)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/tasks.py' matches configured sensitive codepath pattern 'dojo/tasks.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/templates/dojo/filter_js_snippet.html (drs_a747fef7)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/templates/dojo/filter_js_snippet.html' matches configured sensitive codepath pattern 'dojo/templates/**/*.html' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/templates/dojo/findings_list_snippet.html (drs_08690333)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/templates/dojo/findings_list_snippet.html' matches configured sensitive codepath pattern 'dojo/templates/**/*.html' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/templates/dojo/view_test.html (drs_ba5aab48)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/templates/dojo/view_test.html' matches configured sensitive codepath pattern 'dojo/templates/**/*.html' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.
Configured Sensitive Codepath Modified by Non-Allowed Author in dojo/user/authentication.py (drs_ca2fb4c0)
Vulnerability Configured Sensitive Codepath Modified by Non-Allowed Author
Description File 'dojo/user/authentication.py' matches configured sensitive codepath pattern 'dojo/user/*.py' and was modified by 'Pavan19047' (commit f20483c) who is not in the allowed authors list.

Comment to provide feedback on these findings.

Report false positive: @dryrunsecurity fp [FINDING ID] [FEEDBACK]
Report low-impact: @dryrunsecurity nit [FINDING ID] [FEEDBACK]

Example: @dryrunsecurity fp drs_90eda195 This code is not user-facing

All finding details can be found in the DryRun Security Dashboard.

Drop the workflow-wide token permissions, publish the chart after the index update without failing the job, and record the README change for Artifact Hub.
@github-actions github-actions Bot added the docs label Oct 19, 2026

This branch has not been deployed

No deployments
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.

3 participants