Home / Alt manpages / age-keygen(1)

  • age-keygen(1)
  • User command
  • linux

Generate and Verify an age Identity with age-keygen

You will finish with a native age identity file, its public recipient, and a simple check that the two belong together. The examples use age-keygen 1.1.1 from Ubuntu package age 1.1.1-1ubuntu0.24.04.3+esm1.

Allow about ten minutes. You need a shell and the installed age package. No elevated privileges are normally required. The identity file contains a private key, so treat every command that reads or copies it as security-sensitive.

1. Confirm the installed command

Check the executable and version before relying on examples. This is an ordinary, read-only check:

$ command -v age-keygen
/usr/bin/age-keygen
$ age-keygen --version
1.1.1
$ dpkg-query -W -f='${Package} ${Version}\n' age
age 1.1.1-1ubuntu0.24.04.3+esm1

The installed 1.1.1 interface has -o, -y and --version. Current upstream documentation also describes a newer -pq option for post-quantum hybrid keys, but that option is not present in this local manpage or release. Do not paste newer examples into this installation without first checking its own help.

Checkpoint

If your version is not 1.1.1, run age-keygen --help and compare the available options before continuing.

2. Generate the identity into a new file

Choose a path that is not already in use, then let age-keygen create the file:

$ install_dir="$HOME/.config/age"
$ mkdir -p "$install_dir"
$ umask 077
$ age-keygen -o "$install_dir/keys.txt"
Public key: age1<generated-recipient>

The public key is safe to share with someone who will encrypt data for you. The file itself contains the secret identity and must not be shared. With this command, age-keygen writes the identity to the file and prints the corresponding public key to standard error. The exact recipient is generated randomly and will differ on every run.

The umask 077 line limits permissions for files created by subsequent commands in this shell. The program also creates a normal output file with mode 0600 on the tested installation. Check the result without printing the secret:

$ stat -c '%a %n' "$HOME/.config/age/keys.txt"
600 /home/YOUR_USER/.config/age/keys.txt
$ sed -n '1,2p' "$HOME/.config/age/keys.txt"
# created: 2026-09-22T10:00:00+01:00
# public key: age1<generated-recipient>

The timestamp and public key are comments. The third line is the secret key, so do not use cat in a terminal recording, support ticket or log. A backup of the identity is also a backup of the ability to decrypt data addressed to its recipient.

3. Avoid an accidental overwrite

age-keygen -o refuses to replace an existing path. This is a useful safety boundary when a script is rerun:

$ age-keygen -o "$HOME/.config/age/keys.txt"
age-keygen: error: failed to open output file "/home/YOUR_USER/.config/age/keys.txt": file exists

The exact path and diagnostic wording can vary, but the command exits non-zero and the old file remains in place. Do not solve this by deleting the identity until you have checked where it is used and made a secure backup. There is no age-keygen undo operation for a deleted key.

If you genuinely need a second identity, use a new filename such as keys-2026-09.txt, then record which recipient belongs to which purpose. Do not rename or replace a key merely because its public key is inconvenient to type.

4. Derive and verify the recipient

Use -y to read the identity and emit its matching recipient without comments:

$ age-keygen -y "$HOME/.config/age/keys.txt"
age1<generated-recipient>

Compare this output with the public key in the file. A small shell check makes the verification explicit while keeping the secret line out of the output:

$ expected=$(sed -n 's/^# public key: //p' "$HOME/.config/age/keys.txt")
$ actual=$(age-keygen -y "$HOME/.config/age/keys.txt")
$ test "$expected" = "$actual" && printf '%s\n' 'recipient matches identity'
recipient matches identity

That comparison checks the identity's own comment against the value calculated from its secret key. If it fails, stop and inspect the file path and contents with care. Do not edit the secret line by hand. Generate a separate identity if the file is damaged, then recover encrypted data using a known-good backup or the correct original key.

5. Use standard input when a file is not convenient

-y accepts an identity from standard input when no input path is supplied. This is useful for a controlled pipeline, but it makes shell history, process supervision and logs part of your secret-handling review:

$ age-keygen -y < "$HOME/.config/age/keys.txt"
age1<generated-recipient>

Prefer the explicit filename for routine administration because it is easier to audit. Never place the secret identity directly in a command argument, URL, shell variable exported to child processes, or issue report.

6. Pass the recipient to age

The derived recipient is the value an encrypting user needs. For example, save only the public value as a recipients file:

$ age-keygen -y "$HOME/.config/age/keys.txt" > "$HOME/.config/age/recipients.txt"
$ stat -c '%a %n' "$HOME/.config/age/recipients.txt"
644 /home/YOUR_USER/.config/age/recipients.txt

A recipients file contains no private key and can be shared with the people or systems that encrypt for you. If it is wrong, regenerate it from the authoritative identity rather than editing the key material. The related age(1) command can consume it with --recipients-file; encryption and decryption are separate operations from key generation.

Done means

  • age-keygen --version was checked and the examples match the installed interface.
  • A new identity was written to a deliberate path with mode 0600.
  • The secret line was kept out of logs, tickets and shared shell output.
  • age-keygen -y produced the recipient expected by the identity file.
  • The recipient can be shared, while the identity file remains protected and backed up securely.
  • No existing identity was overwritten or deleted.