Skip to content

Compile in signing backends

The sign and keys mint commands resolve their --backend value against the go/signing registry. This module registers no backend itself — the host binary decides which backends exist by blank-importing them in its main package. This guide shows how.

Background on why activation works this way is in Backends are the consumer's responsibility.

Blank-import the backends you want

Each backend registers its name from init(), so importing the package for its side effect is all it takes:

package main

import (
    _ "gitlab.com/phpboyscout/go/signing-aws-kms" // registers "aws-kms"
    _ "gitlab.com/phpboyscout/go/signing/local"   // registers "local"
)
Backend Registered name --key-id means Extra flags
signing-aws-kms aws-kms A KMS key ID, ARN, or alias --kms-region (and any others the backend declares)
signing/local local A path to a PEM-encoded RSA private key

With both imports present:

your-tool sign --backend local   --key-id ./release.pem --public-key release.asc checksums.txt
your-tool sign --backend aws-kms --key-id alias/release-signing-v1 --kms-region eu-west-2 \
    --public-key release.asc checksums.txt

Backend-specific flags such as --kms-region appear in --help automatically when a backend that declares them is compiled in — the commands type-assert each registered backend for an optional RegisterFlags(*pflag.FlagSet) and let it add its own flags.

Keep the imports in one file

go-tool-base isolates its backend imports in a single file so there is one place to change the binary's signing capabilities. cmd/gtb/signing.go is nothing but:

package main

import (
    _ "gitlab.com/phpboyscout/go/signing-aws-kms"
    _ "gitlab.com/phpboyscout/go/signing/local"
)

Copy that pattern in your own main package: a dedicated signing.go (or similar) that holds only the blank imports. It makes the "which backends does this build ship?" question answerable at a glance, and makes dropping one a one-line edit.

Dropping a backend (FIPS / regulated builds)

Because a backend's heavy dependencies (the AWS SDK, for aws-kms) enter the module graph only through its blank import, removing the import and rebuilding removes the SDK from the artefact — linker dead-code elimination does the rest. No code in signing-cli or in your command wiring changes; the aws-kms name simply stops appearing under --backend.

go-tool-base proves this with a dedicated cmd/gtb-no-aws-smoke binary that omits the KMS import specifically to assert the AWS SDK is not pulled in transitively by signing-cli or the command wiring. If you maintain a constrained build, an equivalent smoke binary plus a dependency assertion is a worthwhile guard.

Adding your own backend

Any backend is a type implementing go/signing's Backend interface (Name() and NewSigner(ctx, keyID)), registered from init() via signing.Register. Put it in its own module, blank-import it here just like the built-ins, and it shows up under --backend. The full recipe lives in the go/signing docs: Implement a custom backend.

See also