mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-10 03:47:03 +02:00
253 lines
6.7 KiB
Markdown
253 lines
6.7 KiB
Markdown
# Signing checksums and artifacts
|
|
|
|
Signing ensures that the artifacts have been generated by yourself and your
|
|
users can verify that by comparing the generated signature with your public
|
|
signing key.
|
|
|
|
GoReleaser provides means to sign both executables and archives.
|
|
|
|
## Usage
|
|
|
|
Signing works in combination with checksum files and it is generally sufficient
|
|
to sign the checksum files only.
|
|
|
|
The default is configured to create a detached signature for the checksum files
|
|
with [GnuPG](https://www.gnupg.org/) and your default key. To enable signing
|
|
just add
|
|
|
|
```yaml
|
|
# .goreleaser.yaml
|
|
signs:
|
|
- artifacts: checksum
|
|
```
|
|
|
|
To customize the signing pipeline you can use the following options:
|
|
|
|
```yaml
|
|
# .goreleaser.yaml
|
|
signs:
|
|
-
|
|
# ID of the sign config, must be unique.
|
|
#
|
|
# Defaults to "default".
|
|
id: foo
|
|
|
|
# Name/template of the signature file.
|
|
#
|
|
# Defaults to `${artifact}.sig`.
|
|
signature: "${artifact}_sig"
|
|
|
|
# Path to the signature command
|
|
#
|
|
# Defaults to `gpg`
|
|
cmd: gpg2
|
|
|
|
# Command line templateable arguments for the command
|
|
#
|
|
# to sign with a specific key use
|
|
# args: ["-u", "<key id, fingerprint, email, ...>", "--output", "${signature}", "--detach-sign", "${artifact}"]
|
|
#
|
|
# Defaults to `["--output", "${signature}", "--detach-sign", "${artifact}"]`
|
|
args: ["--output", "${signature}", "${artifact}", "{{ .ProjectName }}"]
|
|
|
|
|
|
# Which artifacts to sign
|
|
#
|
|
# all: all artifacts
|
|
# none: no signing
|
|
# checksum: only checksum file(s)
|
|
# source: source archive
|
|
# package: linux packages (deb, rpm, apk)
|
|
# archive: archives from archive pipe
|
|
# binary: binaries if archiving format is set to binary
|
|
# sbom: any Software Bill of Materials generated for other artifacts
|
|
#
|
|
# Defaults to `none`
|
|
artifacts: all
|
|
|
|
# IDs of the artifacts to sign.
|
|
#
|
|
# If `artifacts` is checksum or source, this fields has no effect.
|
|
#
|
|
# Defaults to empty (which implies no filtering).
|
|
ids:
|
|
- foo
|
|
- bar
|
|
|
|
# Stdin data template to be given to the signature command as stdin.
|
|
#
|
|
# Defaults to empty
|
|
stdin: '{{ .Env.GPG_PASSWORD }}'
|
|
|
|
# StdinFile file to be given to the signature command as stdin.
|
|
#
|
|
# Defaults to empty
|
|
stdin_file: ./.password
|
|
|
|
# Sets a certificate that your signing command should write to.
|
|
# You can later use `${certificate}` or `.Env.certificate` in the `args` section.
|
|
# This is particularly useful for keyless signing (for instance, with cosign).
|
|
# Note that this should be a name, not a path.
|
|
#
|
|
# Defaults to empty.
|
|
certificate: '{{ trimsuffix .Env.artifact ".tar.gz" }}.pem'
|
|
|
|
# List of environment variables that will be passed to the signing command as well as the templates.
|
|
#
|
|
# Defaults to empty
|
|
env:
|
|
- FOO=bar
|
|
- HONK=honkhonk
|
|
|
|
# By default, the stdout and stderr of the signing cmd are discarded unless GoReleaser is running with `--debug` set.
|
|
# You can set this to true if you want them to be displayed regardless.
|
|
#
|
|
# Defaults to false
|
|
output: true
|
|
```
|
|
|
|
### Available variable names
|
|
|
|
These environment variables might be available in the fields that are templateable:
|
|
|
|
- `${artifact}`: the path to the artifact that will be signed
|
|
- `${artifactID}`: the ID of the artifact that will be signed
|
|
- `${certificate}`: the certificate filename, if provided
|
|
- `${signature}`: the signature filename
|
|
|
|
## Signing with cosign
|
|
|
|
You can sign you artifacts with [cosign][] as well.
|
|
|
|
Assuming you have a `cosign.key` in the repository root and a `COSIGN_PWD` environment variable set, a simple usage example would look like this:
|
|
|
|
```yaml
|
|
# .goreleaser.yaml
|
|
signs:
|
|
- cmd: cosign
|
|
stdin: '{{ .Env.COSIGN_PWD }}'
|
|
args: ["sign-blob", "--key=cosign.key", "--output=${signature}", "${artifact}"]
|
|
artifacts: all
|
|
```
|
|
|
|
Your users can then verify the signature with:
|
|
|
|
```sh
|
|
cosign verify-blob -key cosign.pub -signature file.tar.gz.sig file.tar.gz
|
|
```
|
|
|
|
<!-- TODO: keyless signing with cosign example -->
|
|
|
|
## Signing executables
|
|
|
|
Executables can be signed after build using post hooks.
|
|
|
|
### With gon
|
|
|
|
For example, you can use [gon][] to create notarized MacOS apps:
|
|
|
|
```yaml
|
|
# .goreleaser.yaml
|
|
builds:
|
|
- binary: foo
|
|
id: foo
|
|
goos:
|
|
- linux
|
|
- windows
|
|
goarch:
|
|
- amd64
|
|
|
|
# notice that we need a separated build for the MacOS binary only:
|
|
- binary: foo
|
|
id: foo-macos
|
|
goos:
|
|
- darwin
|
|
goarch:
|
|
- amd64
|
|
hooks:
|
|
post: gon gon.hcl
|
|
```
|
|
|
|
and:
|
|
|
|
```terraform
|
|
# gon.hcl
|
|
#
|
|
# The path follows a pattern
|
|
# ./dist/BUILD-ID_TARGET/BINARY-NAME
|
|
source = ["./dist/foo-macos_darwin_amd64/foo"]
|
|
bundle_id = "com.mitchellh.example.terraform"
|
|
|
|
apple_id {
|
|
username = "mitchell@example.com"
|
|
password = "@env:AC_PASSWORD"
|
|
}
|
|
|
|
sign {
|
|
application_identity = "Developer ID Application: Mitchell Hashimoto"
|
|
}
|
|
```
|
|
|
|
Note that notarizing may take some time, and will need to be run from a MacOS machine.
|
|
|
|
If you generate ZIP or DMG as part of your signing via gon you may need
|
|
to ensure their file names align with desired pattern of other artifacts
|
|
as GoReleaser doesn't control how these get generated beyond just executing `gon`
|
|
with given arguments. Relatedly you may need to list these additional artifacts
|
|
as `extra_files` in the `release` section to make sure they also get uploaded.
|
|
|
|
You can also check [this issue](https://github.com/goreleaser/goreleaser/issues/1227) for more details.
|
|
|
|
|
|
### With cosign
|
|
|
|
You can also use [cosign][] to sign the binaries directly,
|
|
but you'll need to manually add the `.sig` files to the release and/or archive:
|
|
|
|
```yaml
|
|
# .goreleaser.yaml
|
|
builds:
|
|
- hooks:
|
|
post:
|
|
- sh -c "COSIGN_PASSWORD=$COSIGN_PWD cosign sign-blob --key cosign.key --output dist/{{ .ProjectName }}_{{ .Version }}_{{ .Target }}.sig {{ .Path }}"
|
|
|
|
# add to the release directly:
|
|
release:
|
|
extra_files:
|
|
- glob: dist/*.sig
|
|
|
|
# or just to the archives:
|
|
archives:
|
|
- files:
|
|
- dist/*.sig
|
|
```
|
|
|
|
While this works, I would recommend using the signing pipe directly.
|
|
|
|
## Signing Docker images and manifests
|
|
|
|
Please refer to [Docker Images Signing](/customization/docker_sign/).
|
|
|
|
## Limitations
|
|
|
|
You can sign with any command that either outputs a file or modify the file being signed.
|
|
|
|
If you want to sign with something that writes to `STDOUT` instead of a file,
|
|
you can wrap the command inside a `sh -c` execution, for instance:
|
|
|
|
```yaml
|
|
# .goreleaser.yaml
|
|
signs:
|
|
- cmd: sh
|
|
args:
|
|
- '-c'
|
|
- 'echo "${artifact} is signed and I can prove it" | tee ${signature}'
|
|
artifacts: all
|
|
```
|
|
|
|
And it will work just fine. Just make sure to always use the `${signature}`
|
|
template variable as the result file name and `${artifact}` as the origin file.
|
|
|
|
[gon]: https://github.com/mitchellh/gon
|
|
[cosign]: https://github.com/sigstore/cosign
|