Access · Back office · Engineering

The allowlist that was a date, not a rule

Twelve findings read “Your account doesn’t have access to this”. One list in the gate named fourteen settings a kitchen may change, and nothing added since.


A tester working through the back office as a kitchen owner filed twelve findings that read the same way: tap a toggle, save a form, change a setting, and the screen said Your account doesn’t have access to this. Store notices, the table map’s reset, QR code options, prep areas, what guests see, delivery statements, the printing centre, the manager PIN. Twelve rows on the sheet, twelve different screens, and the natural reading is twelve bugs.

It was one line of code. The gate that decides what a kitchen’s account may change held a list of fourteen named settings under the venue, written the day the kitchen role was added. Everything built since then, and a food-hall product builds a setting a week, fell outside the list and was refused. The list was not a rule about what a kitchen may touch. It was a photograph of what existed on the day somebody wrote it.

Why nobody noticed for weeks

The owner account sees everything, so the person building the settings never met the refusal. Every new screen was tested as the owner and shipped. The first person to use them as a kitchen was the tester, and by then there were twelve of them. An allowlist fails quietly in exactly this way: the thing it forgot does not crash, it just says no, and a no looks like a permission decision somebody meant.

The rule we replaced it with

A kitchen may change any setting that belongs to its own venue. That is the sentence the product had always meant, so that is now the code: any path under the venue you hold a grant on, with two named exceptions that are genuinely the platform’s, the venue’s root record (its code, which hall it trades in, whether it is open at all) and closing it down. A manager is still kept out of payouts and of other people’s permissions, by name, because those two were decisions rather than oversights.

Two more refusals hid behind the same sentence. The settings route refused anyone below the platform owner, although the route itself had scoped a kitchen’s write to the kitchen’s own row for months. And the kitchen-screen policy looked up the role from a column that reads member for every account that gets its rights from a grant, so it refused the owner of the kitchen whose screen it was.

How it is pinned

We drove nine venue writes through the real gate as the kitchen, the same nine as its manager, and the same nine from the kitchen next door, which must all be refused. Then a matrix over every write route in the product, to see what a kitchen is now kept out of: its venue’s root record, the delete, and the platform’s own families. Nothing else. The twelve rows closed in one release, and the reply to the tester was one paragraph, not twelve.

If your gate holds a list of things somebody may do, ask when it was written. If the answer is a date, it is already wrong.


Try it on tonight’s service.

Nothing to install, no card. Not better by the weekend? Close the tab.