posted: December 9, 2022
tl;dr: I’ve grown to appreciate the security and simplicity of write-only APIs...
I love it when a software product/service/application (system) has a well-designed, fully-featured Application Programming Interface (API). Ideally the API should allow an external program to do nearly any operation that can be done by a user with maximum privileges using the system itself. This includes accessing all the data managed by the application, with full Create-Read-Update-Delete (CRUD) capabilities. It also includes triggering and performing any action that a user can do. When a software system has this type of API, it becomes possible to write automation software that can do anything the system can do, as well as implement new features. In effect the software system can be easily extended and customized without having to wait for the company or entity that controls it to do so.
That said, I’ve also come to appreciate the elegant simplicity of a write-only API. A write-only API lets an external program send information in one direction: into a software system. The external program cannot read the current state of the system, nor can it read back the information it just wrote. The Read operation within CRUD is prohibited: the external program is typically allowed to Create records, and possibly Update and Delete them. In order to perform the Update and Delete operations, the external program will need to have knowledge about the software system that is obtained through other means, to know what records exist. A write-only API may also allow an external program to trigger or perform a limited set of other actions in the system, by sending in commands, as long as there is no need to read the current state of the system.
The benefits of a write-only API are:
Write-only APIs are common in data collection systems, including marketing analytics tools such as Google Analytics and Twilio Segment. Data is sent into these systems and retrieved via other means. A more interesting write-only API that I’ve used is from Vero, an email SaaS tool startup company. Vero made a conscious decision to implement a write-only API, which stands in contrast to their competitors such as Salesforce Marketing Cloud, which has a fully featured API with both SOAP and REST interfaces. To say Vero took a minimalist approach to their API would be an understatement. There are only a few things you can do with Vero’s API, all related to managing the internal database of email-able people (“customers”, in Vero’s lingo).
Vero’s minimalist, write-only API limits what both good actors and bad actors can do. Being a write-only API, a bad actor that gains access to the API cannot download the customer database, which is a quite common type of security breach. All that a bad actor (or a good actor) can do with Vero’s API is add customers, or modify/delete customers if the customers’ IDs are known. That last point is an important one, and a reason why a user’s email address should not be used as the internal ID in Vero’s customer database. By using some other methodology to assign ID values, such as UUIDs, the IDs are much less likely to be known by a bad actor, especially since the bad actor cannot download the customer database through the API.
Besides being unable to download the customer database, a bad actor cannot use the Vero API to send emails, which is another potentially worrisome type of attack on an email service. Nor can a bad actor download customers’ email activity history to learn what emails have been sent to them. This information exists within Vero, and can be exported via other means which are secured in various ways, but it cannot be done via the API.
Vero is meant to be a simpler, lower-cost email service than more fully-featured products like Salesforce Marketing Cloud. They are not (yet) trying to be all things to all people, or go after large corporations as an enterprise-wide tool. A write-only API suits Vero well, in my opinion. It certainly simplifies (and shortens) Vero’s API development task. It also significantly cuts down on customer support issues, and the potential for major hacking incidents. Although I appreciate a fully featured API, I can understand and agree with what Vero did.