Three days of the doas.
I started working on doas quite some time ago after some personal issues with the default sudo config. The “safe environment” was under constant revision and I regularly found myself unable to run pkg_add or build a flavored port or whatever because the expected variables were being excised from the environment. If I had been paying attention, keeping sudoers up to date probably would not have been such an ordeal, but I don’t like change.
The core of the problem was really that some people like to use sudo to build elaborate sysadmin infrastructures with highly refined sets of permissions and checks and balances. Some people (me) like to use sudo to get a root shell without remembering two passwords. And so there was considerable tension trying to ship a default config that would mostly work with the second group, but not be too permissive for the first group.
Writing a small simple replacement meant that we could ship something in base which was totally unsuitable for the power sysadmin group. It could only work for me, and I would be happy. Meanwhile, those who truly needed all the flexibility of sudo would install it from ports, and they would be happy.
The code was just sitting around in a spare source tree for a while because any “like this, but different” software release immediately results in a flood of email. “It’s different!” And despite my reasoning above, I seemed to be the only person actually unhappy with the situation, so there was no motivation to add the necessary polish to reach minimal replacement level.
Talking with deraadt and millert, however, I wasn’t quite alone. There were some concerns that sudo was too big, running too much code in a privileged process. And there was also pressure to enable even more options, because the feature set shipped in base wasn’t big enough. (As shipped in OpenBSD, the compiled sudo was already five times larger than just about any other setuid program.) Hurray, tension. It wasn’t the problem I was trying to solve, but it was an opening from which to launch my diabolical plan.
First, doas needed a new name because nobody ever likes the first name. A few suggestions were made. sux (already taken by su, now with more X). machtfrei (too many letters). powershell (if only). datass (submitted after contest end).
And then the real hacking and chopping could begin. I always thought the most important feature of sudo was that it insulted the user after entering a bad password. Apparently the world is filled with poor typists; the first diff to doas was to add a config option noinsults. Unfortunately, this was a poor compromise that complicated the grammar and required further documentation, so the feature was dropped entirely. There was also another proposal to change the error message from “Permission denied” to “Sorry” to match su, but not implemented. doas will not apologize for your failures.
Deleting a dozen lines of insults made space for one new feature. A simple -s option is almost compatible with sudo if muscle memory proves too difficult to overcome.
The config file syntax is crudely inspired by pf.conf. Instead of pass and block keywords, there are permit and deny keywords. There are some limitations. Trying to deny a single command can be tricky because “ksh” and ”/bin/ksh” and ”///bin/ksh” are all interpreted differently. Don’t do that. My instinct was that adding deny as a means to counteract permit was a natural idiom; certainly that’s how pf works. In retrospect though, a default pass ruleset already is the default, while permit default is certainly not. The keyword should perhaps be escalate. Phrasing it as trying to remove escalation after granting it makes the potential danger more clear.
We’ve been contemplating a different config syntax which reverses the ordering of user and command. Instead of a user focused approach, specify the command first, then the set of permitted users. It should be equivalent in expression, but perhaps the reversed order would encourage users to think about minimal permission grants. I’m not entirely convinced, but I would like it to be at least as natural to express a secure, limited config as a convenient, permissive config.
Coming full circle, the majority of tweaking and polishing of doas now appears to have returned to refinement of the good environment list and the bad environment list. I have built the thing I hate. At least it’s small.
doas was created to run on OpenBSD. I suppose you could port it, but I don’t plan to. Figuring out a replacement for auth_userokay is probably the hard part.