pkg-keygen(1)
NAME
pkg-keygen - create the key pkg build signs with
SYNOPSIS
pkg keygen [--force]
DESCRIPTION
Everything pkg-build(1) produces is signed: every manifest a build emits, and the TUF metadata of the repository it publishes into, including that repository's self-signed metadata/1.root.json. Signing needs a key, and this command makes it.
It generates an Ed25519 key and writes it to $XDG_CONFIG_HOME/pkg/build.key, or to ~/.config/pkg/build.key when XDG_CONFIG_HOME is unset or isn't an absolute path. The directory is created if needed.
You only do this once. pkg build refuses to run without a key, and when it does, it tells you to run this command.
Why not a fresh key per build?
Because the key is the identity of the repositories you publish. Whoever consumes one of your repositories pins its 1.root.json once, and keeps pulling from it. If the key changed with every build, every build would be a new trust root with no relation to the last one, and nobody could follow you. So it's one key per contributor, not one per build.
OPTIONS
--force- Replace an existing key. Read REPLACING A KEY first.
All global options apply; see pkg(1).
THE KEY FILE
32 raw bytes, the Ed25519 seed, at mode 0600. That's the same format pkg sign --key reads, so the same file can sign a manifest by hand; see pkg-sign(1).
It's written to a temporary file at 0600 first, then moved into place. Without --force, an existing key is never replaced, not even by a second pkg keygen racing this one.
Treat it as the private key it is. Never in a repository, never readable by anyone else. And back it up: if you lose it, you can't publish anything more into the repositories it signed.
REPLACING A KEY
An output repository's 1.root.json names the key that created it, and only that key can publish into it again. So after pkg keygen --force, a build into an existing --out directory is refused when it tries to publish.
Build into a new directory instead, and have its consumers pin the new 1.root.json in place of the old one. There's no way around that last step, and there shouldn't be: a repository that quietly accepted a new key would be a repository anyone could take over.
OUTPUT
wrote build key /home/u/.config/pkg/build.key public key 63d3ae8671c5afd7f61344712ec1c7de88088861226b71b8ce9aa59c4013cdff
When a key already exists and you didn't pass --force:
error: build: /home/u/.config/pkg/build.key already exists; --force replaces it, and every repo signed with the old key then needs its trust anchor re-pinned by whoever consumes it
JSON
{ "ok": true, "path": "/home/u/.config/pkg/build.key", "public_key": "63d3...cdff" }
EXAMPLES
Before your first build
pkg keygen pkg build ./which --out ~/work/out
Finding the public key later
Every build prints it, next to the trust anchor it signed:
pkg --json build ./which --out ~/work/out --replace | jq -r .public_key
A second identity
The key path follows XDG_CONFIG_HOME, so a second identity is just a second configuration directory:
XDG_CONFIG_HOME=~/.config-release pkg keygen XDG_CONFIG_HOME=~/.config-release pkg build ./which --out ~/release/out
EXIT STATUS
0 when the key was written. 1 when a key already exists and --force wasn't given, when neither XDG_CONFIG_HOME nor HOME is set, or when the write fails.
ENVIRONMENT
XDG_CONFIG_HOME- The base directory for the key. Ignored unless it's an absolute path, and then $HOME/.config is used.
FILES
- $XDG_CONFIG_HOME/pkg/build.key
- The build key.
SEE ALSO
pkg(1), pkg-build(1), pkg-sign(1), pkg-repository-layout(7)
docs/components/pkg-cli.md, docs/design/trust.md