kkeyroost

Learn · Command line

The command line

Everything the keyroost app does, you can also do by typing commands in a terminal with keyroostctl. This page shows how, one task at a time.

Jump to getting started · choosing a key · naming · PINs · passkeys · codes · importing · certificates · OpenPGP · notes · resetting · scripts · troubleshooting · every command.

Getting started

First check that keyroostctl is installed and that your computer can see your key. If it isn't installed yet, see Install keyroost.

keyroostctl --version   # prints the version, e.g. keyroostctl 0.15.0
keyroostctl doctor      # checks this computer; never touches a key
keyroostctl             # shows the keys that are plugged in

With no command, keyroostctl lists your keys with a number each:

Connected devices

 1) Yubico    Work key  FIDO2 · OATH · PGP · PIV  12345678  USB·PC/SC+HID
 2) SoloKeys  Solo 2    FIDO2 · OATH              87654321  USB·PC/SC+HID

The badges show what each key can do. keyroostctl list shows the same keys in more technical detail. If a key is missing, run keyroostctl doctor: it checks the smart-card service and, on Linux, whether you have permission to use the key.

Every command explains itself. Add --help to any of them:

keyroostctl --help
keyroostctl oath --help
keyroostctl oath import --help

Tab completion saves typing, and even completes your key names. To set it up for bash (other shells are in the README):

keyroostctl completions bash > ~/.local/share/bash-completion/completions/keyroostctl

Choosing a key

With one key plugged in, there is nothing to choose: keyroost uses it. Every command starts by saying which key it is working on:

→ Work key · serial 12345678 · Yubico YubiKey OTP+FIDO+CCID 00 00

With several keys plugged in, keyroost asks which one you mean:

2 connected keys qualify (key with OATH):
   1) Work key, YubiKey 5 NFC, serial 12345678 Yubico YubiKey OTP+FIDO+CCID 00 00
   2) Backup key, YubiKey 5 NFC, serial 87654321 Yubico YubiKey OTP+FIDO+CCID 01 00
Select [1/2]:

To skip the question, say which key with -d (short for --device). It takes the number from the list, a serial number, or a name you gave the key:

keyroostctl oath list -d 2
keyroostctl oath list -d serial:12345678
keyroostctl oath list -d "Work key"

The numbers can change when you plug keys in and out; serials and names don't.

Naming your keys

A name like "Work key" is easier to remember than a serial number. You can keep the name on this computer, or store it on the key itself so it travels with the key.

keyroostctl name set "Work key"               # on this computer
keyroostctl name set "Work key" --store key   # on the key (asks for the FIDO PIN)
keyroostctl name list                         # every name, and where it lives
keyroostctl name clear "Work key"             # remove it, wherever it is

name list shows something like this:

  NAME        STORED         STATUS
  Work key    on the key     connected (#1)
  Backup key  this computer  not connected

A name stored on the key can be read by anyone who has the key, so don't put anything private in it. More in Naming your keys.

PINs and passwords

When a command needs a PIN, keyroost asks for it at a hidden prompt: nothing shows on screen while you type. It never takes a PIN typed into the command itself, because other programs on your computer could see it there.

PIN:

Each part of a key has its own PIN or password:

keyroostctl fido pin set              # passkeys: set the first PIN
keyroostctl fido pin change           # passkeys: change it
keyroostctl piv pin change            # certificates (PIV): the PIN
keyroostctl piv puk change            # certificates: the PUK, which unblocks the PIN
keyroostctl openpgp pin change        # OpenPGP: the user PIN
keyroostctl openpgp pin change --admin  # OpenPGP: the admin PIN
keyroostctl oath password set         # authenticator codes: an optional password
keyroostctl otp pin set               # Token2 key's code storage: an optional PIN

A new PIN is asked for twice, to catch typos. Too many wrong tries locks a PIN, so check how many you have left before guessing:

keyroostctl fido pin status    # e.g. "8 PIN attempt(s) remaining"
keyroostctl piv info           # includes the PIN tries left
keyroostctl openpgp info       # includes the PIN tries left
keyroostctl otp pin status

A blocked certificate PIN can be unblocked with the PUK (keyroostctl piv pin unblock), and a blocked OpenPGP user PIN with the admin PIN (keyroostctl openpgp pin unblock). For a forgotten passkey PIN or code password, the way back is a reset.

Passkeys (FIDO2)

Passkeys let you sign in to websites with your key instead of a password. Websites add them through your browser; keyroost lets you see and manage them.

keyroostctl fido info                # what the key supports (no PIN needed)
keyroostctl fido credential status   # how many passkeys it holds, and room for more
keyroostctl fido credential list     # which sites have a passkey on this key
keyroostctl fido credential delete <ID>   # remove one (asks first)

fido credential status answers in one line:

3 resident credential(s) stored, room for 22 more

The list shows a long id=… for each passkey; that is the ID to give fido credential delete. A deleted passkey can't be brought back, so make sure you have another way into that account first.

Settings and fingerprints:

keyroostctl fido config always-uv enable    # always ask for the PIN or a fingerprint
keyroostctl fido pin min-length set --length 8   # require longer PINs (one-way)
keyroostctl fido fingerprint add "Right thumb"   # on keys with a sensor
keyroostctl fido fingerprint list

The minimum PIN length can only go up; lowering it again takes a reset. More in FIDO2, Settings and Fingerprints.

Authenticator codes on a key

Your key can hold the 6-digit codes an authenticator app shows, so they live on the key instead of your phone. Most keys keep them in their OATH storage:

keyroostctl oath list                   # every code on the key
keyroostctl oath code GitHub:alice      # today's code for one account
keyroostctl oath add GitHub:alice       # asks for the setup key (hidden)
keyroostctl oath delete GitHub:alice    # asks first

oath list shows each account and its type:

GitHub:alice  [TOTP/SHA1]
Mail:demo@example.com  [TOTP/SHA1]

The setup key is the text a website shows next to its QR code. To add many codes at once, import them from your app.

Token2 keys with their own code storage use otp instead:

keyroostctl otp list
keyroostctl otp add --app GitHub --account alice
keyroostctl otp code --app GitHub --account alice

A Token2 Molto2 is a small device with a screen and 100 numbered slots:

keyroostctl molto list                    # slots in use, with their titles
keyroostctl molto seed set -s 5           # put a code in slot #5 (asks for the setup key)
keyroostctl molto title set -s 5 GitHub   # the name shown on the screen
keyroostctl molto sync --all              # set the clock on every slot

More in OATH, On-device OTP and Token2 Molto2.

Import codes from an authenticator app

If your codes live in an app like Aegis or 2FAS, you can copy them all onto your key at once. Export them from the app first; keyroost reads Aegis exports (including encrypted ones), 2FAS exports, lists of otpauth:// links, and QR code screenshots, including Google Authenticator's "Transfer accounts" QR.

See what would happen first. Nothing is written:

keyroostctl oath import --in aegis-export.json --dry-run
→ Work key · serial 12345678 · Yubico YubiKey OTP+FIDO+CCID 00 00
4 entries in aegis-export.json (Aegis) for Work key (serial 12345678) OATH:
  add       GitHub:alice
  add       Example:demo@example.com
  exists    Mail:alice                already on the key; left as is (--replace replaces it)
  skip      Steam:alice               Steam codes aren't supported
Holds 32 codes; 3 on the key; 2 will be added, 0 replaced, 1 left as is, 1 skipped.

If that looks right, run it again without --dry-run; keyroost asks once before it writes anything. If the export is encrypted, keyroost asks for its password; if your key has a password or PIN, it asks for that too.

Codes already on the key with the same name are left alone; add --replace to overwrite them. Codes the key can't store are skipped, with the reason shown. Running it again is safe.

Other keys work the same way:

keyroostctl otp import --in aegis-export.json                # a Token2 key's code storage
keyroostctl molto import --in codes.txt --slot 10            # a Molto2, from slot #10 on

On a Molto2, slots that are already in use are replaced, and the preview says so. Prefer the app? Drop the file onto the keyroost window. More in Importing codes.

Certificates and smart-card keys (PIV)

PIV turns your key into a smart card: it holds certificates for signing in to computers, VPNs or SSH servers. A key made on the card never leaves it; you can also bring a key and its certificate from a .p12/.pfx file.

keyroostctl piv info                                       # what is in each slot
keyroostctl piv key generate --slot 9a                     # make a new key in slot 9a
keyroostctl piv cert generate --slot 9a --subject "CN=Alice"   # give it a certificate
keyroostctl piv cert import --slot 9a --in alice.pem       # or use one from your company
keyroostctl piv cert export --slot 9a --out alice.pem      # save a copy of the certificate
keyroostctl piv key import --slot 9a --in alice.p12        # or a key + certificate from a .p12/.pfx file

A slot is a numbered place for one key: 9a is for signing in, 9c for signing documents, 9d for decrypting. Changing a slot needs the management key, a separate secret. If you never changed it, add --mgmt-key default.

keyroostctl piv key move --from 9a --to 82   # move a key to another slot
keyroostctl piv test --slot 9a               # check the key matches its certificate

piv test changes nothing: it asks the card to use the key and checks the answer against the certificate, then reports each check as passed, failed or skipped. Moving a key needs a key that supports it (for example YubiKey 5.7 and later). More in PIV.

OpenPGP

OpenPGP keys sign and encrypt email, files and git commits. keyroost sets up the card; everyday use usually happens in tools like GnuPG.

keyroostctl openpgp info                                   # keys, PIN tries, details
keyroostctl openpgp key import --generate --backup alice --name "Alice Example"
                                                           # new keys, saved first, then put on the card
keyroostctl openpgp key import --in alice.asc              # restore a backup onto a card
keyroostctl openpgp key expiry --set 2y --public alice.pub.asc     # two more years
keyroostctl openpgp key generate --slot sign --algorithm ed25519   # a key made on the card (no backup)
keyroostctl openpgp key import --slot decrypt --in my-key.pem      # an existing RSA key
keyroostctl openpgp sign --in contract.pdf --out contract.sig      # sign a file
keyroostctl openpgp url set https://example.com/alice.asc          # where your public key lives

There are three slots: sign, decrypt and auth (for logging in). Making or importing a key needs the admin PIN; using it needs the user PIN. A YubiKey also wants a touch. import --generate makes all three keys on this computer and writes three files before it touches the card: alice.asc (the backup, protected by a passphrase you choose), alice.pub.asc (the public key to share) and alice.rev.asc (a revocation certificate). Keep the backup and the revocation certificate offline. --algorithm takes rsa2048, rsa3072, rsa4096, nistp256, nistp384, nistp521, secp256k1 or ed25519 (Ed25519 for signing and logging in, X25519 for decrypting). Without it the type is ed25519 when the card lists it (or publishes no list), else rsa3072 when listed, else the first type the card lists; a type the card doesn't list is refused before any key is made. Keys expire after three years unless --expires says otherwise (never, 1y, 2y, 3y, 5y or YYYY-MM-DD; as in GnuPG, a date expires at midday UTC that day). key expiry signs the new date with the card, or with --backup alice.asc on this computer; it reads armored or binary files and writes them back armored. More in OpenPGP.

Notes stored on the key

Many passkey keys have a small storage area. keyroost can keep short notes there, such as where your backup key is, and SSH certificates. Anyone who has the key can read it without a PIN, so never store passwords or secrets there.

keyroostctl fido blob list                               # everything stored, numbered
keyroostctl fido blob add "Backup key is in the desk drawer"
keyroostctl fido blob show 1                             # one entry in full
keyroostctl fido blob edit 1 "Backup key is at the office"
keyroostctl fido blob export 1 --out note.bin            # save an entry to a file
[0] 64 bytes  key name  "Work key"
[1] 52 bytes  note      Backup key is in the desk drawer

Capacity: 116 of 1024 bytes used, 908 free

For an SSH key made on the key, keyroost can save its certificate where SSH expects it:

keyroostctl fido ssh list
keyroostctl fido ssh export --out id_ed25519_sk-cert.pub

More in Storage.

Resetting

A reset puts one part of the key back to factory condition. It erases everything in that part, and can't be undone. It is also the way back from a forgotten PIN or password.

keyroostctl fido reset      # all passkeys and the FIDO PIN (also notes and an on-key name)
keyroostctl oath reset      # all authenticator codes and the code password
keyroostctl piv reset       # all certificates, PIV keys and PINs
keyroostctl openpgp reset   # all OpenPGP keys; PINs back to 123456 / 12345678
keyroostctl otp reset       # all codes in a Token2 key's code storage
keyroostctl molto reset     # all 100 slots of a Molto2
keyroostctl factory-reset   # every part of the key at once

Before anything is erased, keyroost names the key and asks:

wipe the OATH applet on Work key (serial 12345678)? [y/N]

Anything other than y cancels. factory-reset asks you to type the word reset instead. A passkey reset over USB also asks you to unplug the key, plug it back in, and touch it; most keys only accept a reset just after they are plugged in. Accounts that used the erased passkeys or codes need to be set up again, so sign in with a backup first. More in Resetting.

Using keyroostctl in scripts

A script has no one to answer questions, so keyroost refuses to guess. Tell it everything up front:

keyroostctl fido credential status -d "Work key" --pin env:KR_PIN
pass show keys/fido-pin | keyroostctl fido credential status --pin stdin
keyroostctl oath import -d "Work key" --in codes.txt --yes
keyroostctl fido pin status --json
{
  "pin_retries": 8
}

keyroostctl exits with 0 when the command worked, 1 when it failed, and 2 when the command itself was mistyped (an unknown command or flag). Error messages go to standard error, results to standard output.

Troubleshooting

Start with keyroostctl doctor. It only checks this computer and is safe to run any time:

keyroost doctor — environment check

✓ PC/SC service reachable
✓ 1 reader(s):
    Yubico YubiKey OTP+FIDO+CCID 00 00

✓ YubiKey OTP+FIDO+CCID (/dev/hidraw1) is accessible

✓ udev rules installed (/etc/udev/rules.d/70-keyroost-fido.rules)

✓ /home/alice/.config/keyroost/keys.json is owner-only

A ✗ line says what is wrong; a – line is information. Common messages:

Still stuck? --debug prints every message sent to and from the key. Look it over before posting it publicly, then share it in an issue:

keyroostctl --debug oath list

Every command

Each command with its one-line description, taken from keyroostctl --help. Add --help to any command for its options.

General

CommandWhat it does
keyroostctl listList connected keys: smart-card (PC/SC) readers and FIDO USB (HID) devices
keyroostctl doctorDiagnose the local environment: PC/SC service, readers, FIDO HID access, udev rules, registry permissions. Read-only, touches no key
keyroostctl factory-resetFactory-reset EVERY resettable applet on the selected key: OATH, OpenPGP, Token2 OTP, PIV, then FIDO2. Irreversible: asks for a typed confirmation (--yes to skip)
keyroostctl completionsPrint shell completions to stdout
keyroostctl manpageWrite man pages (keyroostctl.1 + keyroostctl-<group>.1) into a directory

name

Name security keys: on this computer (keys.json) or on the key itself, where the name is visible to anyone who has the key

CommandWhat it does
keyroostctl name setName the selected key, or rename it. Renaming keeps the name where it is unless --store says otherwise
keyroostctl name clearRemove a name wherever it is stored: NAME, or the key selected with -d
keyroostctl name listList the names this computer knows, where each lives, and which keys are connected

fido

Manage FIDO2: passkeys, PIN, fingerprints, settings, the large-blob store, SSH certificates, and reset

CommandWhat it does
keyroostctl fido infoShow the key's FIDO2 capabilities and settings
keyroostctl fido resetFactory-reset FIDO2: wipe every credential (passkeys and security-key sign-ins) and the PIN. Irreversible: asks first (--yes to skip)
keyroostctl fido pinSet, change or check the FIDO2 PIN, and the PIN rules (minimum length, forced change)
keyroostctl fido pin statusShow how many PIN attempts are left
keyroostctl fido pin setSet the initial PIN on an authenticator that doesn't have one yet. The PIN comes from an environment variable, stdin or, with neither, a hidden prompt (asked twice) — never argv
keyroostctl fido pin changeChange the existing PIN. Each PIN comes from an environment variable, stdin (the current PIN on the first line, the new one on the second) or, with neither, a hidden prompt — never argv
keyroostctl fido pin min-lengthRaise the minimum PIN length
keyroostctl fido pin min-length setRaise the minimum PIN length. One-way: asks first (--yes to skip)
keyroostctl fido pin force-changeForce a PIN change on next use, without changing the minimum length
keyroostctl fido credentialList, inspect or delete the credentials (passkeys and security-key sign-ins) on the key
keyroostctl fido credential listList every resident credential on the authenticator, grouped by RP
keyroostctl fido credential deleteDelete one credential (passkey or security-key sign-in) by its hex credential ID. Irreversible: asks first (--yes to skip)
keyroostctl fido credential statusShow how many passkeys the key holds and how many more fit. Needs the PIN
keyroostctl fido fingerprintList, add, rename or delete enrolled fingerprints
keyroostctl fido fingerprint listList enrolled fingerprints (template id + name)
keyroostctl fido fingerprint addEnroll a new fingerprint. Touch the sensor repeatedly when prompted until capture completes
keyroostctl fido fingerprint renameRename an enrolled fingerprint by its hex template ID (from fido fingerprint list)
keyroostctl fido fingerprint deleteDelete an enrolled fingerprint by its hex template ID (from fido fingerprint list). Irreversible: asks first (--yes to skip)
keyroostctl fido configKey-wide FIDO2 switches: always-uv and enterprise attestation
keyroostctl fido config always-uvAlways-uv (always user verification): when on, every sign-in needs the PIN or a fingerprint, not only a touch
keyroostctl fido config always-uv enableTurn on "always require user verification" (alwaysUv). Does nothing if it is already on
keyroostctl fido config always-uv disableTurn off "always require user verification" (alwaysUv). Does nothing if it is already off
keyroostctl fido config attestationEnterprise attestation: lets a managed deployment's sign-in prove which exact key is used
keyroostctl fido config attestation enableEnable enterprise attestation. One-way: asks first (--yes to skip)
keyroostctl fido blobRead and write the key's large-blob store (notes, SSH certificates)
keyroostctl fido blob listList every entry: index, size, type (note, key name, SSH certificate or opaque), and a short preview
keyroostctl fido blob showShow one entry in full by its index (from fido blob list)
keyroostctl fido blob addAppend a keyroost text note
keyroostctl fido blob editReplace the text of an existing keyroost note by its index
keyroostctl fido blob deleteDelete a single entry by its index. Irreversible: asks first (--yes to skip)
keyroostctl fido blob exportSave one entry's bytes to a file (read-only; no PIN needed)
keyroostctl fido blob clearErase the ENTIRE large-blob array, including any RP-owned entries. Irreversible: asks first (--yes to skip)
keyroostctl fido sshList SSH credentials and export their certificates
keyroostctl fido ssh listList resident SSH credentials (ssh:* RP IDs) and whether each has a certificate stored in its largeBlob
keyroostctl fido ssh exportSave an SSH credential's certificate from its largeBlob to a -cert.pub file

oath

Show codes and manage OATH (TOTP/HOTP) accounts on a security key

CommandWhat it does
keyroostctl oath listList the credentials stored on the key
keyroostctl oath codePrint the current TOTP code for a credential
keyroostctl oath addAdd (provision) a TOTP or HOTP credential
keyroostctl oath importAdd every code in an authenticator export to this key's OATH storage
keyroostctl oath deleteDelete a credential by name. Irreversible: asks first (--yes to skip)
keyroostctl oath passwordSet or clear the OATH applet's access password
keyroostctl oath password setSet (or replace) the applet password — never from argv
keyroostctl oath password clearRemove the applet password. The current password comes from --password env:NAME / --password stdin or, with neither, a hidden prompt
keyroostctl oath resetFactory-reset the OATH applet: wipe ALL authenticator credentials and clear the access password. Irreversible: asks first (--yes to skip)

otp

Manage the OTP entries stored on a Token2 T2F2 / PIN+ FIDO key

CommandWhat it does
keyroostctl otp listList the OTP entries stored on the key, with their live codes where the device returns them (TOTP without button-press)
keyroostctl otp codePrint the current code for one entry, identified by app and account. A button-required entry will prompt for a touch
keyroostctl otp addAdd (or overwrite) an OTP entry
keyroostctl otp importAdd every code in an authenticator export to this key's OTP storage
keyroostctl otp deleteDelete one OTP entry by app and account. Irreversible: asks first (--yes to skip)
keyroostctl otp resetErase every OTP entry on the key. Irreversible: asks first (--yes to skip)
keyroostctl otp serialRead the device serial number (over USB, or NFC where the model allows)
keyroostctl otp buttonSet or clear the HOTP code the key types when its button is pressed
keyroostctl otp button setConfigure the single HOTP-on-button keystroke slot, replacing any seed already there. Irreversible: asks first (--yes to skip)
keyroostctl otp button clearClear the HOTP-on-button keystroke slot. Irreversible: asks first (--yes to skip)
keyroostctl otp infoRead and print the device configuration (interface states, capabilities)
keyroostctl otp interfaceChoose which USB interfaces the key offers (FIDO, keyboard, CCID). Irreversible: asks for a typed confirmation (--yes to skip)
keyroostctl otp pinSet, change, clear, check or verify the OTP PIN
keyroostctl otp pin setSet an OTP PIN on a currently-unprotected key
keyroostctl otp pin changeChange the OTP PIN: current first, then new (stdin lines 1 and 2, env vars, or the prompt)
keyroostctl otp pin clearRemove the OTP PIN. Needs the current OTP PIN: via env, stdin or, with neither, a hidden prompt
keyroostctl otp pin statusReport OTP-PIN status (R3.4+ keys): whether a PIN is set and retries left
keyroostctl otp pin verifyVerify the OTP PIN, opening the read window for this connection (mostly for testing; otp list takes --pin directly). The PIN comes from --pin env:NAME or stdin or, with neither, a hidden prompt
keyroostctl otp fingerprintCheck, enable or disable fingerprint unlock for the OTP entries
keyroostctl otp fingerprint statusReport whether the key supports fingerprint-protected OTP and whether it is on
keyroostctl otp fingerprint enableEnable fingerprint protection for OTP. Needs the current OTP PIN. After this, codes can be unlocked by a fingerprint touch as well as the PIN
keyroostctl otp fingerprint disableDisable fingerprint protection for OTP. Needs the current OTP PIN

openpgp

Manage the OpenPGP card applet: info, keys, sign, decrypt, PINs, cardholder details, and reset

CommandWhat it does
keyroostctl openpgp infoShow card status: AID/serial, key algorithms and fingerprints, PIN retry counters, and the signature counter. No PIN or touch required
keyroostctl openpgp pinCheck, change or unblock the user PIN (PW1) or the admin PIN (PW3)
keyroostctl openpgp pin verifyCheck a PIN without changing anything (the user PIN, or the admin PIN with --admin)
keyroostctl openpgp pin changeChange the user PIN, or the admin PIN with --admin
keyroostctl openpgp pin unblockSet a new user PIN using the admin PIN (after too many wrong user PINs)
keyroostctl openpgp keyGenerate, import or show the card's keys, change when they expire, and list the algorithms it supports
keyroostctl openpgp key generateGenerate a fresh key pair in a slot, replacing any key already there. Irreversible: asks first (--yes to skip)
keyroostctl openpgp key importPut a new key set, a backup or an RSA key file onto the card, replacing the keys already there. Irreversible: asks first (--yes to skip)
keyroostctl openpgp key expiryChange when a key set expires and update its public key file
keyroostctl openpgp key showRead the public key from a slot (read-only; no PIN). RSA keys print modulus and exponent, ECC keys the public point, in hex
keyroostctl openpgp key algorithmsList the key algorithms this card reports accepting per slot (read-only; no PIN). Cards that don't publish the list accept any attempt and answer with an error if they can't
keyroostctl openpgp nameSet the cardholder name stored on the card
keyroostctl openpgp name setSet the cardholder name. Needs the admin PIN (PW3)
keyroostctl openpgp urlSet the public-key URL stored on the card
keyroostctl openpgp url setSet the public-key URL. Needs the admin PIN (PW3)
keyroostctl openpgp signSign a file with the key in the signature slot
keyroostctl openpgp decryptDecrypt a file with the key in the decryption slot
keyroostctl openpgp authenticateSign a challenge with the key in the authentication slot (client or SSH login)
keyroostctl openpgp resetFactory-reset the OpenPGP applet: wipe ALL key slots and restore default PINs (PW1 123456, PW3 12345678). Irreversible: asks first (--yes to skip)

piv

Manage the PIV (smart card) applet: info, PIN/PUK, management key, keys, and certificates

CommandWhat it does
keyroostctl piv infoShow PIV status: version, serial, PIN retries, and what each slot holds (certificate, key), including retired slots in use. No PIN or touch required
keyroostctl piv pinChange the PIV PIN, or unblock it with the PUK
keyroostctl piv pin changeChange the PIV PIN. Each PIN comes from an environment variable, stdin (the current PIN on the first line, the new one on the second) or, with neither, a hidden prompt
keyroostctl piv pin unblockUnblock a blocked PIN using the PUK, setting a new PIN
keyroostctl piv pukChange the PUK (the code that unblocks the PIN)
keyroostctl piv puk changeChange the PUK (PIN Unblocking Key). Each PUK comes from an environment variable, stdin (the current PUK on the first line, the new one on the second) or, with neither, a hidden prompt
keyroostctl piv retriesSet how many wrong PIN and PUK entries are allowed
keyroostctl piv retries setSet how many wrong PIN and PUK entries are allowed. Irreversible: asks first (--yes to skip)
keyroostctl piv mgmt-keyChange the management key (mgmt-key: the key that authorizes changes to keys and certificates)
keyroostctl piv mgmt-key changeChange the card-management (9B) key. Both keys are hex; from stdin, the current key comes on the first line and the new one on the second
keyroostctl piv keyGenerate, import, delete or move the private keys in PIV slots
keyroostctl piv key generateGenerate a new key pair in a slot, replacing any key already there, and print its public key (PEM). Irreversible: asks first (--yes to skip)
keyroostctl piv key importImport a private key and its certificate from a .p12/.pfx file into a slot, replacing what the slot holds. Irreversible: asks first (--yes to skip)
keyroostctl piv key deleteDelete a slot's private key; the slot's certificate is left in place. Needs the management key. Irreversible: asks first (--yes to skip)
keyroostctl piv key moveMove a slot's private key to another slot, without it leaving the card
keyroostctl piv certImport, export, delete, request or generate the certificates in PIV slots
keyroostctl piv cert importImport a DER or PEM X.509 certificate into a slot, replacing any certificate already there. Irreversible: asks first (--yes to skip)
keyroostctl piv cert exportExport a slot's certificate as PEM (default) or DER, to a file or stdout. No PIN required
keyroostctl piv cert requestCreate a PKCS#10 certificate signing request for the key in a slot, signed on the card (PEM to stdout or --out). Hand the result to a CA; import the certificate it issues with piv cert import
keyroostctl piv cert generateCreate a self-signed certificate for the key in a slot and store it there, replacing any certificate already there. Irreversible: asks first (--yes to skip)
keyroostctl piv cert deleteDelete a slot's certificate; the slot's private key is left in place. Needs the management key. Irreversible: asks first (--yes to skip)
keyroostctl piv chuidWrite a new CHUID (Card Holder Unique Identifier, the card's identity record)
keyroostctl piv chuid generateWrite a fresh, randomly-generated CHUID (Card Holder Unique Identifier). Needs the management key
keyroostctl piv testTest a slot's private key end to end against the slot certificate's public key. Read-only — nothing on the card changes
keyroostctl piv resetReset the PIV application to factory defaults: wipe all keys, certificates and PINs. Irreversible: asks first (--yes to skip)

molto

Token2 Molto2 / Molto2v2 programmable TOTP token

CommandWhat it does
keyroostctl molto infoPrint device serial number and on-device UTC time
keyroostctl molto listList the 100 slots: occupancy, title, TOTP config. Titles and occupancy are readable by anyone holding the token — no customer key is needed (or used)
keyroostctl molto seedWrite a slot's TOTP seed
keyroostctl molto seed setWrite a TOTP seed to a slot, replacing any seed already there. Irreversible: asks first (--yes to skip)
keyroostctl molto titleShow a slot's title (and whether it holds a seed), or write one with molto title set
keyroostctl molto title setWrite a slot title (1..=12 ASCII characters), replacing the one there
keyroostctl molto deleteDelete one slot's seed. Irreversible: asks first (--yes to skip)
keyroostctl molto configSet a slot's TOTP configuration
keyroostctl molto config setSet a slot's TOTP configuration (and seed the clock with the host's UTC time)
keyroostctl molto syncPush the host's current UTC time to one slot (or all slots)
keyroostctl molto customer-keyChange the Molto2's customer key
keyroostctl molto customer-key changeReplace the Molto2's customer key. Irreversible: asks first (--yes to skip)
keyroostctl molto importImport an otpauth:// URI to a slot, or every entry of an export file to consecutive slots: writes seed, title, and config, replacing what the slots held. Irreversible: asks first (--yes to skip)
keyroostctl molto resetFactory-reset the device: wipe all slots and restore the default customer key. Irreversible: asks first (--yes to skip)

prog

Token2 2nd-generation single-profile programmable TOTP token. Uses the token's fixed device key; no customer key is needed

CommandWhat it does
keyroostctl prog infoPrint device serial number and on-device UTC time. No auth needed
keyroostctl prog seedWrite the token's TOTP seed
keyroostctl prog seed setWrite the TOTP seed, replacing the one on the token. Irreversible: asks first (--yes to skip)
keyroostctl prog configSet the token's TOTP configuration
keyroostctl prog config setSet the device configuration and seed the clock with the host's UTC time