keyfork: add more documentation, unlink root README from crate
This commit is contained in:
parent
1879a250c8
commit
2b8c90fcd5
|
@ -0,0 +1,55 @@
|
||||||
|
# Keyfork: The Kitchen Sink of Entropy
|
||||||
|
|
||||||
|
**Note:** Keyfork operations are meant to be run on an airgapped machine and
|
||||||
|
Keyfork will error if either any network interfaces are detected or if Keyfork
|
||||||
|
is running on a system with a kernel using an insecure random number generator.
|
||||||
|
|
||||||
|
An all-inclusive crate encapsulating end-user functionality of the Keyfork
|
||||||
|
ecosystem, the Keyfork binary includes all mechanisms that should be exposed to
|
||||||
|
the user when running Keyfork. Information about what operations Keyfork
|
||||||
|
performs are available in detail by running `keyfork help` (each subcommand has
|
||||||
|
thorough documentation) or in the [`docs`] mdBook, but here's a quick overview:
|
||||||
|
|
||||||
|
## Getting Started with Keyfork
|
||||||
|
|
||||||
|
Keyfork offers two options for getting started. For multi-user setups, it is
|
||||||
|
best to look at the detailed documentation for Keyfork Shard. For single-user
|
||||||
|
setups, `keyfork mnemonic generate` will (by default) create a 256-bit mnemonic
|
||||||
|
phrase that can be used to start Keyfork. *Store this phrase*, as it's the only
|
||||||
|
way you'll be able to start Keyfork in the future. It is recommended to use a
|
||||||
|
mnemonic recovery sheet or a printed-steel solution such as the [Billfodl] or
|
||||||
|
[Cryptosteel Capsule].
|
||||||
|
|
||||||
|
```sh
|
||||||
|
keyfork mnemonic generate
|
||||||
|
```
|
||||||
|
|
||||||
|
Once a mnemonic has been generated and stored in a secure manner, Keyfork can
|
||||||
|
be started by "recovering" the server from the mnemonic backup mechanism:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
keyfork recover mnemonic
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deriving Keys
|
||||||
|
|
||||||
|
Keyfork's primary goal is to derive keys. These keys can later be used for
|
||||||
|
things such as signing documents and artifacts or decrypting payloads.
|
||||||
|
Keyfork's first derivation target is OpenPGP, a protocol supporting many
|
||||||
|
cryptographic operations. OpenPGP keys require a User ID, which can be used to
|
||||||
|
identify the owner of the key, either by name or by email. To get an OpenPGP
|
||||||
|
public key (more accurately known as a "cert"), the [`sq`][sq] tool is used to
|
||||||
|
convert a key to a certificate:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
keyfork derive openpgp "John Doe <jdoe@example.com>" | sq key extract-cert
|
||||||
|
```
|
||||||
|
|
||||||
|
All Keyfork derivations are intended to be reproducible. Because of this,
|
||||||
|
Keyfork derived keys can be recreated at any time, only requiring the knowledge
|
||||||
|
of how the key was made.
|
||||||
|
|
||||||
|
[`docs`]: /public/keyfork/src/branch/main/docs/src/SUMMARY.md
|
||||||
|
[Billfodl]: https://privacypros.io/products/the-billfodl/
|
||||||
|
[Cryptosteel Capsule]: https://cryptosteel.com/product/cryptosteel-capsule-solo/
|
||||||
|
[sq]: https://gitlab.com/sequoia-pgp/sequoia-sq/
|
|
@ -19,6 +19,9 @@ type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
|
||||||
pub enum DeriveSubcommands {
|
pub enum DeriveSubcommands {
|
||||||
/// Derive an OpenPGP Transferable Secret Key (private key). The key is encoded using OpenPGP
|
/// Derive an OpenPGP Transferable Secret Key (private key). The key is encoded using OpenPGP
|
||||||
/// ASCII Armor, a format usable by most programs using OpenPGP.
|
/// ASCII Armor, a format usable by most programs using OpenPGP.
|
||||||
|
///
|
||||||
|
/// The key is generated with a 24-hour expiration time. The operation to set the expiration
|
||||||
|
/// time to a higher value is left to the user to ensure the key is usable by the user.
|
||||||
#[command(name = "openpgp")]
|
#[command(name = "openpgp")]
|
||||||
OpenPGP {
|
OpenPGP {
|
||||||
/// Default User ID for the certificate, using the OpenPGP User ID format.
|
/// Default User ID for the certificate, using the OpenPGP User ID format.
|
||||||
|
@ -72,6 +75,10 @@ pub struct Derive {
|
||||||
command: DeriveSubcommands,
|
command: DeriveSubcommands,
|
||||||
|
|
||||||
/// Account ID. Required for all derivations.
|
/// Account ID. Required for all derivations.
|
||||||
|
///
|
||||||
|
/// An account ID may not be relevant for the derivation being performed, but the lack of an
|
||||||
|
/// account ID can often come as a hindrance in the future. As such, it is always required. If
|
||||||
|
/// the account ID is not relevant, it is assumed to be `0`.
|
||||||
#[arg(long, global = true, default_value = "0")]
|
#[arg(long, global = true, default_value = "0")]
|
||||||
account_id: u32,
|
account_id: u32,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ mod wizard;
|
||||||
|
|
||||||
/// The Kitchen Sink of Entropy.
|
/// The Kitchen Sink of Entropy.
|
||||||
#[derive(Parser, Clone, Debug)]
|
#[derive(Parser, Clone, Debug)]
|
||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about)]
|
||||||
pub struct Keyfork {
|
pub struct Keyfork {
|
||||||
// Global options
|
// Global options
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
|
@ -20,25 +20,51 @@ pub struct Keyfork {
|
||||||
pub enum KeyforkCommands {
|
pub enum KeyforkCommands {
|
||||||
/// Derive keys of various formats. These commands require that the Keyfork server is running,
|
/// Derive keys of various formats. These commands require that the Keyfork server is running,
|
||||||
/// which can be started by running a `keyfork recover` command.
|
/// which can be started by running a `keyfork recover` command.
|
||||||
|
///
|
||||||
|
/// Derived keys are reproducible: assuming the same arguments are used when deriving a key for
|
||||||
|
/// a second time, the key will be _functionally_ equivalent. This means keys don't need to be
|
||||||
|
/// persisted to cold storage or left hot in a running program. They can be derived when
|
||||||
|
/// they're needed and forgotten when they're not.
|
||||||
Derive(derive::Derive),
|
Derive(derive::Derive),
|
||||||
|
|
||||||
/// Mnemonic generation and persistence utilities.
|
/// Mnemonic generation and persistence utilities.
|
||||||
Mnemonic(mnemonic::Mnemonic),
|
Mnemonic(mnemonic::Mnemonic),
|
||||||
|
|
||||||
/// Splitting and combining secrets, using Shamir's Secret Sharing.
|
/// Splitting and combining secrets, using Shamir's Secret Sharing.
|
||||||
|
///
|
||||||
|
/// Keys can be split such that a certain amount of users, from a potentially even-larger
|
||||||
|
/// amount of users, can be used to recreate a key. This creates resilience for a key, as in a
|
||||||
|
/// "seven of nine" scenario, nine people in total are capable of recreating a key, but only
|
||||||
|
/// seven may be required.
|
||||||
Shard(shard::Shard),
|
Shard(shard::Shard),
|
||||||
|
|
||||||
/// Derive and deploy keys to hardware.
|
/// Derive and deploy keys to hardware.
|
||||||
|
///
|
||||||
|
/// Keys existing in hardware creates a situation where it is unlikely (but not impossible) for
|
||||||
|
/// a key to be extracted. While a key in memory could be captured by a rootkit or some other
|
||||||
|
/// privilege escalation mechanism, a key in hardware would require a hardware exploit to
|
||||||
|
/// extract the key.
|
||||||
|
///
|
||||||
|
/// It is recommended to provision keys whenever possible, as opposed to deriving them.
|
||||||
#[command(subcommand_negates_reqs(true))]
|
#[command(subcommand_negates_reqs(true))]
|
||||||
Provision(provision::Provision),
|
Provision(provision::Provision),
|
||||||
|
|
||||||
/// Recover a seed using the requested recovery mechanism and start the Keyfork server.
|
/// Recover a seed using the requested recovery mechanism and start the Keyfork server.
|
||||||
|
///
|
||||||
|
/// Once the Keyfork server is started, derivation requests can be performed. The Keyfork seed
|
||||||
|
/// is kept solely in the Keyfork server. Derivations with less than two indices are not
|
||||||
|
/// permitted, to ensure a seed often used to derive keys for multiple different paths is not
|
||||||
|
/// leaked by any individual deriver.
|
||||||
Recover(recover::Recover),
|
Recover(recover::Recover),
|
||||||
|
|
||||||
/// Utilities to automatically manage the setup of Keyfork.
|
/// Utilities to automatically manage the setup of Keyfork.
|
||||||
Wizard(wizard::Wizard),
|
Wizard(wizard::Wizard),
|
||||||
|
|
||||||
/// Print an autocompletion file to standard output.
|
/// Print an autocompletion file to standard output.
|
||||||
|
///
|
||||||
|
/// Keyfork does not manage the installation of completion files. Consult the documentation for
|
||||||
|
/// the shell for which documentation has been generated on the appropriate location to store
|
||||||
|
/// completion files.
|
||||||
#[cfg(feature = "completion")]
|
#[cfg(feature = "completion")]
|
||||||
Completion {
|
Completion {
|
||||||
#[arg(value_enum)]
|
#[arg(value_enum)]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![doc = include_str!("../../../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
#![allow(clippy::module_name_repetitions)]
|
#![allow(clippy::module_name_repetitions)]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue