Coding Via Positiva
The first dynamic web application I ever wrote was a content management system to store intellectual property data. This was when I was an intern at Danny Hillis’ think tank, Applied Minds, back in 2003. There were no established content management systems back then and WordPress was brand-spankin’ new as a blogging engine.
Under the guidance of Applied Minds’ Director of Intellectual Property, Dr. Mark Duttweiler, I learned about two technologies that completely blew my mind: PHP and MySQL. Mark taught me how to use PHP to turn static HTML (which I’d been writing since 1995) into dynamic web pages with parameters, calculations, and database interactions. He also taught me the basics of SQL database queries. (The closest thing to a database I’d ever used was FileMaker.) With these new tools, I felt totally limitless.
Every day was a new learning adventure with PHP and MySQL. All I could think about was data organization, query optimization, and building dynamic websites with this incredible technology. It was all blue skies, green fields, and unicorns. No joke: I probably wrote 25 content management systems in 4 years. It was a joy to make something useful for myself and my freelance clients since my computer science program focused primarily on boring Java applications with barely any relevance to the web.
Unfortunately, there wasn’t a real “dev community” or a “dev culture” in these early days of the Internet. No Facebook, no Twitter, no Stack Overflow, no big engineering conferences, no cloud computing, no serverless infrastructure, no JavaScript frameworks. It was difficult to learn sustainable software practices for the web. I had to buy... books (eek!) that were... outdated by the time they were released! By the time any dev culture became established on the web, I moved into full-time management and wrote code solely for side projects.
One mistake that stuck with me for too long was designing flows for the “super admin” user, or “god” user. When designing software systems and applications, it’s easy to begin with the most obvious and streamlined use case, also known as “the happy path.” My code always began with super admin users because it’s the easiest way to build a feature. A lack of limitations on the end user localized all the buggy code to the feature itself. Right?!
Imperfect practice leads to imperfect habits. Being young and inexperienced doesn't help, either.
As I’ve gotten older (receding hairline), wiser (gray hair), and deeper into information security (paranoia), I’ve flipped my thinking. Phrases like “least-privileged access” and “security as a first-class citizen” are at the forefront of my system designs. Now that I’m responsible for the security of personally-identifiable information for millions of end users, I’m always thinking about how a malicious actor can weasel their way through the tiniest bit of insecure code.
In growing philosophically wiser, I’ve learned the terms “via positiva” and “via negativa.” Author Nassim Taleb teaches these concepts in his very excellent Incerto books. He tells the story of Michaelangelo’s carving of the famous statue of David. When asked how he made it, Michaelangelo’s response was, “I simply carved away everything that isn’t David.” In other words, he carved David “via negativa.”
You've probably guessed that “via positiva” is the opposite of "via negativa." It is the concept of adding to something instead of taking away from something.
These concepts can also be applied to software and systems design. In my youth, my default use case started with the “super admin” user. I chiseled away permissions to create less permissive (non-admin) user types. So, I thought of a read-only user as a super admin minus write capabilities. My thinking was problematic for several reasons. You can't "simply carve away everything that isn't super admin."
Building user permissions via negativa can mess with code dependencies. Once a codebase gets to a certain size, I cannot easily account for all my functional assumptions of user privileges. When chiseling away a capability, how do I know that a change to access doesn't inadvertently break something else? Furthermore, when chiseling away from the super admin user, how can I be sure that I’ve removed all of the write capabilities instead of most or some of the write capabilities?
Such problems also extend to data access and structures. Just because a user cannot write to a database doesn’t mean that the user cannot read more than should be permitted! And how can I be sure that data payloads don’t deliver more than the bare minimum necessary when I began with the assumption that a super admin user has access to everything at all times? How do I know that another feature doesn't depend on the larger-than-necessary data payload being returned by my function?
Via negativa just doesn’t work when building safe, scalable, and concise code.
Designing via positiva makes for a very different story. Kicking off my technical design, I can imagine a user with no privileges whatsoever. I can assume the user has access to the system, but cannot actually do anything in the application. A "useless user." Then, via positiva, I can add the appropriate read capabilities with least privileged access. At this point, I can set up read controls such that overreaching queries will throw errors instead of potentially return more data than necessary.
As my codebase grows via positiva, I shouldn’t need to worry (as much!) about broader dependencies because I (should!) have far fewer assumptions of the user’s access, permissions, and capabilities. This makes design much simpler and safer.
Via positiva software design is absolutely essential to building secure codebases. Security-minded developers don't want to get smacked down by the InfoSec team; they want to be applauded. The very last use case to build in code should be the super admin, especially when writing secure software. A super admin should be a last resort and likely should never exist, especially when there is personal information involved.
Back in 2003, all I saw was opportunity. The web was more innocent and people were generally skeptical to share their personal information in any meaningful way. It felt like there was no risk in beginning with a super admin and writing code via negativa.
Fast forward to 2020 and we all want the least amount of information about us available. Worse, nearly everything we do on the web is stored, tracked, and sold. Unfortunately, we now need to play the “via negativa” game with our PII on the Internet, but that’s another thought for another day.