{"id":24764204,"url":"https://github.com/sudo-bot/action-docker-sign","last_synced_at":"2025-10-11T13:30:16.402Z","repository":{"id":65155722,"uuid":"362444625","full_name":"sudo-bot/action-docker-sign","owner":"sudo-bot","description":"Sign your Docker images with DCT","archived":false,"fork":false,"pushed_at":"2024-08-04T00:14:57.000Z","size":92,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-03T21:09:43.492Z","etag":null,"topics":["dct","docker","docker-notary","docker-registry","docker-signatures","github-actions","security","signing"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudo-bot.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-28T11:34:19.000Z","updated_at":"2025-02-20T20:59:57.000Z","dependencies_parsed_at":"2025-01-28T21:38:23.345Z","dependency_job_id":"902c223e-bf6f-4e42-b8d4-717b50ab28e6","html_url":"https://github.com/sudo-bot/action-docker-sign","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sudo-bot/action-docker-sign","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-bot%2Faction-docker-sign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-bot%2Faction-docker-sign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-bot%2Faction-docker-sign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-bot%2Faction-docker-sign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudo-bot","download_url":"https://codeload.github.com/sudo-bot/action-docker-sign/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-bot%2Faction-docker-sign/sbom","scorecard":{"id":857282,"data":{"date":"2025-08-11","repo":{"name":"github.com/sudo-bot/action-docker-sign","commit":"257c981ea6835e3162fd974d223c969319a94f3b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T00:10:31.173Z","repository_id":65155722,"created_at":"2025-08-24T00:10:31.174Z","updated_at":"2025-08-24T00:10:31.174Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007341,"owners_count":26084282,"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","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["dct","docker","docker-notary","docker-registry","docker-signatures","github-actions","security","signing"],"created_at":"2025-01-28T21:38:06.832Z","updated_at":"2025-10-11T13:30:16.090Z","avatar_url":"https://github.com/sudo-bot.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# action-docker-sign\n\nSign your Docker images using [Docker Content Trust (DCT)](https://docs.docker.com/engine/security/trust/) !\n\n## Complete example\n\nYou can forge the key following [this manual](https://docs.docker.com/engine/security/trust/#signing-images-with-docker-content-trust)\n\n/!\\ Be sure to save in a safe place your root key\n\n/!\\ Do not use the repository or root key here, use a created delegated key\n\n```yaml\nname: Publish Docker image on tag push\n\npermissions:\n  contents: read\n\non:\n  push:\n    tags:\n       # Only the tag named latest\n       - 'latest'\n\njobs:\n  push-to-registry:\n    name: Push Docker image to Docker hub\n    runs-on: ubuntu-latest\n    steps:\n        - name: Check out the repository\n          uses: actions/checkout@v4\n        - name: Login to DockerHub\n          uses: docker/login-action@v3\n          with:\n            registry: docker.io\n            username: ${{ secrets.DOCKER_REPOSITORY_LOGIN }}\n            password: ${{ secrets.DOCKER_REPOSITORY_PASSWORD }}\n        - name: Build action image\n          # Use any good build command and be sure to tag the image correctly\n          run: make docker-build\n          env:\n            IMAGE_TAG: \"docker.io/botsudo/action-docker-compose:latest\"\n\n        - name: Sign and push docker image\n          uses: sudo-bot/action-docker-sign@latest\n          with:\n            image-ref: \"docker.io/botsudo/action-docker-compose:latest\"\n            # Example: 51f9a39f3db4ddaaf9174fca69f41fb01a04a4dfb5125ef115feecb93d19efa6\n            private-key-id: \"${{ secrets.DOCKER_PRIVATE_KEY_ID }}\"\n            # The contents from: ~/.docker/trust/private/51f9a39f3db4ddaaf9174fca69f41fb01a04a4dfb5125ef115feecb93d19efa6.key)\n            private-key: ${{ secrets.DOCKER_PRIVATE_KEY }}\n            # Example: myPassw0rdChangeMeReplaceMe\n            private-key-passphrase: ${{ secrets.DOCKER_PRIVATE_KEY_PASSPHRASE }}\n```\n\n## Example with docker buildx using manifests\n\n```yaml\nname: Publish Docker image\n\npermissions:\n    contents: read\n\non:\n    push:\n        tags:\n            - \"v*\"\n\njobs:\n    push-to-registry:\n        name: Push Docker image to Docker hub\n        runs-on: ubuntu-latest\n        strategy:\n            fail-fast: false\n            max-parallel: 4\n            matrix:\n                include:\n                    # All non supported by base image are commented\n                    # This is an example for base image alpine\n                    - { platform: \"linux/arm64\", platform-tag: \"arm64\" }\n                    - { platform: \"linux/amd64\", platform-tag: \"amd64\" }\n                    - { platform: \"linux/arm/v7\", platform-tag: \"armv7\" }\n                    - { platform: \"linux/arm/v6\", platform-tag: \"armv6\" }\n                    - { platform: \"linux/ppc64le\", platform-tag: \"ppc64le\" }\n                    #- { platform: \"linux/riscv64\", platform-tag: \"riscv64\" }\n                    - { platform: \"linux/s390x\", platform-tag: \"s390x\" }\n                    - { platform: \"linux/386\", platform-tag: \"386\" }\n                    #- { platform: \"linux/mips64le\", platform-tag: \"mips64le\" }\n                    #- { platform: \"linux/mips64\", platform-tag: \"mips64\" }\n\n        steps:\n            - name: Check out the repository\n              uses: actions/checkout@v4\n            - name: Login to DockerHub\n              uses: docker/login-action@v3\n              with:\n                  registry: docker.io\n                  username: ${{ secrets.DOCKER_REPOSITORY_LOGIN }}\n                  password: ${{ secrets.DOCKER_REPOSITORY_PASSWORD }}\n            # https://github.com/docker/setup-qemu-action\n            - name: Set up QEMU\n              uses: docker/setup-qemu-action@v3\n            # https://github.com/docker/setup-buildx-action\n            - name: Set up Docker Buildx\n              uses: docker/setup-buildx-action@v3\n            - name: Build and push the image\n              run: make docker-build\n              env:\n                  DOCKER_BUILDKIT: 1\n                  PLATFORM: \"${{ matrix.platform }}\"\n                  IMAGE_TAG: \"docker.io/botsudo/nut-upsd:${{ matrix.platform-tag }}-latest\"\n                  ACTION: push\n\n            - name: Sign the docker image\n              uses: sudo-bot/action-docker-sign@latest\n              with:\n                  image-ref: \"docker.io/botsudo/nut-upsd:${{ matrix.platform-tag }}-latest\"\n                  private-key-id: \"${{ vars.DOCKER_PRIVATE_KEY_ID }}\"\n                  # Must be exported using notary key export -d ~/.docker/trust --key ${{ vars.DOCKER_PRIVATE_KEY_ID }}\n                  # Use the delegated key or the repository key\n                  private-key: ${{ secrets.DOCKER_PRIVATE_KEY }}\n                  private-key-passphrase: ${{ secrets.DOCKER_PRIVATE_KEY_PASSPHRASE }}\n\n    sign-manifest:\n        name: Sign the docker hub manifest\n        runs-on: ubuntu-latest\n        needs: push-to-registry\n        steps:\n            - name: Login to DockerHub\n              uses: docker/login-action@v3\n              with:\n                  registry: docker.io\n                  username: ${{ secrets.DOCKER_REPOSITORY_LOGIN }}\n                  password: ${{ secrets.DOCKER_REPOSITORY_PASSWORD }}\n            - name: Create a manifest\n              env:\n                  DOCKER_CLI_EXPERIMENTAL: enabled\n              run: |\n                  docker manifest create docker.io/botsudo/nut-upsd:latest \\\n                      docker.io/botsudo/nut-upsd:arm64-latest \\\n                      docker.io/botsudo/nut-upsd:amd64-latest \\\n                      docker.io/botsudo/nut-upsd:armv7-latest \\\n                      docker.io/botsudo/nut-upsd:armv6-latest \\\n                      docker.io/botsudo/nut-upsd:ppc64le-latest \\\n                      docker.io/botsudo/nut-upsd:s390x-latest \\\n                      docker.io/botsudo/nut-upsd:386-latest \\\n                      --amend\n\n            - name: Sign the manifest\n              uses: sudo-bot/action-docker-sign@latest\n              with:\n                  image-ref: \"docker.io/botsudo/nut-upsd:latest\"\n                  # Sign the manifest\n                  sign-manifest: true\n                  # Required to sign the manifest\n                  notary-auth: \"${{ secrets.DOCKER_REPOSITORY_LOGIN }}:${{ secrets.DOCKER_REPOSITORY_PASSWORD }}\"\n                  # Use the delegated key or the repository key\n                  private-key-id: \"${{ vars.DOCKER_PRIVATE_KEY_ID }}\"\n                  # Remove this one if you use the repository key\n                  private-key-name: \"releases\" # Will be used for targets/releases\n                  private-key: ${{ secrets.DOCKER_PRIVATE_KEY }}\n                  private-key-passphrase: ${{ secrets.DOCKER_PRIVATE_KEY_PASSPHRASE }}\n\n```\n\n## Some errors you may run into\n\n- I had filled the repository key and key Id in the ENV variables and that did throw `failed to sign docker.io/botsudo/capistrano:latest: no valid signing keys for delegation roles` to me.\n- Then I updated the contents to use the user key contents but forgot to update the key Id and that did throw `failed to sign docker.io/botsudo/capistrano:latest: The targets metadata is invalid: tuf: data has no signatures` to me.\n- When using the user key Id and key contents it did work fine.\n\n## Inspect trust\n\n(be sure to check that the SHA matches, it will use the latest signed image if no signature has been done)\n\n```sh\ndocker trust inspect docker.io/botsudo/action-docker-compose:latest --pretty\n```\n\n### Example inspect output\n\n```text\nSignatures for docker.io/botsudo/action-docker-compose:latest\n\nSIGNED TAG          DIGEST                                                             SIGNERS\nlatest              8729542ca14dd459473e15719924d545809ce86a1b8e83c714e7108283841d13   sudo-bot\n\nList of signers and their keys for docker.io/botsudo/action-docker-compose:latest\n\nSIGNER              KEYS\nsudo-bot            46afe37834b3\nwilliamdes          51f9a39f3db4\n\nAdministrative keys for docker.io/botsudo/action-docker-compose:latest\n\n  Repository Key:\tfd6e4192798bf44c9e38bc4977d32701b5f78d3b27b1d3552e466f1f7460b2ed\n  Root Key:\t40222665dc8b8f91ae7a6fe5b0ec806ff3de8849374175b0334225235347525a\n```\n\n## Check that it works\n\n(be sure to check that the SHA matches)\n\n```sh\ndocker pull docker.io/botsudo/action-docker-compose:latest --disable-content-trust=false\n```\n\n### Example pull output\n\n```text\nPull (1 of 1): botsudo/action-docker-compose:latest@sha256:8729542ca14dd459473e15719924d545809ce86a1b8e83c714e7108283841d13\nsha256:8729542ca14dd459473e15719924d545809ce86a1b8e83c714e7108283841d13: Pulling from botsudo/action-docker-compose\nDigest: sha256:8729542ca14dd459473e15719924d545809ce86a1b8e83c714e7108283841d13\nStatus: Image is up to date for botsudo/action-docker-compose@sha256:8729542ca14dd459473e15719924d545809ce86a1b8e83c714e7108283841d13\nTagging botsudo/action-docker-compose@sha256:8729542ca14dd459473e15719924d545809ce86a1b8e83c714e7108283841d13 as botsudo/action-docker-compose:latest\ndocker.io/botsudo/action-docker-compose:latest\n```\n\n## Some usefull commands\n\n```sh\nnotary -s https://notary.docker.io delegation list docker.io/botsudo/capistrano\n# Add the key to the image as delegation\ndocker trust signer add --key ./key-name-or-user-name.pub key-name-or-user-name docker.io/botsudo/capistrano\n# Or (not sure it will work as well)\n# notary -s https://notary.docker.io delegation add docker.io/botsudo/capistrano targets/releases ./key-name-or-user-name.pub --all-paths\n# To remove it (if you did not use the right key)\ndocker trust signer remove williamdes docker.io/botsudo/capistrano\nnotary -s https://notary.docker.io delegation list docker.io/botsudo/capistrano\n# Using --local or not may change the results of what you are trying to do\ndocker trust sign --local docker.io/botsudo/capistrano:latest\n```\n\n## Sign multi platform manifests\n\nA solution for: https://github.com/docker/buildx/issues/313 and https://github.com/docker/cli/issues/392\n\n### Make a manifest\n\nUse `--amend` to update it.\n\n```sh\nDOCKER_CLI_EXPERIMENTAL=enabled docker manifest create docker.io/botsudo/nut-upsd:latest \\\n    docker.io/botsudo/nut-upsd:arm64-latest \\\n    docker.io/botsudo/nut-upsd:amd64-latest \\\n    docker.io/botsudo/nut-upsd:armv7-latest \\\n    docker.io/botsudo/nut-upsd:armv6-latest \\\n    docker.io/botsudo/nut-upsd:ppc64le-latest\n```\n\n### Push a manifest\n\nPurge is needed to be sure next time you create the manifest it updates the images.\nRef: [comment](https://github.com/docker/cli/issues/954#issuecomment-586722447)\n\n```sh\nDOCKER_CLI_EXPERIMENTAL=enabled docker manifest push docker.io/botsudo/nut-upsd:latest --purge\n```\n\n### Sign it\n\nMy testing show you need to sign **manifests** with the repository key otherwise pull will not work.\nSo do not use `-r targets/sudo-bot`\n\nIf you do not use a manifest you can use the same key as the one to sign the image, anyway you should not even be reading this because the image is already signed at this point.\n\n#### Fetch and check the values\n\nSet the repo to work on\n\n```sh\nexport REPO=\"library/alpine\"\nexport TAG=\"3.19.0\"\n```\n\nGet a token (per $REPO)\n\n```sh\nAUTH_BASIC_FROM_DOCKER_CREDS_IN_BASE64=\"$(cat ~/.docker/config.json | jq -r '.auths.\"https://index.docker.io/v1/\".auth')\"\n# This is usefull if you will do commands using the \"notary\" program\nexport NOTARY_AUTH=\"${AUTH_BASIC_FROM_DOCKER_CREDS_IN_BASE64}\"\nDT=\"$(curl -s \"https://auth.docker.io/token?service=registry.docker.io\u0026scope=repository:${REPO}:pull\" -H \"Authorization: Basic ${AUTH_BASIC_FROM_DOCKER_CREDS_IN_BASE64}\" | jq -r '.token')\"\n```\n\n##### Fetch the data to verify\n\n```sh\n# Recent example: multi arch manifest\n$ notary -s https://notary.docker.io list docker.io/library/alpine | grep -P \"^$TAG\"\n3.19.0             51b67269f354137895d43f3b3d810bfacd3945438e94dc5ac55fdac340352f48    1638            targets\n\n# Second older example: a manifest with only one arch\n$ notary -s https://notary.docker.io list docker.io/library/alpine | grep -P \"^$TAG\"\n3.5                66952b313e51c3bd1987d7c4ddf5dba9bc0fb6e524eed2448fa660246b3e76ec    433             targets\n\n# Other example\nnotary -s https://notary.docker.io list docker.io/botsudo/action-docker-compose\nNAME      DIGEST                                                              SIZE (BYTES)    ROLE\n----      ------                                                              ------------    ----\nlatest    beba5cb5ae49ec8185c999869d20de9ba5e6b2badebe65c1163a31906e65d413    947             targets/releases\n```\n\n##### Verify it (only for manifests: a.k.a multi arch images)\n\nFetch the manifest bytes count (Gives: `1638` bytes for this example)\n\n```sh\nBYTES_SIZE=\"$(curl -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' https://registry-1.docker.io/v2/$REPO/manifests/$TAG -H \"Authorization: Bearer $DT\" -XGET | wc -c)\"\necho \"Manifest size in bytes: $BYTES_SIZE\"\n```\n\nFetch the manifest sha-256 sum (Gives: `51b67269f354137895d43f3b3d810bfacd3945438e94dc5ac55fdac340352f48` for this example)\n\n```sh\nSHA=\"$(curl -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' https://registry-1.docker.io/v2/$REPO/manifests/$TAG -H \"Authorization: Bearer $DT\" -XGET | sha256sum | cut -d ' ' -f 1)\"\necho \"Manifest sha-256: $SHA\"\n```\n\n##### Verify it (only for images that are NOT multiarch)\n\nFetch the manifest bytes count (Gives: `947` bytes for this example)\n\n```sh\nBYTES_SIZE=\"$(curl -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' https://registry-1.docker.io/v2/$REPO/manifests/$TAG -H \"Authorization: Bearer $DT\" -XGET | wc -c)\"\necho \"Manifest size in bytes: $BYTES_SIZE\"\n```\n\nFetch the manifest sha-256 sum (Gives: `beba5cb5ae49ec8185c999869d20de9ba5e6b2badebe65c1163a31906e65d413` for this example)\n\n```sh\nSHA=\"$(curl -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' https://registry-1.docker.io/v2/$REPO/manifests/$TAG -H \"Authorization: Bearer $DT\" -XGET | sha256sum | cut -d ' ' -f 1)\"\necho \"Manifest sha-256: $SHA\"\n```\n\n##### More notes\n\nSource: [~~for the skopeo command~~](https://www.unboundtech.com/docs/UKC/UKC_Code_Signing_IG/HTML/Content/Products/UKC-EKM/UKC_Code_Signing_IG/Notary/notary_overview.htm)\n\nThe `BYTES_SIZE` bytes length can be fetched using [skopeo](https://github.com/containers/skopeo): `skopeo inspect --raw docker://docker.io/$REPO | wc -c` **and should match `${BYTES_SIZE}`**.\n\nAnd the hash from `skopeo inspect --raw docker://docker.io/$REPO | sha256sum` **should match `${SHA}`**\n\nLast method to get the values: `DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect docker.io/$REPO -v | jq '.Descriptor'`, `digest` and `size` should be coherent with `${SHA}` and `${BYTES_SIZE}`.\n\n#### Add the hash to notary\n\n```sh\nnotary addhash -p docker.io/$REPO ${TAG_NAME} ${BYTES_SIZE} --sha256 ${MANIFEST_SHA_FROM_ABOVE_COMMAND}\n```\n\nYou can remove it if you need: `notary remove docker.io/$REPO latest -r targets/williamdes --publish` (`targets/williamdes` can be removed depending on what key signed the value to remove).\n\n#### Some usefull notes\n\nUsing manifests always did give `946` for `${BYTES_SIZE}` for some reason, but not on single signed images.\n\n**A very important note:** `notary list docker.io/botsudo/nut-upsd` can list the bad last signed value, like it was hiding another value behind it. This is why I use `notary remove` when I can not get the same value as the one the signing CI printed out at the end of the process.\n\n**Example:** I had signed an image with my local key, and then I released a version that was signed by the CI key. When I listed using `notary list` the signed value by the CI was not showing. After removing my signature of the previous value it worked fine.\n\nThis [website](https://containers.gitbook.io/build-containers-the-hard-way/#registry-format-oci-image-manifest) is helpfull to know more about how manifests are built.\n\n### See the results\n\nCheck the SHAs !!\n\n```sh\ndocker trust inspect docker.io/botsudo/nut-upsd --pretty\nnotary  -s https://notary.docker.io list docker.io/botsudo/nut-upsd\ndocker pull docker.io/botsudo/nut-upsd:latest --disable-content-trust=false\n```\n\n## Renewing/Re-building the repository metadata\n\nWhen you have one of the errors:\n\n`targets metadata is nearing expiry, you should re-sign the role metadata`\n- `Error getting targets/releases: valid signatures did not meet threshold for targets/releases`\n- `targets/sudo-bot metadata is nearing expiry, you should re-sign the role metadata`\n\n```sh\n# Avoid auth at each notary command\nexport NOTARY_AUTH=\"$(printf \"docker-username:docker-token\" | base64 -w0)\";\n\ndocker trust inspect docker.io/botsudo/nut-upsd --pretty\nnotary -d ~/.docker/trust/ -s https://notary.docker.io delegation list docker.io/botsudo/nut-upsd\nnotary -d ~/.docker/trust/ -s https://notary.docker.io status docker.io/botsudo/nut-upsd\nnotary -d ~/.docker/trust/ -s https://notary.docker.io witness docker.io/botsudo/nut-upsd targets/sudo-bot\nnotary -d ~/.docker/trust/ -s https://notary.docker.io witness docker.io/botsudo/nut-upsd targets/releases\nnotary -d ~/.docker/trust/ -s https://notary.docker.io status docker.io/botsudo/nut-upsd\nnotary -d ~/.docker/trust/ -s https://notary.docker.io publish docker.io/botsudo/nut-upsd\n```\n\nWhen you have one of the errors:\n- `ERRO[0001] Metadata for targets expired`\n- `ERRO[0002] Metadata for targets expired`\n- `fatal: Error retrieving delegation roles for repository docker.io/botsudo/action-docker-compose: targets expired at Sat Apr 27 14:38:05 CEST 2024`\n\n```sh\n# Purge the contents\nnotary -d ~/.docker/trust/ -s https://notary.docker.io delete --remote --verbose docker.io/botsudo/action-docker-compose\n\n# Check key list\nnotary -d ~/.docker/trust/ -s https://notary.docker.io key list\n# You should have the old repository key\n\n# If you make mistakes: notary -s https://notary.docker.io reset docker.io/botsudo/action-docker-compose --all\n# If you make mistakes: notary -s https://notary.docker.io -d ~/.docker/trust/ delete docker.io/botsudo/action-docker-compose\n# Init a new collection with the same old root private key as before\nnotary -d ~/.docker/trust/ -s https://notary.docker.io init docker.io/botsudo/action-docker-compose --rootkey ./root_e54577868c1f326f0070b99c86ca3f17d1bb753808d73a78e7b322d379b0a04c.key -p\n\n# You should not need this\n# notary -d ~/.docker/trust/ -s https://notary.docker.io publish docker.io/botsudo/action-docker-compose\n\n# Add the target\ndocker trust signer add --key ./sudo-bot.pub sudo-bot docker.io/botsudo/action-docker-compose\n\n# Check\nnotary -d ~/.docker/trust/ -s https://notary.docker.io delegation list docker.io/botsudo/action-docker-compose\ndocker trust inspect --pretty docker.io/botsudo/action-docker-compose\n# it shows my sudo-bot key in targets/releases and targets/sudo-bot\n\n# You may want to get rid of the snapshot key: https://stackoverflow.com/a/78830014/5155484\nnotary -d ~/.docker/trust/ -s https://notary.docker.io key rotate docker.io/botsudo/action-docker-compose snapshot -r\n\n# You may want to run this commands, maybe after a tag is pushed ?\nnotary -d ~/.docker/trust/ -s https://notary.docker.io witness docker.io/botsudo/action-docker-compose targets/sudo-bot\nnotary -d ~/.docker/trust/ -s https://notary.docker.io witness docker.io/botsudo/action-docker-compose targets/releases\n```\n\n## Exporting a key\n\n### In the \"Notary format\"\n\nRef: https://github.com/theupdateframework/notary/issues/1363\nRef: https://github.com/docker/cli/issues/1095#issuecomment-423707423\n\n```sh\nnotary key export -d ~/.docker/trust --key 46afe37834b3f7f7f76f5f9cfb77d7a8a3383353581cdf74236dcf43df0260e4\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudo-bot%2Faction-docker-sign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudo-bot%2Faction-docker-sign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudo-bot%2Faction-docker-sign/lists"}