A trail is a set of technical traits that turned up on the same orders, kept together for that reason and for no other. It is not a person, it is not an account, and nothing in the system ever decides that it is one buyer. This article is about why the weaker claim is the more useful one, and what it costs somebody to get out from under it.
The property
A trail is a property of history, not of a person. Traits that appeared together on orders where harm was later confirmed stay linked, and a fresh trait that appears beside them inherits that link. Nobody asserts that a trail is one person. The record only says that these things were seen together.
Why it holds
The case this was built after
Before there was anything to send a check to, an Estonian online retailer worked a run of fraudulent orders backwards through its own logs. Several orders over a few days, each of which had looked ordinary when it was taken. What tied them together was not a name and not an account, because those were different every time. It was a small set of technical traits that kept turning up in the same company.
The interesting part was how the set held. One order shared a trait with the next, that order shared a different trait with the one after it, and by the end the chain covered orders with nothing visible in common. When the shop confirmed the harm and marked those orders, the marks landed on the set rather than on a person, and nobody had to work out who was behind it. The useful object turned out to be smaller than a person and much easier to be sure about.
Figure 1
Co-occurrence, not assertion
A link exists for exactly one reason: two traits were on the same order. That is an observation with an order reference behind it, not an inference, and not a claim that two things belong to the same human being. An identity resolution system would take the next step, decide that a group of records is one person, and reason about the file it had opened. Heatrail declines that step.
The consequence sounds strange written down, and it is the point of the design: a trail can be wrong about a person and still be right about history. If two unrelated people genuinely shared a trait on one order, the record that they shared it stays true, and the statement that would have been false is the one nobody made.
It also settles the language. A check answers that this order touches a trail on which harm has been confirmed. It never answers that this buyer is a fraudster, because the system holds no subject about whom such a sentence could be formed. What comes back is a score and reasons about the order, and a person at the shop decides what to do with them, which is the subject of advisory by construction and of reasons you can read.
Inheritance, and why rotation resets nothing
A trail grows the same way it started. If an order carries a trait already on a trail, everything else on that order is now linked to it too, including something never seen anywhere before. It arrives beside something that is not new, and the link is made by the part that is not new.
That is most of the answer to the obvious question about a system like this one, which is why somebody does not simply change the identifier and carry on. Changing one identifier produces an order carrying a fresh trait next to familiar ones. The fresh trait joins the trail on arrival, and stays on it in its own right, so the replacement cost something and gained nothing.
Figure 2
One trail, a different name in every shop
A trail has no public identifier. Each shop sees one under an opaque alias generated for that shop alone, so the same trail carries a different handle in every member shop, and two shops laying their records side by side cannot line the handles up. The property is part of the contract in the API reference: stable for you, different for everybody else looking at the same thing.
It is useful for your own records, where it lets a shop group its own orders and refer to the same thing twice. It is not a key into the network: it cannot ask about a trail your orders never touched, and a request about another shop's resource is answered as though the resource did not exist, which is the isolation rule. A handle that travelled between shops would become the thing people talk about, and a thing people talk about becomes a thing people treat as a person.
What it costs to evade
What the attacker spends
Every trait that touched the trail has to be absent from the next order, all of them, at once. One repeat undoes the effort, because a single familiar trait beside the new ones rebuilds the link and carries the trail forward onto everything else on that order. This is not one new address or one new number. It is the whole set, on every order, from now on, in every shop in the network, with no way to find out whether it worked, because the answer goes to the shop and never to the buyer.
What the attacker gains
One more order, in one more shop, which can mark it the same day. The signal is the network's rather than one shop's, so the shop that confirms the harm need not be the one hit first. Total replacement buys a single transaction and then has to be performed again, in full, for the next one. The two sides are not close, and that asymmetry is what the design is for.
Verify it
The claim here is about what a response is allowed to say, so it is checked by reading one. Send a check for an order of your own:
# Sign it for real and send an Idempotency-Key: both are checked before the
# payload is, so a placeholder signature answers 401 and a missing key 400.
curl -s -X POST https://api.heatrail.eu/v1/check \
-H "Content-Type: application/json" \
-H "Authorization: HR1 {key id}:{signature}" \
-H "Idempotency-Key: chk-verify-what-a-reason-says-01" \
-d @order.json
# What comes back: a score, reasons that describe this order and the
# trail it touched, and an opaque trail_alias that means something
# only inside your shop. No name, no account, no other shop's data,
# and no sentence about a buyer.Then read the response fields and the reason codes in the API reference as a set, and notice what kind of sentence they all are. Each describes the order in front of you, or the trail that order touched. None describes a person, and there is no field in which such a description could be put.
The second half is the alias. Take a reference your shop never received and ask for it. You get 404 not_found, the same answer as for a reference that never existed anywhere, so an alias is a handle inside your own account rather than a way across the network. The security page explains why that status code and not the more obvious one.
Legal footing
A trail is a set of pseudonymised technical traces (Article 4(5) GDPR), linked by co-occurrence and held for a bounded period (Article 5(1)(e), see forgetting on schedule). Scoring an order against a trail is profiling within Article 4(4), and we say so rather than arguing our way out of a definition: personal data is evaluated automatically to predict something about a person's behaviour. Profiling is lawful on the shop's Article 6(1)(f) basis, and it is what makes the shop's duties under Articles 13(2)(f) and 15(1)(h) answerable, which is why the reasons come back in sentences (reasons you can read). What it is not is a decision within Article 22: nothing follows from the response by itself (advisory by construction). See the data processing agreement and the trust center.
Related
- Identity without identities, on what the traits are by the time they reach us, and why a hashed value is still personal data.
- Heat, and what cools it, on what a confirmed label does to a trail, and what does not undo it.
- Corroboration, on why one shop's view of a trail is not the network's view of it.
- Why the network cannot be enumerated, on the other reason a trail alias is not a lookup key.