{"id":19293018,"url":"https://github.com/avisi-cloud/cosign-tutorial","last_synced_at":"2025-08-26T16:21:01.925Z","repository":{"id":38397062,"uuid":"506568008","full_name":"avisi-cloud/cosign-tutorial","owner":"avisi-cloud","description":"Use cosign to secure your container images using Github actions","archived":false,"fork":false,"pushed_at":"2022-10-03T20:14:03.000Z","size":378,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T04:11:57.703Z","etag":null,"topics":["cosign","docker"],"latest_commit_sha":null,"homepage":"https://docs.avisi.cloud","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avisi-cloud.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":"2022-06-23T09:01:08.000Z","updated_at":"2025-04-07T17:57:24.000Z","dependencies_parsed_at":"2023-01-19T04:31:10.279Z","dependency_job_id":null,"html_url":"https://github.com/avisi-cloud/cosign-tutorial","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/avisi-cloud%2Fcosign-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avisi-cloud%2Fcosign-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avisi-cloud%2Fcosign-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avisi-cloud%2Fcosign-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avisi-cloud","download_url":"https://codeload.github.com/avisi-cloud/cosign-tutorial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514205,"owners_count":21116903,"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":["cosign","docker"],"created_at":"2024-11-09T22:33:50.962Z","updated_at":"2025-04-12T04:12:04.642Z","avatar_url":"https://github.com/avisi-cloud.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cosign tutorial - signing OCI artifacts\n\n![Avisi Cloud Logo](https://docs.avisi.cloud/avisi-cloud-logo-black.png)\n\nCosign allows us to sign our container images and verify the integrity when pulling images from our registry. This repository is a tutorial on how to use cosign to sign your OCI artifacts.\n\nCosign is a project part of [sigstore](https://www.sigstore.dev/), an effort to introduce a new standard for signing, verifying and protecting software.\n\n# Tutorial\n\n## Generate a key pair\n\nGenerate a key pair that will be used to sign your OCI artifacts / container images.\n\n```shell\n❯ cosign generate-key-pair\nEnter password for private key:\nEnter again:\nPrivate key written to cosign.key\nPublic key written to cosign.pub\n```\n\nMake sure you save your password, as you will need it to sign OCI artifacts.\n\n## Cosign CLI\n\n### Sign OCI artifacts\n\nNow you have everything needed from cosign to sign an OCI artifact.\nFor this step, you will need write access to a registry, as well as a container image.\n\nDemo image:\n```shell\n❯ docker pull docker.io/library/nginx:latest\n❯ docker tag docker.io/library/nginx:latest ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest\n```\n\nSign the artifact:\n\n```shell\n❯ cosign sign --key cosign.key ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest\n```\n\nNote that the image should already be present in the registry, otherwise you will receive an error:\n\n```shell\nError: signing [ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest]: accessing entity: entity not found in registry\nmain.go:46: error during command execution: signing [ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest]: accessing entity: entity not found in registry\n```\n\nWhen signing the image:\n```shell\n❯ cosign sign --key cosign.key ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest\nEnter password for private key: \nPushing signature to: ghcr.io/avisi-cloud/cosign-tutorial-nginx\n```\n\n### Verify our signature\n\nYou can verify in Github Packages that this image has been signed:\n\n![github packages for cosign-tutorial-nginx image](/img/cosign-tutorial-nginx-signed.png)\n\nNote that this image contains two tags: `latest` and the `sha256-` tag. \n\n`sha256-3536d368b898eef291fb1f6d184a95f8bc1a6f863c48457395aab859fda354d1.sig` is the signature created and pushed by cosign. It is used by cosign to verify this image against the public key.\n\nYou can verify this through the CLI using `cosign verify`:\n\n```shell\n❯ cosign verify --key cosign.pub ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest\n\nVerification for ghcr.io/avisi-cloud/cosign-tutorial-nginx:latest --\nThe following checks were performed on each of these signatures:\n  - The cosign claims were validated\n  - The signatures were verified against the specified public key\n\n[{\"critical\":{\"identity\":{\"docker-reference\":\"ghcr.io/avisi-cloud/cosign-tutorial-nginx\"},\"image\":{\"docker-manifest-digest\":\"sha256:3536d368b898eef291fb1f6d184a95f8bc1a6f863c48457395aab859fda354d1\"},\"type\":\"cosign container image signature\"},\"optional\":null}]\n```\n\n## Using Github Actions\n\nYou can automate the signing of your container images by using Github Actions. For this you need to do the following:\n\nFirst add the `cosign.key` and `password` as a secret to your project or Github organisation as an [action secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets).\nYou can do this within your project or by using organisation secrets.\n\n![cosign organisation secrets example](/img/cosign-organisation-secrets.png)\n\n### Set-up action\n\n\nYou can set-up cosign by using the following job step:\n\n```yaml\njobs:\n  build-push:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n      # install cosign\n      - name: Set up cosign\n        uses: sigstore/cosign-installer@main\n\n      # log in to the ghcr registry\n      - name: Login to GitHub Container Registry\n        uses: docker/login-action@v2\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n```\n\nYou can also verify the base image in your `Dockerfile`. This allows you to make sure the base image used is from a trusted source.\n\n```yaml\n      - name: Verify base image\n        run: |          \n          cosign dockerfile verify --base-image-only --key https://github.com/GoogleContainerTools/distroless Dockerfile\n```\n\nNext build and publish your container image to the registry:\n```yaml\n      - name: Publish container image\n        uses: docker/build-push-action@v3\n        with:\n          push: true\n          builder: ${{ steps.buildx.outputs.name }}\n          context: .\n          file: ./Dockerfile\n          platforms: linux/amd64\n          tags: |\n            ghcr.io/avisi-cloud/${{ env.IMAGE_NAME }}:${{ env.VERSION }}\n          labels: |\n            org.opencontainers.image.title=${{ github.event.repository.name }}\n            org.opencontainers.image.description=${{ github.event.repository.description }}\n            org.opencontainers.image.url=${{ github.event.repository.html_url }}\n            org.opencontainers.image.revision=${{ github.sha }}\n            org.opencontainers.image.version=${{ env.VERSION }}\n```\n\n\u003e Note that this entire process will work with any container registry, not just ghcr.\n\nNow we can sign the images we just published to our registry by using `cosign sign` with the `cosign.key` and password we used as our orgnaisation or project secret:\n\n```yaml\n      - name: sign container image\n        run: |\n            cosign sign --key env://COSIGN_KEY ghcr.io/avisi-cloud/${{ env.IMAGE_NAME }}:${{ env.VERSION }}\n        shell: bash\n        env:\n          COSIGN_KEY: ${{secrets.COSIGN_KEY}}\n          COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}\n```\n\nAnd a final step we can verify our entire signing proces worked as expected by running `cosign verify` as our last step in the action workflow:\n\n```yaml\n\n      - name: Check images\n        run: |\n          docker buildx imagetools inspect ghcr.io/avisi-cloud/${IMAGE_NAME}:${{ env.VERSION }}\n          docker pull ghcr.io/avisi-cloud/${IMAGE_NAME}:${{ env.VERSION }}\n          cosign verify --key cosign.pub ghcr.io/avisi-cloud/${IMAGE_NAME}:${{ env.VERSION }} \n```\n\nYou can see a full example [here](https://github.com/avisi-cloud/cosign-tutorial/blob/main/.github/workflows/release.yml).\n\n![example run](img/github-actions.png)\n\n## Gitlab CI Pipelines\n\nThis is also possible in Gitlab CI or any other CI service. Here is an example for in Gitlab:\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favisi-cloud%2Fcosign-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favisi-cloud%2Fcosign-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favisi-cloud%2Fcosign-tutorial/lists"}