onewayglass
Retrieval that cannot tell you what it hid. v0.2.1 · API docs · health
The leak, in one request
No token needed. Counts only, over a corpus of synthetic fiction.
curl "{HOST}/attack?q=compensation+bands+redundancy+acquisition"
The naive counts differ between principals. The enforced counts do not. That difference is the entire result.
Or run it yourself, as two different people
curl -H "Authorization: Bearer demo-u_ic_eng" \
"{HOST}/search/naive?q=redundancy+planning+next+fiscal+year"
# result_count: 0 of 5 requested. Three restricted documents matched.
curl -H "Authorization: Bearer demo-u_exec" \
"{HOST}/search/naive?q=redundancy+planning+next+fiscal+year"
# result_count: 5. The difference between these two numbers is the leak.
curl -H "Authorization: Bearer demo-u_ic_eng" \
"{HOST}/search?q=redundancy+planning+next+fiscal+year"
# result_count: 5. Identical to the CEO's. Content differs; the count does not.
Tokens
Published deliberately — the corpus is fiction and there is nothing to protect. They exist because count-stability is a claim about what different authenticated callers can observe, so it cannot be demonstrated from one anonymous endpoint.
| token | who | dept / level | may read |
|---|---|---|---|
demo-u_ic_eng | Engineer | engineering / IC | 13 of 35 |
demo-u_lead_eng | Eng Lead | engineering / LEAD | 17 of 35 |
demo-u_dir_eng | Eng Director | engineering / DIRECTOR | 20 of 35 |
demo-u_ic_sales | Account Exec | sales / IC | 11 of 35 |
demo-u_dir_sales | Sales Director | sales / DIRECTOR | 15 of 35 |
demo-u_ic_people | People Partner | people / IC | 10 of 35 |
demo-u_dir_people | People Director | people / DIRECTOR | 14 of 35 |
demo-u_exec | CEO | exec / EXEC | 35 of 35 |
demo-u_contractor | Contractor | external / IC | 10 of 35 |
A timing channel survives this
Count-stability is a partial defence. The count channel is closed; a timing channel of about 1.8 µs remains, and the padded arm is faster — so it leaks “this query had few readable matches for you”. Measured at median SNR 0.73 and published rather than buried, because the project’s own thesis committed to that before the code was written.
Endpoints
| route | auth | what |
|---|---|---|
GET /attack | none | the attack across all 9 principals |
GET /search | bearer | enforced: count-stable |
GET /search/naive | bearer | the leaking path, deployed unfixed |
GET /whoami | bearer | this token’s own access |
GET /health | none | asserts count-stability at runtime |
Rate limit 120 requests per 60s per token, in-memory and per-instance.