Add an authenticator seed, and read why one cannot make a code.
Store a login's authenticator seed from the CLI or Skarbiec Desktop; Skarbiec checks it computes a code before storing it, and an invalid stored seed carries the reason it failed.
Add a seed from the CLI#
skarbiec totp set <item-id> stores the seed of one login or identity item. The seed goes on standard input, never in an argument: either the Base32 secret the provider shows beside its QR code, or the whole otpauth://totp/ address the QR code encodes. Only the totp_secret field changes; the item's other fields, tags and recipients stay as they were.
Before anything is stored the seed must compute a code the way every reader computes one (SHA1, 6 digits, a 30-second period, as src/core/totp/mod.rs declares). The answer is {ok, item, revision, current_code}: type current_code where the provider asks you to confirm the authenticator. The write is journalled as totp-seed-set with the item and its new revision, never the seed.
Refusals, word for word: standard input held no seed; send the Base32 secret or the otpauth:// address · the address is not otpauth://totp/; only time-based codes are computed here · the otpauth:// address has no parameters, so it carries no secret · the otpauth:// address states <key> twice · the address asks for <algorithm>; codes here are computed with SHA1 · the address asks for <n> digits; codes here have 6 · the address asks for a <n>-second period; codes here change every 30 seconds · the otpauth:// address carries no secret parameter · the seed is not Base32 (letters A to Z and digits 2 to 7); nothing was stored · a <kind> item has no totp_secret field, so nothing was stored in <id>; a login or an identity holds the seed. An item under the credential lifecycle is refused with use the item's controlling lifecycle instead of direct owner store an authenticator seed in.
pbpaste | skarbiec totp set google-admin
skarbiec totp seed google-adminAdd a seed in Skarbiec Desktop#
Select the login or identity item; its inspector shows Set up authenticator. Paste the secret or the otpauth:// address into Authenticator secret or otpauth:// address and choose Set up authenticator, or choose Read the QR code from an image… and pick the screenshot or downloaded image of the provider's QR code: the address is read from the image and never shown. Desktop stores it through the same operation as skarbiec totp set, so the same check and the same refusals apply, and it shows the current code with Type this code where the provider asks to confirm the authenticator.
A Google account behind a Brama subscription whose setup key is shown only inside a signed-in session is enrolled through Weles instead, with brama subscription authenticator enrol <PROVIDER> --subscription-id <ID> --reason <REASON>; Weles reads the key, proves the first code and stores it in the login item.
The check is the code itself#
skarbiec totp seed [<item-id>] validates each item's totp_secret through the same Base32-to-six-digit-code path skarbiec totp code uses. It never prints the seed or the computed code, and a non-empty field is not taken for a working second factor.
Every row carries seed_state and a description; an invalid seed also carries reason, and a state the vault can name the next action for carries repair. skarbiec totp code prints the same reason beside has_seed, which is true only for a present seed.
Why a seed is invalid#
the seed is not padded RFC 4648 Base32 text: the field holds characters outside the Base32 alphabet, or padding that RFC 4648 does not allow where it stands.
the seed is not RFC 4648 Base32: the text passed the shape check but does not decode as Base32.
the seed decodes to no bytes: the text is valid Base32 of nothing, so there is no key to compute a code from.
the current time step cannot be read from the system clock: <cause>: the seed is usable, but the machine's clock could not give the time step a code is computed for; the cause is the clock's own error.
The other states#
present: the field has the supported Base32 shape and a six-digit code was computed. It does not prove the account still has that seed enrolled.
placeholder: the field holds an uppercase underscore-delimited placeholder such as WELES_ADMIN_GOOGLE_TOTP_SECRET; replace it with a real account's seed before enrolling. The shared credential resolver refuses placeholders too, so route verify, the doctor credentials check and grant capability never call one usable.
declared_empty: the item kind declares totp_secret but stores no text in it. field_absent: the item kind declares no totp_secret, so the item must be stored as a login to carry one. unreadable: the item could not be opened, and the row carries the read error instead of a guessed state.
skarbiec totp seed google-admin
skarbiec totp code google-admin