Invental/Review lessons/Trust boundaries the server must hold

Trust boundaries the server must hold

Never accept fields only the server sets

When callers can pre-fill parts of a state machine, check each pre-filled piece against the same invariants the machine counts on (reachability, iteration). Also shape the input so that duplicates and engine-only flags can't be expressed at all.

01 · Before and afterThe pattern

TypeScript
// before: array input, duplicate check by hand, caller-supplied flags trusted
seededSteps: z.array(z.object({ nodeId: z.string(), outputs: slots }))

// after: one entry per node by construction; engine-only state derived, never accepted
seededSteps: z.record(z.string().min(1), slots).optional()
const reachable = descendantsOf(graph, trigger.id);
for (const id of Object.keys(seededSteps)) if (!reachable.has(id)) throw new GraphValidationError(...);
const stored = { ...graph, seeded: Object.keys(seededSteps) };   // not read from the request

02 · Run it on your appThe check

Can a client of your API send a field that only your server is supposed to set, and does the server keep it?

If the honest answer is no or not sure, this is worth a look before it reaches production.

Want this checked on your code?

Tell us what you are building and what worries you. We match a senior reviewer to your code and confirm scope before anything starts.

— Get in touch
hi@invental.co ↗
— Or
— What to include

A link or short description of the code or system, what you want checked, your stack, and when you need the answer. No repository access is needed until scope is agreed.

— Or leave a note
We reply within one business day.