Manage LUKS2 Tokens with cryptsetup token
cryptsetup token manages the metadata that tells an activation mechanism, such as a TPM or keyring, how to use a keyslot. It lets you inspect, export, import, bind and remove that metadata. The examples use cryptsetup-bin 2:2.7.0-1ubuntu4.2, providing cryptsetup 2.7.0. Allow about fifteen minutes, and work with a LUKS2 test volume or one whose header backup you have already verified.
The route
Jump straight to the step you need, or tick off Done means at the end.
Most commands below read or rewrite the LUKS2 header, so they normally need elevated privileges. Replace /dev/mapper/example with the underlying LUKS2 device, not a mounted filesystem or an arbitrary path. A token is metadata used by an activation mechanism: it is not a passphrase and it is not itself a keyslot.
1. Check the installed contract
Start with read-only checks. This confirms the program and package version without opening or changing a volume:
$ cryptsetup --version
cryptsetup 2.7.0
$ dpkg-query -W -f='${Package} ${Version}\n' cryptsetup-bin
cryptsetup-bin 2:2.7.0-1ubuntu4.2
$ cryptsetup token --help
The supported actions on this installation are add, remove, import, export and unassign, and the command only supports LUKS2. Check the format before going further:
$ sudo cryptsetup isLuks /dev/mapper/example
$ sudo cryptsetup luksDump /dev/mapper/example | sed -n '1,12p'
An exit status of zero from isLuks confirms a LUKS header, but not that it is LUKS2. The luksDump output should identify Version: 2. Stop if this is a LUKS1 volume.
2. Export a token before changing anything
Export is the safest way to see the JSON for one token. List the token section first and pick an ID that actually exists:
$ sudo cryptsetup luksDump /dev/mapper/example
...
Tokens:
0: systemd-tpm2
Keyslots:
The token type and output are host-specific: do not assume token 0 exists. Once you have an ID, export it to standard output:
$ sudo cryptsetup token export --token-id 0 --json-file=- /dev/mapper/example
{
"type":"systemd-tpm2",
"keyslots":["0"],
"tpm2-pcrs":"..."
}
Those fields are illustrative, not a template to paste back into a header: your token may come from a different plugin with different fields. To preserve the exact JSON for review, use a root-readable file in a protected directory:
$ sudo install -d -m 0700 /root/luks-token-backups
$ sudo cryptsetup token export --token-id 0 \
--json-file=/root/luks-token-backups/token-0.json /dev/mapper/example
$ sudo cryptsetup token export --token-id 0 --json-file=- /dev/mapper/example \
| diff -u /root/luks-token-backups/token-0.json -
Checkpoint
The final command should produce no diff and return zero. Treat exported token JSON as security-sensitive metadata: it can reveal how automatic activation is configured, and an imported token can alter how a volume is activated.
3. Understand the binding before editing it
A token can be assigned to one keyslot, several keyslots, or none. The keyslot is where encrypted volume-key material lives; the token is a separate JSON object that tells a handler how to use that keyslot. Use luksDump to compare the Tokens and Keyslots sections before deciding what to change.
For a keyring token, add requires --key-description. Without --key-slot, the new token is assigned to all active keyslots, a default that is easy to miss. Specify a slot when the token must be tied to one particular slot.
Adding a token changes the LUKS2 header. Make a header backup first, and verify where it landed:
$ sudo cryptsetup luksHeaderBackup /dev/mapper/example \
--header-backup-file /root/luks-token-backups/example-header.img
$ sudo test -s /root/luks-token-backups/example-header.img && \
echo 'header backup exists'
header backup exists
Do not put that backup in an unprotected shared directory: it contains keyslot metadata and is part of the recovery material for the volume.
4. Add or unassign a keyring token
Adding a keyring token associates a keyring description with the selected keyslot. The passphrase itself must already be stored in the user or user-session keyring under that description; this command does not ask for, create or print it.
$ sudo cryptsetup token add \
--key-description='example-volume-passphrase' \
--key-slot=0 \
/dev/mapper/example
If it succeeds, inspect the token section and record the ID cryptsetup chose. With no --token-id, the first unused token ID is selected:
$ sudo cryptsetup luksDump /dev/mapper/example | sed -n '/Tokens:/,/Keyslots:/p'
To keep the token but remove its relationship with keyslot 0, both identifiers are mandatory:
$ sudo cryptsetup token unassign \
--token-id 1 --key-slot 0 /dev/mapper/example
Replace 1 with the ID you recorded. Unassigning is not removing: it drops one binding while leaving the token JSON in the header. Re-run luksDump to confirm the binding changed.
5. Import, replace or remove token JSON
Import accepts valid token JSON from a file or standard input. Prefer a file whose contents came from a trusted export or the documentation for the installed token handler:
$ sudo cryptsetup token import \
--json-file=/root/luks-token-backups/token-0.json \
--key-slot=0 /dev/mapper/example
If you specify --token-id and that ID is already occupied, import refuses to replace it unless you also specify --token-replace. Replacement is destructive to the old JSON at that ID: export it first, then use the explicit ID only once you have checked the new JSON.
$ sudo cryptsetup token import --token-id 1 --token-replace \
--json-file=/root/luks-token-backups/reviewed-token.json \
--key-slot=0 /dev/mapper/example
Warning
There is no undo flag for an import or replacement. To recover, restore the verified header backup, or import the previously exported JSON with the correct ID and binding. Do not restore a header while the volume is actively being changed.
Remove is broader than its name suggests: it removes any token type at the selected ID, not just a keyring token.
$ sudo cryptsetup token remove --token-id 1 /dev/mapper/example
$ sudo cryptsetup luksDump /dev/mapper/example | sed -n '/Tokens:/,/Keyslots:/p'
Check the ID carefully before pressing Enter. Removing a token can break automatic activation even though passphrase-based activation still works. If you need to remove a token from one keyslot but keep it for another, use unassign instead.
Common failure traps
- Wrong format: the token actions are LUKS2 only. Confirm the version instead of trying options until one happens to work.
- Wrong object: use the LUKS device or detached-header arrangement documented for your volume. A filesystem path and a mapper name are not interchangeable.
- Wrong default: omitting
--key-slotwhen adding or importing binds the token to all active keyslots; omitting--token-idselects the first unused ID. - Plugin confusion:
--disable-external-tokensstops external token handlers loading. Do not use it while testing a token that depends on a plugin. - Lock bypass:
--disable-locksdisables metadata locking and is meant only for restricted environments where/runcannot be used, not a general fix for a lock error.
Done means
- Format confirmed: the target is LUKS2 and the installed cryptsetup version is known.
- Backups secured: the original token JSON and a verified LUKS2 header backup are stored securely.
- Every change checked: each changed token ID and keyslot binding was verified with
luksDump. - Imports trusted: any import used trusted, valid JSON, and any replacement was preceded by an export.
- Activation tested: automatic activation was tested separately from ordinary passphrase activation.