1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-10 03:47:03 +02:00
goreleaser/www/docs/customization/sign.md

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