Number 14
August 2, 2023

Don’t corner your users

A long time ago, before we used computers for everything, an office clerk would find it trivially easy to fill out a form and insert it in the middle of a file as if it had been there from the beginning. This practice circumvented all the established procedures for creating and maintaining files, of course, and anyone who could subvert the process so easily could cause real damage with little risk of discovery. For this reason, when offices and governments were computerized, the new computer system’s usual requirement was that users follow the established process to the letter with no exceptions.

A doorway in the middle of a field and a monk boarding it up.“Now, with this blocked off, nobody can get to the other side.”

Now, being so radical is not a good idea. Processes are never error-free: sometimes, someone’s file could enter an inconsistent state that the existing process cannot deal with, forcing us to use extraordinary measures to fix it. If it is impossible to make changes outside the established procedure, errors will pile up, and many people will suffer.

Think of that one person everybody knows, who ended up somehow owing a half-cent to the electric company, and now they keep getting nasty phone calls every week because of this debt that cannot be paid or canceled.

Another drawback to this rigidity is that people will try very hard to do what they set out to do: when encountering an obstacle, they will look for a way around it. I recently listened to a podcast in which Wenceslas (not his name) talked about how learning SQL helped him be more effective in his tech support job. Thanks to knowing SQL, he could connect to the database and directly change it to solve the customer’s problems. I’m sure his employer wouldn’t be happy to hear this, and they would remove his access if they knew, and he would soon find another way to do it.

The reason why we are often asked, as system designers, to enforce the rules rigidly is one of control. Someone designed those rules and procedures to control and monitor all accesses to personal and financial data and to ensure that all operations produce traces and evidence that can be audited and verified afterward. Whenever Wenceslas executes a “SELECT” statement on the database, he circumvents those controls, and nobody knows he accessed a record; when he runs an “UPDATE,” nobody knows he made changes in the data either.

It is proper to block many of these “off-procedure” operations for legal or ethical reasons. However, many others don’t need to be shut off entirely; there should be a mechanism that lets users, with the appropriate permissions levels, perform those operations while preserving the ability to audit, investigate and make people accountable after the fact.

For example, Wenceslas should be unable to log into the database and run whatever SQL statements he wishes. Still, it would be helpful for him to be able to make changes to fix a customer’s problems. Instead of blocking his access completely, we could have a system that asked him to justify his SQL sessions and stored this justification along with the session’s content. Then, someone could review this later and check if the explanation is valid and if the SQL statements he issued match the stated reason.

That’s not the only thing that we can do. For example, if reviewing Wenceslas’s SQL statements after the fact is not enough, we could use a system in which someone else will review and approve his SQL statements before he can issue them. This would work very similarly to code review systems where a second person reviews all code before the author can commit it to the version control system.

It’s very rarely necessary to block an operation entirely. When a customer asks you to do it, try to find an alternative, or the users will feel cornered and find it themselves.

The illustration for this Coding Sheet is based on a drawing by Rembrandt and an engraving from “Germania: dos mil años de historia alemana”.