{"id":16927721,"url":"https://github.com/dirien/signed-helm-chart","last_synced_at":"2026-03-18T22:56:09.214Z","repository":{"id":45377489,"uuid":"438962058","full_name":"dirien/signed-helm-chart","owner":"dirien","description":"PoC to create a signed oci helm chart","archived":false,"fork":false,"pushed_at":"2021-12-16T22:07:57.000Z","size":14,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-18T06:44:06.302Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Smarty","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dirien.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-16T11:16:40.000Z","updated_at":"2022-11-08T15:44:18.000Z","dependencies_parsed_at":"2022-09-02T01:40:50.215Z","dependency_job_id":null,"html_url":"https://github.com/dirien/signed-helm-chart","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fsigned-helm-chart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fsigned-helm-chart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fsigned-helm-chart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fsigned-helm-chart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dirien","download_url":"https://codeload.github.com/dirien/signed-helm-chart/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244728187,"owners_count":20500023,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T20:34:56.267Z","updated_at":"2026-01-03T23:40:52.446Z","avatar_url":"https://github.com/dirien.png","language":"Smarty","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PoC To Create A Keyless Signed OCI Helm Chart\n\n## Requirements\n\n- CR_PAT for the GitHub container registry\n\nSee [this guide](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry)\nfor more information on how to create a personal access token.\n\n## Task\n\nTask is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make.\n\nSince it’s written in Go, Task is just a single binary and has no other dependencies, which means you don’t need to mess\nwith any complicated install setups just to use a build tool.\n\nOnce installed, you just need to describe your build tasks using a simple YAML schema in a file called Taskfile.yml:\n\nOur Taskfile.yml file looks like this:\n\n```yaml\nversion: '3'\n\ntasks:\n  purge:\n    cmds:\n      - echo \"Purging...\"\n      - rm -rf dist\n\n  default:\n    deps:\n      - purge\n    cmds:\n      - mkdir dist\n      - echo $CR_PAT | helm registry login ghcr.io --username $OWNER --password-stdin\n      - helm package signed-helm-chart --destination dist\n      - helm push dist/signed-helm-chart-*.tgz oci://ghcr.io/dirien/ \u003e .digest\n      - cat .digest | awk -F \"[, ]+\" '/Digest/{print $NF}'\n      - cosign sign ghcr.io/dirien/signed-helm-chart@$(cat .digest | awk -F \"[, ]+\" '/Digest/{print $NF}')\n    env:\n      HELM_EXPERIMENTAL_OCI: 1\n      COSIGN_EXPERIMENTAL: \"true\"\n```\n\nAnd has a purge and default task inside.\n\n## Helm\n\nHelm 3 supports OCI for package distribution. Chart packages are able to be stored and shared across OCI-based\nregistries.\n\nEnabling OCI Support Currently OCI support is considered experimental.\n\nIn order to use the commands described below, please set `HELM_EXPERIMENTAL_OCI` in the environment:\n\n```\nexport HELM_EXPERIMENTAL_OCI=1\n```\n\nWe're going to use `helm package` to create a the chart package and with `helm push` to push it to the OCI registry. In\nthis case , we will use `ghcr.io` as the registry.\n\n## Cosign\n\nTo use `cosign` to sign keyless our OCI chart, we need to create set `COSIGN_EXPERIMENTAL` in the environment of\nour `Taskfile.yml` task `default` and of course have the `cosign` binary installed.\n\n## GitHub Action\n\nTo use keyless signing in GitHub Actions, we need do following steps:\n\n### Step 1: Enable OCI Support\n\nAdd permissions to add `id-token` to the `permissions` section.\n\n```yaml\npermissions:\n  id-token: write\n```\n\n### Step 2: Install Cosign\n\nJust add this GitHub Action to your workflow:\n\n```yaml\n- name: Install cosign\n  uses: sigstore/cosign-installer@v1.4.1\n  with:\n    cosign-release: 'v1.4.1'\n```\n\n### Step 3: Call the Taskfile\n\nTo build and sign our chart, we need to call the `Taskfile.yml` file in the GitHub Action. Just add this GitHub to your\nworkflow:\n\n```yaml\n- name: Build the helm chart and sign the oci image\n  run: task\n  env:\n    CR_PAT: ${{ secrets.CR_PAT }}\n    OWNER: ${{ github.repository_owner }}\n```\n\n## Result\n\nIf everything works, you should see the following output:\n\n```shell\nRun task\ntask: [purge] echo \"Purging...\"\nPurging...\ntask: [purge] rm -rf dist\ntask: [default] mkdir dist\ntask: [default] echo $CR_PAT | helm registry login ghcr.io --username $OWNER --password-stdin\nLogin Succeeded\ntask: [default] helm package signed-helm-chart --destination dist\nSuccessfully packaged chart and saved it to: dist/signed-helm-chart-0.1.0.tgz\ntask: [default] helm push dist/signed-helm-chart-*.tgz oci://ghcr.io/dirien/ \u003e .digest\ntask: [default] cat .digest | awk -F \"[, ]+\" '/Digest/{print $NF}'\nsha256:ab513674fdfdb100b9187747d63fca8cb9e89ba02977f3ef105ceee3ff9e9062\ntask: [default] cosign sign ghcr.io/dirien/signed-helm-chart@$(cat .digest | awk -F \"[, ]+\" '/Digest/{print $NF}')\nGenerating ephemeral keys...\nRetrieving signed certificate...\nclient.go:196: root pinning is not supported in Spec 1.0.19\nSuccessfully verified SCT...\ntlog entry created with index: 955563\nPushing signature to: ghcr.io/dirien/signed-helm-chart\n```\n\n## Open Points - Helm Provenance and Integrity\n\nWhat we need to improve now is: `helm verify` needs to check that the chart been signed and is valid.\n\nCurrently, Helm does not support the `cosign` to verify the signature of the chart.\n\nSee the [documentation](https://helm.sh/docs/topics/provenance/) about the supported Helm Provenance and Integrity\nmechanisms.\n\n## Resources\n\n- [go-task](https://taskfile.dev/)\n- [cosign](https://github.com/sigstore/cosign)\n- [helm](https://helm.sh/)\n- [GitHub Actions](https://docs.github.com/en/actions)\n- [Zero-friction “keyless signing” with Github Actions](https://chainguard.dev/posts/2021-12-01-zero-friction-keyless-signing)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirien%2Fsigned-helm-chart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdirien%2Fsigned-helm-chart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirien%2Fsigned-helm-chart/lists"}