Conversation
The retriever /api/v1/ask endpoint drove chat + embedding LLM-gateway calls with no per-user throttle: a single valid subscription token could drive unbounded paid inference (denial-of-wallet, security finding L1). Wire the documented-but-unimplemented ADR-0012 rate limit (slowapi) ahead of the gateway call, keyed on the authenticated user (AuthUser.sub) via a request.state stash set by a dependency chained off require_auth (one JWT decode). Default 10/minute, enabled by default, disableable via config. A 429 returns the ADR-0012 body plus a Retry-After header and exits cleanly through CORS. Per-tenant limiting is a documented forward extension (the token carries no tenant claim today). Refs #261
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
POST /api/v1/askin the retriever service drove chat + embedding LLM-gateway calls with no per-user throttle: a single valid subscription token could drive unbounded paid inference (denial-of-wallet, security finding L1 from the LLM abuse-surface assessment #228). This wires the documented-but-unimplemented ADR-0012 rate limit (slowapi) ahead of the gateway call.AuthUser.sub, stashed ontorequest.stateby a dependency chained offrequire_auth(one JWT decode, no divergent validation). Per-tenant limiting is a documented forward extension: the token carries no tenant claim today, so a per-tenant key would collapse to one global bucket.RATE_LIMIT_ENABLEDfor ops/tests. Fail-closed: a malformedRATE_LIMIT_ASKcrashes app startup (parse_manyat wire time), andswallow_errors=Falsesurfaces limiter errors rather than silently exempting.Retry-Afterheader, and exits cleanly through CORS.services/retriever/.Closes #261
Pipeline phases
test_create_app_wires_limiter_and_handlerto assert the realcreate_app(), dropping a maskingtry/except); delta re-verified via the full gate run.Test results
Both configured gate commands from
.daedalus/config.jsonwere run from the worktree and exited 0.(cd services/retriever && uv sync && ruff check + ruff format --check + mypy --strict) && (cd services/petdata && ... ruff + mypy + bandit) && (cd apps/stacker && npm ci && npm run check)→ exit 0. retriever: ruff clean, format clean, mypySuccess: no issues found in 68 source files. petdata: clean. stacker svelte-check:0 ERRORS 0 WARNINGS.(cd services/retriever && uv sync && pytest tests/ --ignore=tests/integration) && (cd apps/stacker && npm ci && npm run build)→ exit 0. retriever: 382 passed, 10 deselected, total coverage 89.45% (newrate_limit.pyat 100%). stacker:✓ built.(petdata pytest is CI-delegated: it needs Postgres+pgvector on :5434, per
.daedalus/config.json.)Eval scores
No evals configured for this repo.