Hardening a public agent endpoint
The Copilot on this site is an unauthenticated, tool-using agent on an endpoint that spends money per request. Every control that holds it up is linked to the file that implements it and the test that would catch its removal.
The Copilot on this site is a public, unauthenticated, tool-using agent on an endpoint that spends money per request — the same shape as the agent surfaces I build on platforms, at a size where I own every line of it.
No login, no human in the loop, no one watching a dashboard. Every control has to hold against an anonymous caller and against a model that can be argued with, and it has to hold overnight.
I worked the trust boundary a class at a time: prompt injection through retrieved and page text, tool-call abuse turning the navigation tool into an open redirect, unbounded request bodies on an endpoint whose Content-Length is client-controlled, and volumetric cost abuse. Each class got a control that fails closed and a test that fails the build.
Six controls, each linked below to its implementation and its test. The limiter denies rather than serves when KV is unreachable, the only side-effecting tool resolves against a closed allowlist server-side before anything is streamed, and the public MCP route answers from a bundled index while making no model calls at all.
// an unreachable counter denies the request, it does not wave it through
// retrieved and page text enters the prompt as data, never as instructions
- — Failing closed means a KV outage returns 503 instead of serving the assistant unmetered — availability traded for a bill I can predict.
- — The CSP is still Report-Only. Enforcing it would block Astro's per-build inline hydration scripts until they are hashed, and a policy that breaks the page is worse than one being observed.
- — The rate-limit counters are read-modify-write on KV, so under concurrency they under-count — and a contended write is tolerated rather than denied, since the shared daily key collides under ordinary multi-user traffic. Exact enforcement needs a Durable Object, which this traffic does not justify.
Want something like this built, or want to talk about the work?