/ doc / dev / notes / state-management-cli.md
state-management-cli.md
   1  # State and key management CLI
   2  
   3  > This document uses deprecated terminology: "client authorization" is
   4  > now known as "restricted discovery".
   5  
   6  Arti will need the following new subcommands:
   7  
   8    * `arti-keys`, porcelain key management commands, for general key management
   9    * `arti-keys-raw`, plumbing key management commands
  10    * `arti-hss`, for managing the state (including keys) of hidden services
  11    * `arti-hsc`, for managing the state (including keys) of hidden service
  12      clients
  13  
  14  Initially, `arti-hss` and `arti-hsc` will be only used for listing,
  15  manipulating, and verifying the contents of Arti key stores (they are frontends
  16  to Arti's [`KeyMgr`]). In the future, they will be extended to support
  17  manipulating other types of persistent state too (for example, `arti hss` will
  18  also be used for manipulating the on-disk IPT records of the service).
  19  
  20  NOTE: The subcommands documented here do not exist yet. Rather than being the
  21  documentation for a finished product, this document is
  22    * a design document describing what needs to be implemented (which implicitly
  23      highlights what `KeyMgr` features we are missing)
  24    * a starting point for the CLI docs (although it might require some
  25      amendments, depending on how much the implementation deviates from what is
  26      described here)
  27  
  28  This document illustrates what the rendered man pages for the future state
  29  management CLIs might look like. The actual documentation/man pages will be be
  30  generated by rendering the [ROFF] obtained from the documentation of Arti's
  31  `clap::Command` (which will include the new `hsc` and `hss` subcommands).
  32  
  33  NOTE: This document talks about "keys and certificates", but the `KeyMgr` does not
  34  currently support certificates (but it will in the future. See [arti#955])
  35  
  36  NOTE: `arti-keys`, `arti-keys-raw`, `arti-hsc` and `arti-hss` will be
  37  implemented as arti subcommands (`arti keys`, `arti hsc`, `arti hss`).
  38  
  39  TODO HSS: Design commands for converting C Tor HS service state to an Arti
  40  keystore and associated state (calling it something like `arti-hss migrate` or
  41  `arti-hss ctor-migrate`)
  42  
  43  ## `arti-keys`
  44  ```
  45  NAME
  46         arti-keys - Command-line key management tools for Arti
  47  
  48  DESCRIPTION
  49         A CLI for accessing, manipulating and validating the contents of Arti key
  50         stores.
  51  
  52         As with arti, keystores are configured through Arti's TOML config
  53         (specified using the --config flag).
  54  
  55         The key management functionality is exposed as a collection of
  56         subcommands, each subcommand supporting a different set of options.
  57  
  58         This command provides high-level subcommands ("porcelain"), suitable for
  59         most use cases. Its subcommands implement high-level operations,
  60         manipulating either individual keys or key bundles, as applicable. They
  61         also provide guardrails preventing users from corrupting the key stores,
  62         and are suitable for routine key management tasks. Moreover, they don't
  63         require familiarity with the implementation details of Arti's key stores.
  64  
  65         TODO: explain what an ArtiPath is (ArtiPaths are mentioned throughout
  66         the manual)
  67  
  68  OPTIONS
  69         -c, --config <FILE>
  70                 Specify which config file(s) to read. Defaults to
  71                 [File("$HOME/.config/arti/arti.toml"),
  72                 Dir("$HOME/.config/arti/arti.d/")]
  73  
  74             --disable-fs-permission-checks
  75                 Don't check permissions on the files we use.
  76  
  77         --keystore-dir <ARTI_KEYSTORE>
  78            Use the keystore from the specified directory, which should be an Arti
  79            format keystore. This is a convenience alias for
  80            -o storage.keystore.path=<ARTI_KEYSTORE>
  81  
  82         -h, --help
  83                 Print help information
  84  
  85         -l, --log-level <LEVEL>
  86                 Override the log level (usually one of 'trace', 'debug', 'info', 'warn', 'error').
  87  
  88         -o <KEY=VALUE>
  89                 Override config file parameters, using TOML-like syntax.
  90  
  91         -V, --version
  92              Print version information
  93  
  94  SUBCOMMANDS
  95         help               Print this message or the help of the given subcommand(s)
  96         list               List keys and certificates from the configured key stores
  97         describe           Print information about a specific key
  98         verify             Perform validity and consistency checks
  99  ```
 100  
 101  ### `arti-keys-list`
 102  
 103  ```
 104  NAME
 105         arti-keys-list - List keys and certificates from the configured key
 106         stores
 107  
 108  SYNOPSIS
 109         arti keys list [OPTIONS]
 110  
 111  DESCRIPTION
 112         List the keys and certificates from the specified key stores. If no key
 113         stores are specified, this command lists the keys and certificates from
 114         all stores.
 115  
 116         In the pretty-printed output:
 117            * expired keys and certificates are annotated with (exp).
 118            * unrecognized keys and certificates (i.e. keys that have an unknown
 119              purpose) are annotated with (unk)
 120            * the keys and certificates that are not associated with one of the
 121              configured identities (i.e. keys with an unrecognized client/service
 122              nickname) are also annotated with (unk)
 123  
 124  OPTIONS
 125         --keystore all
 126              List the keys and certificates from all key stores. This is the
 127              default behavior if the --keystore flag is omitted
 128         --keystore default
 129              List the keys and certificates from the default keystore.
 130         --keystore [<kid>...]
 131              Specifies the IDs of the keystores to list keys and certificates
 132              from. The IDs must be associated with keystores from the Arti TOML
 133              config. It is an error to specify a key store ID not associated with
 134              any of the configured key stores.
 135          --output [pretty|json]
 136              The output format. Defaults to 'pretty', a pretty-printed,
 137              human-friendly format.
 138         --verbose
 139             Print more information about each listed key. This includes a
 140             description of the key, the ID of the key store it is located in, and
 141             whether the key is unrecognized or expired. This flag is disregarded
 142             if --output=json, because the JSON output always contains the full
 143             description of the key
 144  
 145         TODO: in the future we might want an option for only listing certs or
 146         only listing a type of key
 147         TODO: maybe this needs an option for listing keys that match a given
 148         ArtiPath pattern?
 149  
 150  EXAMPLES
 151         To pretty-print all the keys and certificates from keystores foo
 152         and bar:
 153  
 154           arti keys --config arti.toml list   \
 155             --keystore foo,bar                \
 156             --output pretty
 157  
 158         Sample output:
 159  
 160           ===== foo =====
 161             client/alice/abc.onion/KS_hsc_desc_enc.x25519_private
 162             client/alice/xyz.onion/KS_hsc_desc_enc.x25519_private
 163             client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private (unk)
 164             hs/carol/KS_hs_id.expanded_ed25519_private
 165             hs/carol/KS_hs_blind_id+19666_1440_43200.ed25519_expanded_private (exp)
 166             hs/carol/KS_hs_blind_id+19667_1440_43200.ed25519_expanded_private
 167             hs/carol/KS_hs_desc_sign+19666_1440_43200.ed25519_expanded_private (exp)
 168             hs/carol/KS_hs_desc_sign+19667_1440_43200.ed25519_expanded_private
 169             hs/dan/KS_hs_id.expanded_ed25519_private
 170             hs/eve/KS_hs_blind_id+19666_1440_43200.ed25519_expanded_private (unk)
 171             hs/eve/KS_hs_desc_sign+19667_1440_43200.ed25519_expanded_private (unk)
 172           ===== bar =====
 173             client/bob/def.onion/KS_hsc_desc_enc.x25519_private
 174  
 175         To include more information about each key, use --verbose:
 176  
 177           arti keys --config arti.toml list   \
 178             --keystore foo,bar                \
 179             --output pretty                   \
 180             --verbose
 181  
 182         Sample output:
 183  
 184           ===== client/alice/abc.onion/KS_hsc_desc_enc.x25519_private =====
 185             purpose: Client authorization key, used for onion descriptor decryption
 186             client: alice
 187             keystore ID: foo
 188             expired: no
 189  
 190           ===== client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private =====
 191             purpose: unknown
 192             client: alice
 193             keystore ID: foo
 194  
 195           ===== hs/eve/KS_hs_desc_sign+19666_1440_43200.ed25519_expanded_private =====
 196             purpose: descriptor signing key
 197             service: unknown
 198             keystore ID: foo
 199             expired: unknown
 200  
 201           ===== hs/eve/KS_hs_desc_sign+19667_1440_43200.ed25519_expanded_private =====
 202             purpose: descriptor signing key
 203             service: unknown
 204             keystore ID: foo
 205             expired: unknown
 206            ...
 207  
 208  
 209         With --output=json, the command prints the same information in JSON format.
 210  
 211         TODO: Add JSON output sample
 212  ```
 213  
 214  #### Implementation
 215  
 216  Required `KeyMgr` APIs:
 217  
 218    * `KeyMgr::list_matching`
 219    * `KeyMgr::describe`
 220  
 221  TODO: we might want to add a `KeyMgr::list_all` for listing all the keys from a
 222  given store (today this can be achieved by calling `list_matching` with a `"*"`
 223  `KeyPathPattern`).
 224  
 225  This command will be implemented by an API that uses `KeyMgr::list_matching` and
 226  `KeyMgr::describe` under the hood. Note: `KeyMgr::list_matching` lists the keys
 227  from all keystores. It will need to be modified to accept a `KeystoreSelector`
 228  argument to support only listing the keys from a given keystore (otherwise we
 229  can't implement the `--keystore` option). We'll also need some way of detecting
 230  which keys are expired: given a valid `KeyPath`, the API will:
 231    * parse it back into its corresponding `KeySpecifier`
 232    * check if the `TimePeriod` stored in the `KeySpecifier` is "relevant". If it
 233      is not, it will declare the key expired. Checking if the `TimePeriod` is
 234      relevant or not can be done by checking if it's one of the
 235      `NetDir::hs_all_time_periods()` returned by a recent `NetDir`.
 236      Alternatively, the API could try to "guess" which time periods are relevant
 237      based on the current wallclock time
 238  
 239  ### `arti-keys-verify`
 240  
 241  ```
 242  NAME
 243         arti-keys-verify - perform consistency, validity, and integrity checks
 244         on the specified stores
 245  
 246  SYNOPSIS
 247         arti keys verify [OPTIONS]
 248  
 249  DESCRIPTION
 250         The key validity checks fail if there are any
 251           * keys and certificates not associated with any current identity
 252           * unrecognized keys
 253           * expired keys
 254           * ... (TODO)
 255  
 256         If --fix is not specified, this command lists the keys and
 257         certificates that failed the validity checks from each key store,
 258         along with the reason for the failure.
 259  
 260         Note:
 261            * expired keys and certificates are annotated with (exp).
 262            * unrecognized keys and certificates (i.e. keys that have an unknown
 263              purpose) are annotated with (unk)
 264            * the keys and certificates that are not associated with one of the
 265              configured identities (i.e. keys with an unrecognized client/service
 266              nickname) are also annotated with (unk)
 267  
 268  OPTIONS
 269         --keystore default
 270              Perform checks on the default keystore. This is the default
 271              behavior if the --keystore flag is omitted
 272         --keystore [<kid>...]
 273              Specifies the IDs of the keystores to check. The IDs must
 274              be associated with keystores from the Arti TOML config. It is an
 275              error to specify a key store ID not associated with any of the
 276              configured key stores.
 277         --fix
 278              Attempt to fix the problems detected. Any expired or unrecognized
 279              keys and certificates are removed. Prompts before every removal
 280          --output [pretty|json]
 281              The output format. Defaults to 'pretty', a pretty-printed,
 282              human-friendly format
 283         --verbose
 284              Print more information about each reported problem. This flag is
 285              disregarded if --output=json, because the JSON output always
 286              contains the full error report
 287  
 288  EXAMPLES
 289         Perform validity checks on keystores foo and bar:
 290  
 291           arti keys verify --config arti.toml \
 292             --keystore foo,bar                \
 293             --output pretty
 294  
 295         Sample output:
 296  
 297           verifying 2 keystores
 298           bar ... OK
 299           foo ... FAILED
 300  
 301           failures:
 302  
 303           ====== foo ======
 304           client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private (unk)
 305           hs/carol/KS_hs_blind_id+19666_1440_43200.ed25519_expanded_private (exp)
 306           hs/carol/KS_hs_desc_sign+19666_1440_43200.ed25519_expanded_private (exp)
 307  
 308         Perform validity checks on keystores foo and bar, removing any invalid keys:
 309  
 310          arti keys verify --config arti.toml \
 311            --keystore foo,bar                \
 312            --fix
 313  
 314         Sample output:
 315  
 316           verifying 2 keystores
 317           bar ... OK
 318           foo ... FAILED
 319  
 320           failures:
 321  
 322           ====== foo ======
 323           client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private (unk) Remove? [y/N]: y
 324           hs/carol/KS_hs_blind_id+19666_1440_43200.ed25519_expanded_private (exp) Remove? [y/N]: y
 325           hs/carol/KS_hs_desc_sign+19666_1440_43200.ed25519_expanded_private (exp) Remove? [y/N]: N
 326  ```
 327  
 328  #### Implementation
 329  
 330  Required `KeyMgr` APIs:
 331  
 332    * `KeyMgr::list_matching`
 333    * `KeyMgr::describe`
 334    * `KeyMgr::remove`
 335  
 336  This command is exactly like `arti-keys-list`, except it also removes the
 337  invalid keys if prompted to do so.
 338  
 339  ### `arti-keys-describe`
 340  
 341  ```
 342  NAME
 343         arti-keys-describe - print information about a specific key
 344  
 345  SYNOPSIS
 346         arti keys describe [OPTIONS] <ARTI_PATH>
 347  
 348  DESCRIPTION
 349         Given the ArtiPath of a key, print a description of what the key is used
 350         for.
 351  OPTIONS
 352         --output [pretty|json]
 353             The output format. Defaults to 'pretty', a pretty-printed,
 354             human-friendly format
 355         --verbose
 356             Print more information about the key. This includes a description of
 357             the key, the ID of the key store it is located in, and whether the
 358             key is unrecognized or expired. This flag is disregarded if
 359             --output=json, because the JSON output always contains the full
 360             description of the key
 361  
 362         TODO: maybe this needs an option for describing keys that match a given
 363         ArtiPath pattern?
 364  
 365  EXAMPLES
 366         Describe the ArtiPath of a hidden service identity key:
 367  
 368           arti keys describe hs/carol/KS_hs_id.expanded_ed25519_private
 369  
 370         Sample output:
 371  
 372           ===== hs/carol/KS_hs_id.expanded_ed25519_private =====
 373             purpose: The long-term identity keypair of the service.
 374             type: ed25519 keypair
 375             service: carol
 376             expired: no
 377  
 378         Describe a malformed client ArtiPath:
 379  
 380           arti keys describe \
 381               client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private
 382  
 383         Sample output:
 384           ===== client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private =====
 385             purpose: unknown
 386             type: x25519 keypair
 387             expired: unknown
 388  
 389         Describe a malformed ArtiPath:
 390  
 391           arti keys describe abc.xyz
 392  
 393         Sample output:
 394           ===== abc.xyz =====
 395             purpose: unknown
 396             type: unknown
 397             expired: unknown
 398  ```
 399  
 400  #### Implementation
 401  
 402  Required `KeyMgr` APIs:
 403  
 404    * `KeyMgr::describe`
 405  
 406  This will be implemented by an API based on `KeyMgr::describe`. As mentioned
 407  under `arti-keys-list`, the API will also need to be able to detect if the
 408  specified key is expired or not (this is not something `KeyMgr` can do. See
 409  `KeystoreSweeper` for an example of how key expiration is detected and handled
 410  today. The key expiration logic will need to be factored out of
 411  `KeystoreSweeper`, because we'll need it for the CLI APIs too).
 412  
 413  ## `arti-keys-raw`
 414  
 415  ```
 416  NAME
 417         arti-keys-raw - Command-line key management plumbing tools for Arti
 418  
 419  DESCRIPTION
 420         A CLI for accessing and manipulating the contents of Arti key stores.
 421  
 422         As with arti, keystores are configured through Arti's TOML config
 423         (specified using the --config flag).
 424  
 425         The key management functionality is exposed as a collection of "plumbing"
 426         subcommands, each subcommand supporting a different set of options.
 427  
 428         The arti-keys-raw commands operate at a lower level than the arti-keys(1)
 429         commands. They operate on individual keys, specified as `ArtiPath`s. As
 430         such, their misuse can lead to key store corruption.
 431  
 432         You most likely do **not** need to use these: all common/routine use
 433         cases *should* be covered by the higher level arti-keys(1) subcommands.
 434         If you find yourself needing these commands for routine key management
 435         tasks, it means we are missing a porcelain wrapper for your workflow.
 436  
 437         TODO: explain what an ArtiPath is (ArtiPaths are mentioned throughout
 438         the manual)
 439  
 440  OPTIONS
 441         -c, --config <FILE>
 442                 Specify which config file(s) to read. Defaults to
 443                 [File("$HOME/.config/arti/arti.toml"),
 444                 Dir("$HOME/.config/arti/arti.d/")]
 445  
 446             --disable-fs-permission-checks
 447                 Don't check permissions on the files we use.
 448  
 449         --keystore-dir <ARTI_KEYSTORE>
 450            Use the keystore from the specified directory, which should be an Arti
 451            format keystore. This is a convenience alias for
 452            -o storage.keystore.path=<ARTI_KEYSTORE>
 453  
 454         -h, --help
 455                 Print help information
 456  
 457         -l, --log-level <LEVEL>
 458                 Override the log level (usually one of 'trace', 'debug', 'info', 'warn', 'error').
 459  
 460         -o <KEY=VALUE>
 461                 Override config file parameters, using TOML-like syntax.
 462  
 463         -V, --version
 464              Print version information
 465  
 466  SUBCOMMANDS
 467         list            Plumbing subcommand for listing the files from key stores
 468         remove-by-path  Plumbing subcommand for removing files from key stores
 469  
 470  ```
 471  
 472  ### `arti-keys-raw-list` (plumbing)
 473  
 474  
 475  ```
 476  NAME
 477         arti-keys-raw-list - List all available keys, without interpreting their
 478         meaning
 479  
 480  SYNOPSIS
 481         arti keys-raw list [OPTIONS]
 482  
 483  DESCRIPTION
 484         List the keys and certificates from the specified key stores. If no key
 485         stores are specified, this command lists the keys and certificates from
 486         all stores.
 487  
 488  OPTIONS
 489         --keystore all
 490              List the keys and certificates from all key stores. This is the
 491              default behavior if the --keystore flag is omitted
 492         --keystore default
 493              List the keys and certificates from the default keystore.
 494         --keystore [<kid>...]
 495              Specifies the IDs of the keystores to list keys and certificates
 496              from. The IDs must be associated with keystores from the Arti TOML
 497              config. It is an error to specify a key store ID not associated with
 498              any of the configured key stores.
 499  
 500  EXAMPLES
 501         List the keys in keystores foo and bar:
 502  
 503           arti keys-raw list --config arti.toml \
 504             --keystore foo,bar
 505  
 506         Sample output:
 507           ===== foo =====
 508             abc/not-a-key.txt
 509             client/alice/abc.onion/ks_hsc_desc_enc.x25519_private
 510             client/alice/xyz.onion/KS_hsc_desc_enc.x25519_private
 511             client/alice/xyz.onion/KS_hsc_desc_not_a_valid_name.x25519_private
 512             hs/carol/KS_hs_id.expanded_ed25519_private
 513             hs/carol/KS_hs_blind_id+19666_1440_43200.ed25519_expanded_private
 514             hs/carol/KS_hs_blind_id+19667_1440_43200.ed25519_expanded_private
 515             hs/carol/KS_hs_desc_sign+19666_1440_43200.ed25519_expanded_private
 516             hs/carol/KS_hs_desc_sign+19667_1440_43200.ed25519_expanded_private
 517             hs/dan/KS_hs_id.expanded_ed25519_private
 518             hs/eve/KS_hs_blind_id+19666_1440_43200.ed25519_expanded_private
 519             hs/eve/KS_hs_desc_sign+19667_1440_43200.ed25519_expanded_private
 520           ===== bar =====
 521             client/bob/def.onion/KS_hsc_desc_enc.x25519_private
 522  ```
 523  
 524  #### Implementation
 525  
 526  Required `KeyMgr` APIs:
 527  
 528    * `KeyMgr::list_matching`
 529  
 530  ### `arti-keys-raw-remove-by-path` (plumbing)
 531  
 532  ```
 533  NAME
 534         arti-keys-raw-remove-by-path - Remove a key, given its ArtiPath
 535  
 536  SYNOPSIS
 537         arti keys-raw remove-by-path [OPTIONS] <RAW_PATH>
 538  
 539  DESCRIPTION
 540        Remove the specified file from the key store.
 541  
 542        The specified RAW_PATH is in the format of an ArtiPath, and so it is
 543        relative to the key store root.
 544  
 545        TODO: warn about misuse
 546  
 547  OPTIONS
 548         --keystore default
 549              Remove the key from the default keystore. This is the default
 550              behavior if the --keystore flag is omitted
 551         --keystore <kid>
 552              Specifies the ID of the keystore to remove the key from. The ID must
 553              match one of the key store IDs configured in the specified config. It
 554              is an error to specify an unrecognized key store ID.
 555        --remove-all
 556              Remove **all** the keys and certificates of this key from all
 557              keystores. This is a dangerous option and should be used with care.
 558              Prompts before removal. Cannot be used with --keystore
 559  
 560  EXAMPLES
 561  
 562         Remove a file from keystore foo:
 563  
 564           arti keys-raw --config arti.toml remove-by-path            \
 565               --keystore foo                                         \
 566               client/alice/abc.onion/ks_hsc_desc_enc.x25519_private
 567  
 568  
 569         Remove a file that is probably not a key from keystore foo:
 570  
 571           arti keys-raw --config arti.toml remove-by-path            \
 572               --keystore foo                                         \
 573               foo/some-file.txt
 574  ```
 575  
 576  #### Implementation
 577  
 578  Required `KeyMgr` APIs:
 579  
 580    * `KeyMgr::remove`
 581  
 582  ## `arti-hsc`
 583  
 584  ```
 585  NAME
 586         arti-hsc - Command-line tool for managing the state of Arti hidden
 587         service clients
 588  
 589  SYNOPSIS
 590         arti hsc [OPTIONS] <SUBCOMMAND> [SUBCOMMAND-OPTIONS]
 591  
 592  DESCRIPTION
 593         A CLI for accessing, manipulating and validating the contents of Arti key
 594         stores and other persistent state.
 595  
 596         As with arti, keystores are configured through Arti's TOML config
 597         (specified using the --config flag).
 598  
 599         The state management functionality is exposed as a collection of
 600         subcommands, each subcommand supporting a different set of options.
 601  
 602         TODO: explain what an ArtiPath is (ArtiPaths are mentioned throughout
 603         the manual)
 604  
 605  OPTIONS
 606         -c, --config <FILE>
 607                 Specify which config file(s) to read. Defaults to
 608                 [File("$HOME/.config/arti/arti.toml"),
 609                 Dir("$HOME/.config/arti/arti.d/")]
 610  
 611             --disable-fs-permission-checks
 612                 Don't check permissions on the files we use.
 613  
 614         --keystore-dir <ARTI_KEYSTORE>
 615            Use the keystore from the specified directory, which should be an Arti
 616            format keystore. This is a convenience alias for
 617            -o storage.keystore.path=<ARTI_KEYSTORE>
 618  
 619         -h, --help
 620                 Print help information
 621  
 622         -l, --log-level <LEVEL>
 623                 Override the log level (usually one of 'trace', 'debug', 'info', 'warn', 'error').
 624  
 625         -o <KEY=VALUE>
 626                 Override config file parameters, using TOML-like syntax.
 627  
 628         -V, --version
 629              Print version information
 630  
 631  SUBCOMMANDS
 632         help           Print this message or the help of the given subcommand(s)
 633         generate-key   Generate a key in one of the configured key stores
 634         remove-key     Remove a key from one of the configured key stores
 635  ```
 636  
 637  ### `arti-hsc-generate-key`
 638  
 639  ```
 640  NAME
 641         arti-hsc-generate-key-auth - Generate a hidden service client authorization key
 642  
 643  SYNOPSIS
 644         arti hsc generate-key auth [OPTIONS]
 645  
 646  DESCRIPTION
 647         NOTE: while generate-key currently has only one subcommand ("auth"), in
 648         the future we might need to extend it with additional subcommands (if we
 649         extend the protocol to support other forms of client auth, for example)
 650  
 651         Generate a hidden service client authorization key, placing the keypair
 652         in the specified key store.
 653  
 654         This generates an x25519 descriptor encryption keypair and prints the
 655         corresponding public key to stdout in the format specified via the
 656         --pub-format option.
 657  
 658         This command should be run by clients who want to connect to a hidden
 659         service that requires client authorization.
 660  
 661         To connect to a hidden service that has client authorization enabled,
 662         clients need to share the public part of the key with the hidden service
 663         through a secure channel. The hidden service can then authorize the
 664         client to connect by encrypting its descriptor with the client's public
 665         key. The client uses the generated x25519 keypair to compute the keys for
 666         decrypting the superencrypted layer of the descriptor.
 667  
 668  OPTIONS
 669         --keystore default
 670              Generate the key in the default keystore. This is the default
 671              behavior if the --keystore flag is omitted
 672         --keystore <kid>
 673              Specifies the ID of the keystore to generate the key into. The ID
 674              must match one of the key store IDs configured in the specified
 675              config. It is an error to specify an unrecognized key store ID.
 676         --nickname
 677              The nickname of the client for which to generate the key
 678         --hsid
 679              The hidden service for which to generate the key
 680         --pub-format [arti|ctor]
 681              The format to print the public part of the key in
 682              TODO: decide what the arti format looks like
 683         --force
 684              Whether to overwrite the key if it already exists
 685  
 686  EXAMPLES
 687         Generate a client authorization key for service xyz.onion in keystore foo:
 688  
 689           arti hsc --config arti.toml generate-key auth --keystore foo  \
 690               --nickname alice                                          \
 691               --hsid xyz.onion                                          \
 692               --pub-format ctor
 693  
 694        Stdout:
 695  
 696           descriptor:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja
 697  
 698        TODO: update this section and document the arti --pub-format after we
 699        reach a conclusion in #1028
 700  ```
 701  
 702  #### Implementation
 703  
 704  Required `KeyMgr` APIs:
 705  
 706    * `KeyMgr::generate`
 707  
 708  ### `arti-hsc-remove-key`
 709  
 710  ```
 711  NAME
 712         arti-hsc-remove-key - remove a client authorization key from the specified
 713         key store
 714  
 715  SYNOPSIS
 716         arti hsc remove-key auth [OPTIONS]
 717  
 718  DESCRIPTION
 719         NOTE: like generate-key, remove-key currently has only one subcommand
 720         ("auth").
 721  
 722         Remove a hidden service client authorization key from the specified key
 723         store.
 724  
 725         After removing the key, the client will no longer be able to connect to
 726         the service specified via --hsid, if the service has enabled client
 727         authorization.
 728  
 729  OPTIONS
 730         --nickname
 731              The nickname of the client for which to remove the key
 732         --hsid
 733              The hidden service the key is associated with
 734  
 735  EXAMPLES
 736         Remove the client authorization key for service xyz.onion from keystore foo:
 737  
 738           arti hsc --config arti.toml remove-key auth --keystore foo    \
 739               --type desc-enc                                           \
 740               --nickname alice                                          \
 741               --hsid xyz.onion
 742  ```
 743  
 744  #### Implementation
 745  
 746  Required `KeyMgr` APIs:
 747  
 748    * `KeyMgr::remove`
 749  
 750  ## `arti-hss`
 751  
 752  ```
 753  NAME
 754         arti-hss - Command-line tool for managing the state of Arti hidden
 755         services
 756  
 757  SYNOPSIS
 758         arti hss [OPTIONS] <SUBCOMMAND> [SUBCOMMAND-OPTIONS]
 759  
 760  DESCRIPTION
 761        A state management tool for Arti hidden services.
 762  
 763        The managed state includes:
 764           * the IPT state of the service stored on disk
 765           * the keys associated with the service
 766  
 767  OPTIONS
 768         -c, --config <FILE>
 769                 Specify which config file(s) to read. Defaults to
 770                 [File("$HOME/.config/arti/arti.toml"),
 771                 Dir("$HOME/.config/arti/arti.d/")]
 772  
 773             --disable-fs-permission-checks
 774                 Don't check permissions on the files we use.
 775  
 776         --keystore-dir <ARTI_KEYSTORE>
 777            Use the keystore from the specified directory, which should be an Arti
 778            format keystore. This is a convenience alias for
 779            -o storage.keystore.path=<ARTI_KEYSTORE>
 780  
 781         -h, --help
 782                 Print help information
 783  
 784         -l, --log-level <LEVEL>
 785                 Override the log level (usually one of 'trace', 'debug', 'info', 'warn', 'error').
 786  
 787         -o <KEY=VALUE>
 788                 Override config file parameters, using TOML-like syntax.
 789  
 790         -V, --version
 791              Print version information
 792  
 793  SUBCOMMANDS
 794         help                  Print this message or the help of the given subcommand(s)
 795         new-service           Initialize a new hidden service
 796         generate-online-keys  Generate all the keys necessary to run a hidden service
 797         destroy               Remove all the keys and state of a hidden service
 798         print-onion           Print the .onion address of a service
 799         auth-clients          Manage the authorized clients of this hidden service
 800         destroy-and-recreate  Generate a new identity keypair for a hidden service
 801  ```
 802  
 803  ### `arti-hss-new-service`
 804  
 805  ```
 806  NAME
 807         arti-hss-new-service - initialize a new hidden service
 808  
 809  SYNOPSIS
 810         arti hss new-service [OPTIONS]
 811  
 812  DESCRIPTION
 813        Initializes a new hidden service by generating a new identity keypair and
 814        placing it in the specified key store.
 815  
 816        Users wanting to create a new service that will run in offline mode should
 817        run this command on a secure offline host to create its identity keys, and
 818        then run arti-hss-generate-online-keys(1) to generate the keys needed to
 819        run the service.
 820  
 821        Before running this command, ensure the hidden service you are
 822        initializing is configured in the Arti config (specified via --config).
 823  
 824        If Arti is already running using a config that contains an entry for the
 825        hidden service, its identity key has likely already been automatically
 826        generated by Arti. If that is the case, this command will report that an
 827        identity key already exists for the service, and exit with an error.
 828  
 829        TODO: make Arti support watching for keystore changes. Decide what happens
 830        if a new service is configured while Arti is running
 831  
 832  OPTIONS
 833         --keystore default
 834              Place the identity key in the default keystore. This is the default
 835              behavior if the --keystore flag is omitted
 836         --keystore <kid>
 837              Specifies the ID of the keystore to generate the identity key into.
 838              The ID must match one of the key store IDs configured in the
 839              specified config. It is an error to specify an unrecognized key
 840              store ID.
 841         --nickname
 842              The nickname of the service
 843  
 844  EXAMPLES
 845         Initialize a new hidden service with nickname "shallot" in the default
 846         key store:
 847  
 848           arti hss --config arti.toml new-service \
 849               --nickname shallot
 850  
 851         Sample output:
 852  
 853           Generated a new hidden service using nickname "shallot":
 854             wrxdvcaqpuzakbfww5sxs6r2uybczwijzfn2ezy2osaj7iox7kl7nhad.onion
 855  
 856         If any of the configured keystores contain any entries for service
 857         "shallot", a new identity key pair will **not** be generated:
 858  
 859           Cannot generate a new service with nickname "shallot": keystores foo and
 860           bar contain keys associated with a pre-existing hidden service with the
 861           same nickname
 862  
 863              Hint: use a different nickname.
 864  
 865              Alternatively, if you want to erase the service with nickname
 866              "shallot", run:
 867  
 868                 arti hss --config arti.toml destroy \
 869                     --nickname shallot
 870  
 871              before retrying the operation
 872  
 873         If the public part of the identity key is available, this command also
 874         prints the corresponding .onion address before exiting:
 875  
 876           Cannot generate new hidden service with nickname "shallot": an identity key
 877           already exists
 878             wrxdvcaqpuzakbfww5sxs6r2uybczwijzfn2ezy2osaj7iox7kl7nhad.onion
 879  
 880  ```
 881  
 882  #### Implementation
 883  
 884  Required `KeyMgr` APIs:
 885  
 886    * `KeyMgr::generate`
 887  
 888  ### `arti-hss-generate-online-keys`
 889  
 890  ```
 891  NAME
 892         arti-hss-generate-online-keys - generate the keys needed to run a hidden service in offline mode
 893  
 894  SYNOPSIS
 895         arti hss generate-online-keys [OPTIONS]
 896  
 897  DESCRIPTION
 898        Generates all the keys required for a hidden service to operate without
 899        needing access to its identity key, up to a given time period.
 900  
 901        You do **not** need to run this command unless you want to run a hidden
 902        service in offline mode (where the identity key of the service is kept
 903        offline). If the identity keys are "online" (i.e. available on the host
 904        running the hidden service), you do not need to run this command, as Arti
 905        will automatically generate all the necessary keys and certificates.
 906  
 907        This command should be run on a secure offline system where the secret
 908        identity key of the service is available. It generates keys inside an
 909        "online" keystore, specified via --online-keystore-dir. Because the
 910        "online" keystore is a directory on disk, it can be copied from the
 911        offline system to the (online) hidden service host using the file-copying
 912        utilities available on your system. On the online system, the
 913        storage.keystore.path from the TOML config of the hidden service should
 914        point to the path the "online" keystore was copied to.
 915  
 916        The service will be able to operate without its secret identity key until
 917        the time specified via --up-to. After that, additional keys will
 918        need to be generated.
 919  
 920        This command assumes the hidden service has already been initialized,
 921        either manually, using arti-hss-new-service(1), or implicitly,
 922        by starting arti as a hidden service,
 923        and that the identity keypair is available in one
 924        of the configured key stores.
 925  
 926        Generates the following keys and certificates for each time period
 927        starting from the current time period up until the time specified
 928        via --up-to:
 929  
 930          * blinded identity keypair
 931          * descriptor signing key
 932          * descriptor signing certificate (obtained by signing the descriptor
 933            signing key with the blinded identity key)
 934  
 935  OPTIONS
 936         --online-keystore-dir
 937              The root of the online keystore, where the keys will be generated.
 938              The keystore directory will be created if it does not already exist.
 939         --nickname
 940              The nickname of the service for which to generate the keys
 941         --up-to {<TIMESTAMP>|<DURATION>}
 942              A timestamp or duration representing the validity interval of
 943              the generated keys. The service will be able to run using the
 944              generated keys until the specified <TIMESTAMP>, or for the specified
 945              <DURATION>. after which new keys will need to be generated.
 946              Timestamps represent an absolute date/time given in RFC3339 format.
 947              Durations are relative to the current time (i.e. the time when this
 948              command was run), and represent a number of hours, minutes, or days
 949              (for example "--up-to 48h", --up-to 48 hours", "--up-to 10 days").
 950  
 951  EXAMPLES
 952         Initialize a new "online" keystore at $HOME/foo with the keys needed in
 953         order for hidden service "shallot" to run in offline mode until
 954         2023-02-09T12:00:00Z (the identity key of the service must be in one of
 955         the keystores configured in arti.toml):
 956  
 957           arti hss --config arti.toml generate-online-keys \
 958               --online-keystore-dir $HOME/foo              \
 959               --nickname shallot                           \
 960               --up-to 2023-02-09T12:00:00Z
 961  
 962         Keystore foo can be exported to the online system by copying the
 963         $HOME/foo directory. On the online system, in the TOML config of the
 964         hidden service, storage.keystore.path should point to the parent directory
 965         of foo (TODO: make the keystore ID part of the config).
 966  ```
 967  
 968  #### Implementation
 969  
 970  Required `KeyMgr` APIs:
 971  
 972    * `KeyMgr::generate`
 973  
 974  ### `arti-hss-destroy`
 975  
 976  ```
 977  NAME
 978         arti-hss-destroy - remove the persistent state and all the keys of a hidden service
 979  
 980  SYNOPSIS
 981         arti hss destroy [OPTIONS]
 982  
 983  DESCRIPTION
 984         Remove the persistent state and all the keys of a hidden service.
 985  
 986         This removes
 987           * the IPT state of the service stored on disk
 988           * any the keys associated with the service, from all key stores
 989  
 990  OPTIONS
 991         --nickname
 992              The nickname of the service to erase
 993  
 994  EXAMPLES
 995         Erase all the keys and state hidden service with nickname "shallot":
 996  
 997           arti hss --config arti.toml destroy \
 998               --nickname shallot
 999  ```
1000  
1001  #### Implementation
1002  
1003  Required `KeyMgr` APIs:
1004  
1005    * `KeyMgr::remove`
1006  
1007  ### `arti-hss-print-onion`
1008  
1009  ```
1010  NAME
1011         arti-hss-print-onion - print the .onion address of a service
1012  
1013  SYNOPSIS
1014         arti hss print-onion [OPTIONS]
1015  
1016  DESCRIPTION
1017        Print the .onion address of a service.
1018  
1019  OPTIONS
1020         --nickname
1021              The nickname of the service to display
1022  
1023  EXAMPLES
1024        Print the .onion address of the service with nickname allium from the
1025        default keystore:
1026  
1027          arti hss --nickname allium print-onion-name
1028  
1029       Sample output:
1030          wrxdvcaqpuzakbfww5sxs6r2uybczwijzfn2ezy2osaj7iox7kl7nhad.onion
1031  ```
1032  
1033  #### Implementation
1034  
1035  Required `KeyMgr` APIs:
1036  
1037    * `KeyMgr::get`
1038  
1039  ### `arti-hss-auth-clients`
1040  
1041  ```
1042  NAME
1043         arti-hss-auth-clients - Manage the authorized clients of this hidden service
1044  
1045  SYNOPSIS
1046         arti hss auth-clients [SUBCOMMAND]
1047  
1048  DESCRIPTION
1049        A command for managing the authorized clients of an Arti hidden service.
1050  
1051        TODO: document how these commands are supposed to work after we reach a
1052        conclusion in #1028
1053  
1054  SUBCOMMANDS
1055         help                  Print this message or the help of the given subcommand(s)
1056         import                Import the public keys of a client
1057         disable               Un-authorize a previously authorized client
1058         enable                Authorize a new client
1059  ```
1060  
1061  ### `arti-hss-destroy-and-recreate`
1062  
1063  ```
1064  NAME
1065         arti-hss-destroy-and-recreate - Generate a new identity keypair for a hidden service
1066  
1067  SYNOPSIS
1068         arti hss destroy-and-recreate [OPTIONS]
1069  
1070  DESCRIPTION
1071         A command for generating a new set of keys for an existing hidden
1072         service.
1073  
1074         This command deletes all the keys, including identity key, of the
1075         specified service and generates a fresh identity keypair.
1076  
1077         This command preserves the nickname of the service and its configuration
1078         (including the authorized clients).
1079  
1080         TODO: Expand on the description, add an example
1081  
1082  OPTIONS
1083         --nickname
1084              The nickname of the service to destroy and recreate
1085  ```
1086  
1087  #### Implementation
1088  
1089  Required `KeyMgr` APIs:
1090  
1091    * `KeyMgr::remove`
1092    * `KeyMgr::generate`
1093  
1094  
1095  
1096  [`KeyMgr`]: https://docs.rs/tor-keymgr/0.4.0/tor_keymgr/struct.KeyMgr.html
1097  [ROFF]: https://crates.io/crates/clap_mangen
1098  [arti#955]: https://gitlab.torproject.org/tpo/core/arti/-/issues/955
1099