otp
Makes the short code a site asks for after the password, from the key stored
on the record, and puts it on the clipboard the way
get hands over a password.
sefy otp <REFERENCE> [OPTIONS]| Option | Meaning |
|---|---|
--set |
Store a key on the record first. It is asked for and never echoed. |
--key-env <VAR> |
Read the key to store from this variable instead of asking. Implies --set. |
--qr |
Draw the key as a QR code for an authenticator app on a phone. |
--stdout |
Print the code instead of copying it. |
--clear-after <SECONDS> |
Clear the clipboard again after this long. Default 45; 0 leaves it. |
$ sefy otp githubcopied the one-time code of "github" to the clipboard; valid for 19s, clearing in 45sclipboard cleared“Valid for” is how long the code has before the next one replaces it. A site usually accepts the previous code for a few seconds more, but pasting one with two seconds left is a race worth not running: wait for the next.
Turning on two-factor sign-in
Section titled “Turning on two-factor sign-in”The site shows a QR code and, beside it, a text key for when scanning is not an
option. Either one is what --set takes: the otpauth:// link inside the QR
code, or the text key, spaces and all.
$ sefy otp github --setSetup key or otpauth:// link:stored the one-time password key of "github"copied the one-time code of "github" to the clipboard; valid for 24s, clearing in 45sThe first code follows straight away, because that is what the site asks for next — proof the key was taken. Storing and answering are one command so the key is in the vault before the site switches two-factor sign-in on.
What is not a key is refused on the way in, while the setup page is still open and the key can still be fetched again:
$ sefy otp github --setSetup key or otpauth:// link:error: not a one-time password key: the key is not base32 (letters A-Z and digits 2-7)The message never quotes what was typed. A counter-based (HOTP) link is refused by name: sefy makes time-based codes only.
How the key is kept
Section titled “How the key is kept”In the record’s totp field, secret, as it came:
- A link is kept word for word. Its issuer, account, number of digits, period and hash are the site’s own, and codes are made with exactly those.
- A text key loses the spaces and dashes it was printed with and is upper-cased, so the same key is always stored the same way. It means what every site means by one: six digits, thirty seconds, SHA-1.
show hides the field and points here. The key itself
can still be taken out with sefy get <REFERENCE> --field totp — to move it to
another tool, for instance.
--set on a record that already has a key replaces it, and the one it replaces
stays in the record’s history. A site that was
switched to a new key and never confirmed it still takes the old one:
sefy restore <REFERENCE> <VERSION> --field totp brings it back.
Onto a phone
Section titled “Onto a phone”$ sefy otp github --qr▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀…scan it with the authenticator app, then press Enter to clear the screenclearedThe picture is the key — anyone who can see it or photograph it has what the
phone has. So it is drawn only when both ends are a terminal, and the screen and
the scrollback are wiped as soon as Enter is pressed. Its colours are set
explicitly, so it reads the same on a light and a dark terminal; a terminal
that cannot draw colour (NO_COLOR set, or a very old console) gets a refusal
rather than an inverted code a phone may not read.
A key stored as text has no issuer or account of its own; the QR code names it
after the record’s title and its login field, which is what the phone will
show.