github.com/goreleaser/goreleaser@v1.25.1/www/docs/customization/sign.md (about)

     1  # Signing checksums and artifacts
     2  
     3  Signing ensures that the artifacts have been generated by yourself, and your
     4  users can verify that by comparing the generated signature with your public
     5  signing key.
     6  
     7  GoReleaser provides means to sign both executables and archives.
     8  
     9  ## Usage
    10  
    11  Signing works in combination with checksum files, and it is generally enough
    12  to sign the checksum files only.
    13  
    14  The default is configured to create a detached signature for the checksum files
    15  with [GnuPG](https://www.gnupg.org/), and your default key. To enable signing
    16  just add
    17  
    18  ```yaml
    19  # .goreleaser.yaml
    20  signs:
    21    - artifacts: checksum
    22  ```
    23  
    24  To customize the signing pipeline you can use the following options:
    25  
    26  ```yaml
    27  # .goreleaser.yaml
    28  signs:
    29    - #
    30      # ID of the sign config, must be unique.
    31      #
    32      # Default: 'default'
    33      id: foo
    34  
    35      # Name of the signature file.
    36      #
    37      # Default: '${artifact}.sig'
    38      # Templates: allowed
    39      signature: "${artifact}_sig"
    40  
    41      # Path to the signature command
    42      #
    43      # Default: 'gpg'
    44      cmd: gpg2
    45  
    46      # Command line arguments for the command
    47      #
    48      # to sign with a specific key use
    49      # args: ["-u", "<key id, fingerprint, email, ...>", "--output", "${signature}", "--detach-sign", "${artifact}"]
    50      #
    51      # Default: ["--output", "${signature}", "--detach-sign", "${artifact}"]
    52      # Templates: allowed
    53      args: ["--output", "${signature}", "${artifact}", "{{ .ProjectName }}"]
    54  
    55      # Which artifacts to sign
    56      #
    57      # Valid options are:
    58      # - none        no signing
    59      # - all:        all artifacts
    60      # - checksum:   checksum files
    61      # - source:     source archive
    62      # - package:    Linux packages (deb, rpm, apk, etc)
    63      # - installer:  Windows MSI installers (Pro only)
    64      # - diskimage:  macOS DMG disk images (Pro only)
    65      # - archive:    archives from archive pipe
    66      # - binary:     binaries output from the build stage
    67      # - sbom:       any SBOMs generated for other artifacts
    68      #
    69      # Default: 'none'
    70      artifacts: all
    71  
    72      # IDs of the artifacts to sign.
    73      #
    74      # If `artifacts` is checksum or source, this fields has no effect.
    75      ids:
    76        - foo
    77        - bar
    78  
    79      # Stdin data to be given to the signature command as stdin.
    80      #
    81      # Templates: allowed
    82      stdin: "{{ .Env.GPG_PASSWORD }}"
    83  
    84      # StdinFile file to be given to the signature command as stdin.
    85      stdin_file: ./.password
    86  
    87      # Sets a certificate that your signing command should write to.
    88      #
    89      # You can later use `${certificate}` or `.Env.certificate` in the `args` section.
    90      #
    91      # This is particularly useful for keyless signing with cosign, and should
    92      # not usually be used otherwise.
    93      #
    94      # Note that this should be a name, not a path.
    95      #
    96      # Templates: allowed
    97      certificate: '{{ trimsuffix .Env.artifact ".tar.gz" }}.pem'
    98  
    99      # List of environment variables that will be passed to the signing command
   100      # as well as the templates.
   101      env:
   102        - FOO=bar
   103        - HONK=honkhonk
   104  
   105      # By default, the stdout and stderr of the signing cmd are discarded unless
   106      # GoReleaser is running with `--debug` set.
   107      # You can set this to true if you want them to be displayed regardless.
   108      #
   109      # Since: v1.2
   110      output: true
   111  ```
   112  
   113  ### Available variable names
   114  
   115  These environment variables might be available in the fields that accept
   116  templates:
   117  
   118  - `${artifact}`: the path to the artifact that will be signed
   119  - `${artifactID}`: the ID of the artifact that will be signed
   120  - `${certificate}`: the certificate filename, if provided
   121  - `${signature}`: the signature filename
   122  
   123  ## Signing with cosign
   124  
   125  You can sign your artifacts with [cosign][] as well.
   126  
   127  Assuming you have a `cosign.key` in the repository root and a `COSIGN_PWD`
   128  environment variable set, a simple usage example would look like this:
   129  
   130  ```yaml
   131  # .goreleaser.yaml
   132  signs:
   133    - cmd: cosign
   134      stdin: "{{ .Env.COSIGN_PWD }}"
   135      args:
   136        - "sign-blob"
   137        - "--key=cosign.key"
   138        - "--output-signature=${signature}"
   139        - "${artifact}"
   140        - "--yes" # needed on cosign 2.0.0+
   141      artifacts: all
   142  ```
   143  
   144  Your users can then verify the signature with:
   145  
   146  ```sh
   147  cosign verify-blob -key cosign.pub -signature file.tar.gz.sig file.tar.gz
   148  ```
   149  
   150  <!-- TODO: keyless signing with cosign example -->
   151  
   152  ## Signing executables
   153  
   154  Executables can be signed after build using post hooks.
   155  
   156  ### With gon
   157  
   158  !!! notice
   159  
   160      [gon][] was discontinued by its maintainer, but it lives on in a
   161      [fork][gon-fork], which we'll use here.
   162  
   163  For example, you can use [gon][gon-fork] to create notarized macOS apps:
   164  
   165  ```yaml
   166  # .goreleaser.yaml
   167  builds:
   168    - binary: foo
   169      id: foo
   170      goos:
   171        - linux
   172        - windows
   173      goarch:
   174        - amd64
   175  
   176    # notice that we need a separated build for the MacOS binary only:
   177    - binary: foo
   178      id: foo-macos
   179      goos:
   180        - darwin
   181      goarch:
   182        - amd64
   183      hooks:
   184        post: gon gon.hcl
   185  ```
   186  
   187  And:
   188  
   189  ```terraform
   190  # gon.hcl
   191  #
   192  # The path follows a pattern
   193  # ./dist/BUILD-ID_TARGET/BINARY-NAME
   194  source = ["./dist/foo-macos_darwin_amd64/foo"]
   195  bundle_id = "com.mitchellh.example.terraform"
   196  
   197  apple_id {
   198    username = "mitchell@example.com"
   199    password = "@env:AC_PASSWORD"
   200  }
   201  
   202  sign {
   203    application_identity = "Developer ID Application: Mitchell Hashimoto"
   204  }
   205  ```
   206  
   207  Note that notarizing may take some time, and will need to be run from a macOS
   208  machine.
   209  
   210  If you generate ZIP or DMG as part of your signing via gon you may need to
   211  ensure their file names align with desired pattern of other artifacts as
   212  GoReleaser doesn't control how these get generated beyond just executing `gon`
   213  with given arguments. Relatedly you may need to list these additional artifacts
   214  as `extra_files` in the `release` section to make sure they also get uploaded.
   215  
   216  You can also check
   217  [this issue](https://github.com/goreleaser/goreleaser/issues/1227) for more
   218  details.
   219  
   220  ### With cosign
   221  
   222  You can also use [cosign][] to sign the binaries directly, but you'll need to
   223  manually add the `.sig` files to the release and/or archive:
   224  
   225  ```yaml
   226  # .goreleaser.yaml
   227  builds:
   228    - hooks:
   229        post:
   230          - sh -c "COSIGN_PASSWORD=$COSIGN_PWD cosign sign-blob --key cosign.key --output-signature dist/{{ .ProjectName }}_{{ .Version }}_{{ .Target }}.sig {{ .Path }}"
   231  
   232  # add to the release directly:
   233  release:
   234    extra_files:
   235      - glob: dist/*.sig
   236  
   237  # or just to the archives:
   238  archives:
   239    - files:
   240        - dist/*.sig
   241  ```
   242  
   243  While this works, I would recommend using the signing pipe directly.
   244  
   245  ## Signing Docker images and manifests
   246  
   247  Please refer to [Docker Images Signing](/customization/docker_sign/).
   248  
   249  ## Limitations
   250  
   251  You can sign with any command that either outputs a file or modify the file
   252  being signed.
   253  
   254  If you want to sign with something that writes to `STDOUT` instead of a file,
   255  you can wrap the command inside a `sh -c` execution, for instance:
   256  
   257  ```yaml
   258  # .goreleaser.yaml
   259  signs:
   260    - cmd: sh
   261      args:
   262        - "-c"
   263        - 'echo "${artifact} is signed and I can prove it" | tee ${signature}'
   264      artifacts: all
   265  ```
   266  
   267  And it will work just fine. Just make sure to always use the `${signature}`
   268  template variable as the result file name and `${artifact}` as the origin file.
   269  
   270  [gon]: https://github.com/mitchellh/gon
   271  [gon-fork]: https://github.com/Bearer/gon
   272  [cosign]: https://github.com/sigstore/cosign