From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 7986 invoked from network); 20 Jul 2021 13:03:03 -0000 Received: from bsd.lv (HELO mandoc.bsd.lv) (66.111.2.12) by inbox.vuxu.org with ESMTPUTF8; 20 Jul 2021 13:03:03 -0000 Received: from fantadrom.bsd.lv (localhost [127.0.0.1]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id 05994f4c for ; Tue, 20 Jul 2021 08:03:00 -0500 (EST) Received: from scc-mailout-kit-02.scc.kit.edu (scc-mailout-kit-02.scc.kit.edu [129.13.231.82]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id db09b29a for ; Tue, 20 Jul 2021 08:02:58 -0500 (EST) Received: from hekate.asta.kit.edu ([141.3.145.153] helo=hekate.usta.de) by scc-mailout-kit-02.scc.kit.edu with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (envelope-from ) id 1m5pOj-00026D-DC; Tue, 20 Jul 2021 15:02:57 +0200 Received: from donnerwolke.asta.kit.edu ([141.3.145.61] helo=donnerwolke.usta.de) by hekate.usta.de with esmtp (Exim 4.92.2) (envelope-from ) id 1m5pOh-0001Zf-G0; Tue, 20 Jul 2021 15:02:55 +0200 Received: from athene.asta.kit.edu ([141.3.145.60] helo=athene.usta.de) by donnerwolke.usta.de with esmtp (Exim 4.84_2) (envelope-from ) id 1m5pOh-0003Ra-9d; Tue, 20 Jul 2021 15:02:55 +0200 Received: from localhost (athene.usta.de [local]) by athene.usta.de (OpenSMTPD) with ESMTPA id 17d0354d; Tue, 20 Jul 2021 15:02:55 +0200 (CEST) Date: Tue, 20 Jul 2021 15:02:55 +0200 From: Ingo Schwarze To: Stephen Gregoratto Cc: discuss@mandoc.bsd.lv Subject: Re: mdoc synopsis style for more than one mandatory, mutually exclusive options? Message-ID: <20210720130255.GA95195@athene.usta.de> References: <20210719224854.hrmf3ez2oynitfe3@BlackBox> <20210720003457.GB7771@athene.usta.de> <20210720041038.3k5pt4q2r4lzlhec@BlackBox> X-Mailinglist: mandoc-discuss Reply-To: discuss@mandoc.bsd.lv MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210720041038.3k5pt4q2r4lzlhec@BlackBox> User-Agent: Mutt/1.12.2 (2019-09-21) Hi Stephen, Stephen Gregoratto wrote on Tue, Jul 20, 2021 at 02:10:38PM +1000: > Thanks for your recommendations. The program I'm working on is an > implementation of age[1], an encryption program. It's supposed to > act as just another UNIX-style filter that just works. I see, thanks for clarifying. > My implementation is different in that I'm not strictly following the > reference's style of arguments, as I find them too complicated for my > tastes. It commits the "sin" of arguments taking on different meanings > in different contexts. I agree that the API shown at https://age-encryption.org/v1 is atrocious, and so is the quality of the documentation. Both are highly confusing. > You make a good point about needless complexity, and I've tried > to structure my implementation to reduce this as much as > possible, mainly by using subcommands. IMHO, subcommands only make sense when there is a significant number of them, like in bgpctl(8) or smtpctl(8), but here, i can only think of three, and in that case, simply using options without arguments like in tar(1) may be sufficient: -e encrypt file -d decrypt file -g generate key Consider simplicity in typical everyday use. I guess the dominant use case will be encryping with a single key. While pasting the public key to the command line seems possible, i don't expect it to be the most frequent use. Which of the following is less cumbersome: ... | zage encrypt -R ~/.ssh/id_ed25519.pub | ... ... | zage -eR ~/.ssh/id_ed25519.pub | ... What are people expected to use this for? Encrypting files for themselves? In that case, -r/-R/-I to be re-typed again and again would be horrible, that would be a matter for a configuration file. For sending files to friends? In that case, i would want to type something like zage -er sgregoratto secret.file >> message.txt I must admit i'm not quite sure what the intended use is. If there are multiple scenarios, it ought to work well for all of them, without being cumbersome for any of them, yet the syntax still ought to be clear and simple. > Here's the full synopsis of the previous scenario, in context: > > zage encrypt [-a] [-i file] [-o file] \ > -R recipient-file -I identity-file recipients ... > zage encrypt [-a] [-i file] [-o file] -p > > Here "recipients" are public keys, in two forms: age X25519 keys and > OpenSSH Ed25519 keys. One lesson from the past is that algorithms change. Do i understand correctly that the reason why the CLI provides no option to choose the algorithm is because each key file already states the algorithm? If so, that's nicely simple and flexible design. Your "recipient" argument (which is a misnomer by the way, it's really a pubkey, not a recipient) is always long (about 60-70 characters), so pasting it will be an uncommon use case, and whether the syntax used for it is short or long does not matter at all. So making it an argument is a clear misdesign. It should definitely be an option argument - both of the following are highly cumbersome, so it really doesn't matter, and *this* should most certainly *not* block the argument space, which is much more precious than option argument space: ... | zage -er some_very_long_gibberish | ... ... | zage -e some_very_long_gibberish | ... > They're short enough that it's reasonable to > expect users to paste them in as arguments. -R denotes files > containing these recipient types, one per line. This means that users > can pass their authorized_keys file, and encrypt to any ssh-ed25519 key > in said file. I kept going back and forth between having -R only > specified once or more than, but I decided to stick with the latter > since it leads to cute invocations like: > > -R ~/.ssh/id_ed25519.pub -R <(curl -s https://github.com/ischwarze.keys) >From a UI design perspective, having an option that can be specified multiple times is perfectly fine, so i certainly don't recommend against that, even though i don't understand what the point is in encrypting with more than one key of the same person. Doesn't that just multiply the total size of the output by the number of (equivalent) keys used? And if you want to send the same file to five different persons and consequently encode with five keys, why would you want the encrypted output to go to the same output file? Wouldn't you need five separate output files, to be sent into five different directions? > -I is similar to -R, except it reads secret keys, and thus has to > compute the public key of each. This one is a holdover from the > reference implementation, and I'm not so sure about keeping it around. Actually, i tend to recommend deleting the option and the functionality it provides, for two reasons. First and more obvious reason: every reasonable key generation tool generates the private and public key files side by side. The private one is never supposed to be moved anywhere else. The public one can be *copied* away as often as you like, but *moving* it away or deleting it would be utterly stupid. Even if it does accidentylly get deleted - then again, how can that happen in a directory as delicate as one containing a private key - that should almost certainly be fixed by re-crating it, using an appropriate tool, and that's totally unrelated to zage. So there is no sane use case for -I. The second, more important argument is that you should not encourage people to gratuitiously use the private key file when it's not needed, in particularly not manually, because every manual use of a private key file poses a risk of misusing the private key and accidentally compromising it, most likely without even noticing the compromise. Besides, everything you can delete from an API is a significant gain in API quality. So, if you can delete an option without significant loss of functionality, do it. There is no loss whatsoever here... > -i and -o are the usual input and output files, defaulting to stdin/out > if not given. That is definitely good design. > -a is for PEM/ASCII armour, and -p is a special case for > password encryption. That sounds reasonable, except that i wonder: which algorithm does password encryption use? Hopefully not a hard-coded one, which would soon become obsolete? And if a varible one, how does the program select it? > Hope that clears things up. I think I'll stick to your advice about > keeping the SYNOPSIS simple, and explain in detail later on (probably in > a subheading to keep things neat). Sure. Note that the discussion started as a discussion about markup, but the lion's share of the discussion is actually about UI design. That's typical! Always be prepared to consider UI design extremely carefully, even when it may seem simple at first. Work spent on good UI design is almost never wasted (and almost never quick). Once you have good UI design, documenting the UI tends to be very straightforward, and most markup questions tend to become trivial, too. It does happen that writing documentation is arduous, and that even choosing adequate markup is hard - but usually only when the UI design was seriously botched in the first place. Yours, Ingo -- To unsubscribe send an email to discuss+unsubscribe@mandoc.bsd.lv