THIS EXPLANATION
THE ROOM
CDA·75 Computing, Data & AI 6 MIN · 8 STATIONS

Detecting a theft you cannot see

A Socratic walk-through of detecting a theft you cannot see — reasoned out one step at a time, not lectured.

abcdefgh
a

The question we started with

THE QUESTION #

How do you find out a credential was copied when the copy works exactly like the original?

Steal a bicycle and the owner notices, because the bicycle is gone. Copy a credential and nothing is gone. The original still works; the copy works identically; the two are the same string of characters and no examination of either can tell you which came first.

That is a genuinely strange situation to defend, and the usual instinct — look harder at the credential — is guaranteed to fail. If the copy is byte-identical, there is no property to find. So the question is not how to inspect better. It is what could possibly serve as evidence when the thing you want to detect leaves no trace in the object itself.

b

Reasoning it through

REASONING #

Start by being precise about why the problem exists. A bearer token grants access by possession alone: presenting it is the proof. Nothing in the presentation demonstrates that the presenter is the party it was issued to. That property is what makes bearer tokens simple and fast, and it is the same property that makes a copy indistinguishable from an original. The convenience and the vulnerability are one design decision, not two.

Given that, if evidence cannot come from the credential, where can it come from? Only from behaviour over time — from the pattern of use rather than the object used. That is a shift worth naming: you stop trying to observe the theft and start looking for a consequence that theft produces and legitimate use does not.

So what consequence can we manufacture? Here is the move. Make the credential single-use. Each time a refresh token is presented, issue a replacement and retire the one presented — but remember the retired one rather than forgetting it. Now the legitimate holder always has the newest value in the chain, and only ever presents that.

Follow what happens after a copy is taken. Two parties hold the same value. Whichever presents it first is served and receives a fresh token; the other, whenever it next tries, presents a value the server has already retired. And a retired token being presented is something that cannot happen in normal operation. It is not suspicious, ambiguous, or a matter of thresholds — it is proof that the chain forked, which means two holders exist.

Ask what to do with that proof, because the obvious answer is wrong. Refuse the request? That stops the second presenter, but you do not know which presenter is the thief. If the attacker used the token first, the legitimate app is the one now holding a dead value and the attacker holds a live one. So the correct response is to revoke the entire lineage — every token descended from that grant. Both parties are locked out, and the user re-authenticates. This is the token-family invalidation described in the current OAuth security guidance, RFC 9700, published in 2025.

That asymmetry is the honest part of this design: it converts an undetectable compromise into a detectable one, at the cost of a false alarm whenever a legitimate client loses a response mid-flight and retries with a token the server already consumed. Race conditions on flaky networks make that real, not theoretical, which is why implementations allow a short grace window — and why the window is a deliberate trade between missed detection and needless logouts.

Notice too what this does not do. It detects the copy only when both parties use it. A thief who reads the token and uses it exclusively, while the real client sits idle, triggers nothing. Detection is a consequence of contention.

Which raises the better question: could we stop the copy from working at all? Yes, by abandoning the bearer property. If the token is bound to a key the client holds and must be presented with a fresh signature — mutual TLS binding under RFC 8705, or the application-layer scheme DPoP standardised as RFC 9449 in 2023 — then a copied token is inert without the private key that never left the device. That is prevention rather than detection, and it is where the field is heading; rotation is what you do while you still have bearer tokens.

c

The analogy

THE ANALOGY #
THE FIGURE

A serially numbered cloakroom ticket that is exchanged for a new number every time you collect and re-deposit your coat. The attendant keeps the spent numbers. A forger can copy your ticket perfectly, and the copy works — once. The moment either of you presents a number already spent, the attendant knows there are two tickets in circulation, without ever having been able to tell the two apart by looking.

WHERE IT BREAKS DOWN

the attendant can see which person is standing at the counter and could simply ask them, whereas an authorization server sees only two requests over the network and has no way to tell which one came from you, which is why it must lock out both rather than the guilty one.

d

Clarifying the model

THE MODEL #

Three refinements.

First, this is detection, not prevention. Between the theft and the reuse, the attacker has real access. Rotation shortens the window and guarantees the compromise eventually surfaces; it does not stop it.

Second, the signal only exists because the server keeps state. A retired token has to be remembered for the reuse to be recognised, so a design that prides itself on stateless validation has traded away the very record that makes this possible. That is a genuine trade, not an oversight.

Third, the softer signals people reach for — address changes, unfamiliar devices, impossible travel — are a different kind of evidence and should not be confused with this one. They are probabilistic and require tuning against false positives. Reuse of a retired token is categorical: it has one explanation. Both are useful; only one of them is proof.

e

A picture of it

THE PICTURE #
Detecting a theft you cannot see
Detecting a theft you cannot see Steps 1 and 2 are ordinary use, and the note after them is the whole mechanism -- retiring a token while remembering it. Step 4 is the only unusual event in the diagram, and it is unusual in a way that has exactly one explanation. Step 8 is the uncomfortable consequence: your legitimate app is locked out too, because at step 7 the server knew a copy existed but not which participant was holding it. {"generator":"mermaid-svg-renderer@3.2.1","source":"../Socrates/.diagram-cache/_src/detecting-a-theft-you-cannot-see.md","sourceIndex":1,"sourceLine":4,"sourceHash":"a6b4bf61707d1ff5694a0c5c7c24c120eed91e20f1cd5a6be0ffa90cc7b5c367","diagramType":"sequence","layoutVariant":"source","repairedDuplicateIds":[],"motion":"entrance-with-reduced-motion-fallback","presentation":"editorial","attempt":1,"viewBox":{"x":0,"y":0,"width":797,"height":794},"qa":{"passed":true,"findings":[]}} Authorization server 01 Holder of the copy 02 Your app 03 R1 is retired but remembered A retired token in use means two holders exist Presents refresh token R1 1 Access token plus a new R2 2 Presents the copied R1 3 Refused 4 Revoke every token in the family 5 Presents R2 6 Refused so the user must sign in again 7
KINDSlifelineparticipantmessage

How to readSteps 1 and 2 are ordinary use, and the note after them is the whole mechanism — retiring a token while remembering it. Step 4 is the only unusual event in the diagram, and it is unusual in a way that has exactly one explanation. Step 8 is the uncomfortable consequence: your legitimate app is locked out too, because at step 7 the server knew a copy existed but not which participant was holding it.

f

What became clearer

WHAT CLEARED #
WHAT CLEARED

You cannot detect a copy by examining a credential, because a perfect copy has nothing to examine. What you can do is engineer the credential so that copying leaves a mark elsewhere — make each value usable once and remember the spent ones, and the mere fact of a second use becomes proof of a theft you were never able to observe directly.

g

Where to go next

ONWARD #
  • Sender-constrained tokens, and why binding to a device key removes the need to detect copies at all.
  • How grace windows for network retries are chosen, and what they cost in missed detections.
  • The same one-use-plus-memory pattern in other settings, such as nonce tracking against replay.
h

Key terms

TERMS #
TermWhat it means
Bearer tokena credential granting access by possession alone, with no proof that the presenter is the party it was issued to.
Refresh-token rotationissuing a replacement refresh token on every use and retiring the presented one.
Reuse detectiontreating the presentation of an already-retired token as evidence of compromise.
Token familythe chain of tokens descended from a single grant, revoked together when reuse is detected.
DPoP (RFC 9449)Demonstrating Proof of Possession, an application-layer scheme binding a token to a key the client must prove it holds.

Every term the collection defines is gathered in the glossary.

Nearby on the shelf

4