Skip to content

Cache admission gates, swept for unsafe inputs

Inputs tried, every one up to a size bound, in two separate sweeps (one per gate)

Tenant gate: 976,562,500 inputs, unsafe ones let through: 0

Memory gate: 1,012,500,000 inputs, unsafe ones let through: 0

The two sweeps add to 1,989,062,500 inputs. Weakened gates the checker caught letting an unsafe input through: 14 of 14.

The result

Two admission gates for a shared cache let no unsafe input through in exhaustive sweeps up to a size bound, each weakened version made by dropping one or more of their conditions was caught, and a Rust checker matched the lab's Python reference exactly where both ran

What it does not claim

The total is two separate sweeps added together, one per gate; the two gates were not swept together. Each sweep covers every input up to its bound, and is not a proof for all inputs. For the full gates, admitting nothing unsafe follows from how each gate is written, as all of its conditions at once; what the sweep adds is that the code computes this, and that it catches every weaker gate. It checks a model of each gate, not a deployed cache. The lab points to separate machine-checked proofs for all inputs; this page does not rest on them, and they are not published here.

The limits, in the lab’s words:

Honest scope: the ~1.99e9 is two SEPARATE exhaustive-to-bound single-gate sweeps SUMMED (tenant 9.77e8 = 125⁴·4 + MemGate 1.01e9 = 150⁴·2), NOT a joint sweep of the composed `fullAdmit = tenant ∧ mem` input space; each is exhaustive-to-its-bound, NOT a ∀-inputs theorem (the Lean tight bounds are the ∀-inputs backstop).

Excerpts, word for word from the published file, where the full text can be read.

When several customers share one KV cache, a gate decides whether a cached block may be served to a request, and whether memory may be handed over. The lab wrote two such gates, then built a checker that tries every input up to a size bound and counts the unsafe inputs each gate lets through. It also weakened each gate by dropping one or more of its conditions, to show the checker catches a gate that is wrong. The checker is written in Rust; a slower reference program, which the lab also wrote, in Python, gives the expected answers.

What it shows

In this model: each gate is a yes-or-no rule over a few whole numbers and flags, as written above. The checker tries every combination of values up to a size bound, for each gate on its own.

The tenant gate was tried on 976,562,500 inputs, with each of its four identifiers taking 125 values. The memory gate was tried on 1,012,500,000 inputs, with each of its four addresses taking 150 values. Neither gate let an unsafe input through: the count is 0 for the tenant gate and 0 for the memory gate. Together the two sweeps tried 1,989,062,500 inputs.

Showing the check can fail

A gate that admits nothing unsafe is only half the story: a checker that never finds anything would report the same. So the lab dropped one or more conditions from each gate, which gives 14 weakened gates in all. The checker found an unsafe input that each weakened gate admits, for 14 of them.

Two programs that agree

The Python reference and the Rust checker were run at small bounds that both can finish, where the tenant identifiers take 2 values and the addresses take 3. Their records match exactly: the same counts for every variant, the same verdicts, and the same first unsafe input for each weakened gate. The large sweeps then ran in Rust alone.

Why it matters, and to whom

For teams that share a KV cache between customers, the gate is where a leak would happen. A rule that drops one condition, such as the tenant check on a private block, serves one customer's cached work to another. This result shows each condition is needed: remove any one and an unsafe input gets through, and the checker finds it.

For a buyer, the value is the checker as much as the gates. It agrees exactly with a separate, slower reference program the lab wrote in Python, at the small bounds both can run, and it is shown to catch broken gates.

Why now

Shared prompt caches are now common in model serving, and researchers have shown that they can leak between users, as in the audit of prompt caching cited below. Engines have since added per-customer cache keys. A gate like these checks ownership at the point of reuse, in the lab's model; blocks marked public, and timing side channels like those in the audit, are outside what was checked.

How it was checked

The certificate records the bounds, the counts, the escapes for each gate, the weakened gates caught, and whether the Rust and Python records matched. The extract linked below copies those fields, unchanged, with the certificate's own hash and the lab commit it was read at. The Rust program is identified by its hash in the same extract.

How to reproduce

The extract names the certificate, the Rust program and the lab commit, each by its hash. Anyone with access to the lab's code can rerun the checker and compare. The lab's code is not public yet. The figures and the claim and limits are published here, and each is listed with its hash in the site's receipt manifest.

The two gates

In words: the tenant gate serves a cached block only when its content hash matches the request, it has not been deleted, and it is either public or owned by the asking customer. The memory gate lets a direct memory transfer through only when the block has been cleared, and the transfer's lower and upper addresses lie inside the range the customer owns. An input is unsafe for a gate when any one of its conditions fails.

The result, in the lab’s exact words

Read it with this condition: the total adds two separate sweeps, one per gate; it is not one sweep of the two gates together. Each sweep tries every input up to a size bound, which is not a proof for all inputs. The Rust checker's records were matched to the Python reference at small bounds that both ran; the large sweeps ran in Rust alone.

~1.99 billion adversarial admission inputs → 0 escapes, all 14 conjunct-weakenings broken, native Rust farm bit-for-bit identical to the Python oracle.

Quoted word for word from the lab’s published claim and limits.

Prior art

Evidence

Related results

All results from AxiomLimit · The AxiomLimit home page

How the numbers on this page are checked

Every number on this page links to the file it comes from. All published files.

  • Loadingshown only once its file has loaded in your browser
  • Not checkeda question we have not checked would say so, with no number
  • Checked, nothing founda search that found nothing would say so, with no number
  • No valuea file that holds no value for the question would say so
  • File missinga number whose file is missing or altered would be hidden
  • Unclear subjecttwo files that disagree about what a number describes would both be shown
  • Small samplea number from a small sample would carry its sample size
  • Conflicting filestwo files giving different values would both be shown
  • Not publishablea file we may not publish would be named by its fingerprint only
  • Out of datea measurement older than a week would carry its age
  • Does not applya question that does not apply to this page would say so
  • Run faileda measurement whose program failed would say so, with no number