Repository navigation
feat: API authentication with hashed keys and roles (#11) - #39
Conversation
Protect the HTTP API behind Bearer keys (argon2) and optional JWTs while keeping AUTH_ENABLED=false so local demo and existing tests stay open. Closes #11 Co-authored-by: Leonardo <leo-aa88@users.noreply.github.com>
Keep src.api.auth.__init__ empty so TestClient imports do not pull PasswordHasher until a key is actually verified. Refs #11 Co-authored-by: Leonardo <leo-aa88@users.noreply.github.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Code review — PR #39 (issue #11)CI is green. Review is of Checked hashing/logging, middleware exemptions, role map (including GET vs POST must-fixNone should-fixNone nice-to-have
Verdictmust-fix count: 0 What looks correct (not findings): keys are argon2-hashed ( |
Closes #11.
Adds HTTP API authentication so raglogs can be exposed to another service. Default remains off so local demo and existing TestClient tests keep working.
API keys
Authorization: Bearer rlk_…keys stored argon2-hashed inapi_keys(Alembic0004_api_keys).ingest/query/admin) and ascopestring (defaultdefault) for later G8. Log queries are not filtered by scope in this PR.raglogs keys create|list|revoke. The plaintext secret is printed once and never logged.Roles
GET /health,GET /metrics*POST /ingestionsGET /ingestions*POST /query/*GET /config/,/static*,/docsMissing/invalid bearer →
401{ "error_code": "AUTH_UNAUTHORIZED", "message": "..." }. Wrong role →403AUTH_FORBIDDEN.OIDC
Optional JWT validation when
AUTH_MODE=oidcorboth(PyJWT + JWKS cache). Unit tests mock JWKS; no live IdP required.Insecure bind
AUTH_ENABLED=falseon a non-loopback bind logs a warning.AUTH_REFUSE_INSECURE_BIND=truerefuses startup. Docker compose documentsAUTH_ENABLED=truefor a networked API.Tests
Unit tests cover
/healthbypass, 401/403 bodies, role enforcement, revoked keys, mocked OIDC, and the bind guard. Default auth-off path leaves existing API tests unchanged.