Notes

An operator's look at your account is written down

If one of our operators opens your account's history, that read is written into it, naming them. The platform-wide view is filed under the operator instead.

When an operator opens one customer's history, that read is written into the same history, naming the operator. The one view that cannot work that way, the platform-wide river of recent activity, is filed under the operator instead. A surface that can read everything and records nothing is the one thing an operator tool must not be.

This post is the rule, the case where it had to bend, and what it still does not record.

Operators are rows, and so are their reads

An operator is a person on our side who may read across accounts. They are not a customer with extra rights. An operator is a row in a table of their own, signs in with an email and a password against that table, and has an id in a different namespace from every customer's, so the two kinds of principal read as different at a glance in the event log.

An operator is added by one command, run by somebody who can already reach the database. There is no invite and no reset flow, because a reset would be a way into the most powerful surface we own that starts with a mailbox, and mailboxes are outside everything this platform controls.

Every route on that surface writes an event, and the event is filed where the affected person would look:

If an operator opens your account's history, that read is written into the same history, under your account, naming the operator.

That sentence is on the privacy page. The reasoning is that the person with the strongest claim to know their history was read is the person whose history it is. Who did the reading is carried on the line, so it says that somebody from the platform read this, and which somebody.

One view could not obey the rule

The rule was written when every route named one account. Then the operator surface gained a river: every event across every account, newest first, refreshed every fifteen seconds.

Filing a read of the river under each customer on the page is faithful to the rule and unusable. A river across thirty accounts would write thousands of operator rows an hour into customers' histories, and those rows would flow back into the river being watched. The record would drown the thing it records.

So the river writes one event, under the operator. Opening one customer's history is unchanged and still lands under that customer.

That made a sentence on the privacy page untrue, and the page changed in the same release. It now says the other half out loud: a line of yours can be seen in the platform-wide view without a line appearing in your history, because opening that view is recorded against the operator who opened it. Anything an operator does to your account, such as stopping a site, putting it back, suspending or restoring the account, or releasing a domain, is still written under your account, naming them.

The same fact, counted honestly

Two smaller decisions keep the record from lying about itself.

One look is written per question, and the number of questions is kept small on purpose. Opening an account page asks for the account's history, its standing and its sites, and each question is written under that customer. The account's standing, including whether it is suspended, rides along on a read that is already made once per view, rather than getting a route of its own that would add another line to somebody's history for one look.

The river opens on customers' activity, and the operator's own rows are one segment away. Most of an unfiltered river was the operator watching the river. The split between the two sides is by who acted, and customer activity is defined as everything that is not an operator's, so an actor added next year appears under customers rather than under neither. A filtered read is still a read and still writes its own row. An account's own history opens on both sides, because there the operator's rows are the promise being kept.

What it does not record

Three gaps are real, and the decision names them rather than implying otherwise.

  • A stranger who fails to sign in leaves nothing in the event log. An event is filed under an account, and the only name a failed attempt supplies is one the caller typed. Recording those would let a stranger choose which strings appear in a table indexed by account. A successful sign-in is recorded.
  • A refused caller leaves nothing either. Holding a session is what being an operator is, so a caller without one is a stranger, and the account column cannot hold a stranger.
  • Whatever can write the control-plane database can grant itself operator rights. That is the price of an operator being a row rather than an entry in a deployment file. It is recorded rather than argued away.

The upside was named at the same time: an operator can be added or removed without a deploy, and getting in does not depend on a vendor's console being reachable on the day it is not.

The rule, once

Every read an operator makes is an event, filed under the customer it names, and the one view that names no single customer is filed under the operator and says so in public. The tools and their refusals are listed in the docs.