# Setting up `derivepassphrase vault` for three accounts, with a master passphrase ## The scenario In this tutorial, we will setup `derivepassphrase` for three services, using a master passphrase and the standard `vault` passphrase derivation scheme. We will assume the following three services with the following passphrase policies:
--lower n, for any n > 0.
Upper case letters (`--upper`), digits (`--number`), symbols (`--symbol`), spaces (`--space`) and dashes (`--dash`) work similarly.
- A policy "spaces *forbidden*" translates to the option `--space 0`.
Again, other character classes behave similarly.
- A policy "no character may appear n times (or more) in a row" translates to the option --repeat (n − 1), for any n > 1.
In particular, `--repeat 1` means no character may be immediately repeated.
(See the mnemonic below.)
* A policy "between n and m characters long" translates to --length k, for any choice of k which satisfies n ≤ k ≤ m.
(`derivepassphrase` does not explicitly choose k for you.)
??? info "Mnemonic: the `--repeat` option"
The `--repeat` option denotes the *total* number of consecutive occurrences of the same character.
Or alternatively: if you request --repeat n, then `derivepassphrase` will *avoid* deriving any passphrase that repeats a character *another n times*.
Examples:
| option | valid examples | invalid examples |
|:--------------|:-----------------------|:--------------------------|
| `--repeat 1` | `abc`, `aba`, `abcabc` | `aa`, `abba`, `ababb` |
| `--repeat 4` | `122333111123`, `4444` | `55555`, `67788888999996` |
| `--repeat 11` | `01234567899999999999` | `$$$$$$$$$$$$$$$$$$$$$$$` |
For the `email` service, we choose passphrase length 12.
This leads to the command-line options `--length 12 --space 0 --upper 1 --lower 1 --number 1 --repeat 3`.
Because we are using a master passphrase, we also need the `-p` option.
!!! note "Note: interactive input"
In code listings, sections enclosed in `[[...]]` signify input to the program, for you to type or paste in.
Also, it is normal for passphrase prompts to not "echo" the text you type in.
~~~~ shell-session
$ derivepassphrase vault --length 12 --space 0 --upper 1 --lower 1 \
> --number 1 --repeat 3 -p email
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
kEFwoD=C?@+7
~~~~
By design, we can re-generate the same passphrase using the same input to `derivepassphrase`:
~~~~ shell-session
$ derivepassphrase vault --length 12 --space 0 --upper 1 --lower 1 \
> --number 1 --repeat 3 -p email
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
kEFwoD=C?@+7
~~~~
We can then visit our email provider and change the passphrase to `kEFwoD=C?@+7`.
### Storing the settings to disk
Because it is tedious to memorize and type in the correct settings to re-generate this passphrase, `derivepassphrase` can optionally store these settings, using the `--config` option.
~~~~ shell-session
$ derivepassphrase vault --config --length 12 --space 0 --upper 1 --lower 1 \
> --number 1 --repeat 3 email
~~~~
!!! danger "Security risk: use of `-p` and `--config`"
You are **strongly discouraged** from using the `-p` and the `--config` options together to store the master passphrase!
The configuration is assumed to *not contain sensitive contents* and is *not encrypted*, so your master passphrase is then visible to *anyone* with appropriate privileges!
Check that the settings are stored correctly:
~~~~ shell-session
$ derivepassphrase vault --export -
{"services": {"email": {"length": 12, "repeat": 3, "lower": 1, "upper": 1, "number": 1, "space": 0}}}
~~~~
Once the settings are stored, only the service name and the master passphrase option are necessary:
~~~~ shell-session
$ derivepassphrase vault -p email
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
kEFwoD=C?@+7
~~~~
## Setting up the bank account
We choose the straightforward service name `bank`.
The passphrase policy leads to the command-line options `--length 5 --lower 0 --upper 0 --number 5 --space 0 --dash 0 --symbol 0`.
The additional one-time password is generated by the hardware token, and therefore out of the scope for `derivepassphrase`.
The rest is similar to the `email` account: we configure our stored settings, generate the passphrase, and request the bank change the account passphrase to match the generated passphrase.
~~~~ shell-session
$ derivepassphrase vault --config --length 5 --lower 0 --upper 0 --number 5 \
> --space 0 --dash 0 --symbol 0 bank
$ derivepassphrase vault -p bank
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
98517
~~~~
## Setting up the work account
We first take care of the first two constraints (passphrase length and permitted/required characters), then deal with the passphrase change/reuse aspects afterwards.
Again, we start with the straightforward service name `work`, we choose "upper case letters" to fulfill the "1 letter" requirement, and add the options `--length 8 --space 0 --symbol 1 --upper 1 --number 1`.
~~~~ shell-session
$ derivepassphrase vault --length 8 --space 0 --symbol 1 --upper 1 --number 1 \
> -p work
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
r?9\XQR&
~~~~
Then we attempt to set the work passphrase to `r?9\XQR&`… but our employer's identity management system returns an error: `illegal character: &`.
What happened?
### Complication 1: What is a (permitted) "special character"? {#special-character}
`derivepassphrase` considers the characters `!"#$%&'()*+,./:;<=>?@[\]^{|}~-_'` to be permitted special characters.
Other service providers may permit other characters (quite rare) or fewer characters (quite common).
(Service providers may also *not* explicitly say which special characters they permit, except through trial and error.)
!!! abstract "Further reading"
→ [How to deal with "supported" and "unsupported" special characters][SUPPORTED_SPECIAL_CHARACTERS]
For this case specifically, we restrict ourselves to the dashes as the only permitted special characters, and hope that this passes their passphrase policy.
~~~~ shell-session
$ derivepassphrase vault --length 8 --space 0 --symbol 0 --dash 1 \
> --upper 1 --number 1 -p work
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
it90-HPO
~~~~
This works.
For now.
### Complication 2: How to implement passphrase rotation? {#passphrase-rotation}
`derivepassphrase` can only ever derive one passphrase per configuration, so passphrase rotation cannot be accomplished by reusing the same configuration.
So some part of the configuration---generally the service name---needs to change upon each rotation.
!!! abstract "Further reading"
→ [How to deal with regular passphrase rotation/rollover][PASSPHRASE_ROTATION]
We choose to append a very coarse timestamp to the "base" service name `work`: the 4-digit year, a `Q`, and the "quarter" number (1, 2, 3 or 4).
As of October 2024, this leads to the final service name `work-2024Q4`.
~~~~ shell-session
$ derivepassphrase vault --config --length 8 --space 0 --symbol 0 --dash 1 \
> --upper 1 --number 1 work-2024Q4
$ derivepassphrase vault -p work-2024Q4
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
-P268G0A
~~~~
## Summary
We have installed `derivepassphrase` and set up three accounts for use with the `vault` passphrase derivation scheme, and the master passphrase `I am an insecure master passphrase, but easy to type.`.
Our configuration should look like this:
~~~~ shell-session
$ derivepassphrase vault --export -
{"services": {"email": {"length": 12, "repeat": 3, "lower": 1, "upper": 1, "number": 1, "space": 0}, "bank": {"length": 5, "lower": 0, "upper": 0, "number": 5, "space": 0, "dash": 0, "symbol": 0}, "work-2024Q4": {"length": 8, "upper": 1, "number": 1, "space": 0, "dash": 1, "symbol": 0}}}
~~~~
We should also get the following output when asking for those passphrases again:
~~~~ shell-session
$ derivepassphrase vault -p email
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
kEFwoD=C?@+7
$ derivepassphrase vault -p bank
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
98517
$ derivepassphrase vault -p work-2024Q4
Passphrase: [[I am an insecure master passphrase, but easy to type.]]
-P268G0A
~~~~
This completes the tutorial.
As a next step, you may want to [configure the accounts to use a master SSH key instead][BASIC_SETUP_SSH_KEY].
[BASIC_SETUP_SSH_KEY]: basic-setup-ssh-key.md "Tutorial: Using a master SSH key with derivepassphrase vault on existing accounts"
[SUPPORTED_SPECIAL_CHARACTERS]: ../how-tos/supported-special-characters.md
[PASSPHRASE_ROTATION]: ../how-tos/passphrase-rotation.md