Skip to content

Make auth/MCP client timeouts and JWKS cache settings admin-configurable #69

Open

Description

@prometheusgr

Context

Same audit as #68 (docs/CONFIG_AUDIT_2026-09-04.md, Part 2) found a second cluster of hardcoded operational knobs, this time around JWKS caching and outbound HTTP timeouts for Keycloak and the doc-search MCP client. None of these are covered by the existing SystemSettings-backed config (LLM/embedding provider, retention, guardrails, tracing, rate-limiting).

Gaps found

JWKS caching (auth):

  • backend/app/core/auth.py:20 — _JWKS_CACHE_TTL = 600 (10 min)
  • mcp-servers/doc-search/app/auth.py:26 — _JWKS_CACHE_TTL = 600 (duplicated in the second deployable, own cache)
  • mcp-servers/doc-search/app/auth.py:40 — _JWKS_REFETCH_COOLDOWN_SECONDS = 30 (rate-limits forced refetch on an unknown kid, protecting Keycloak from being hammered)

Outbound HTTP timeouts:

  • backend/app/api/auth.py:141 — timeout=10.0 on the Keycloak token-exchange POST (login/refresh)
  • mcp-servers/doc-search/app/auth.py:79 — timeout=10.0 on the JWKS fetch
  • backend/app/mcp_client/doc_search_client.py:30 — MCP_CALL_TIMEOUT = timedelta(seconds=30) (the actual search_knowledge_base tool call)
  • backend/app/mcp_client/doc_search_client.py:63 — _CONNECT_TIMEOUT_SECONDS = 30.0
  • backend/app/mcp_client/doc_search_client.py:64 — _SSE_READ_TIMEOUT_SECONDS = 300.0

All are plain numeric values, resolved (or read) fresh on every call/request — none require a process restart to take effect, unlike tracing_enabled.

Why bundle these together

Same resolver pattern, same "Timeouts & Caching" Settings UI section, and an operator tuning one (e.g. a slower Keycloak, or doc-search under heavier load) plausibly wants to tune several together.

Scope

  1. Add nullable SystemSettings columns for each value above (7 fields total; the two _JWKS_CACHE_TTL constants should share one setting since they're the same knob duplicated across two deployables — doc-search already resolves its own DB-backed config independently the way embedding_provider does, so this is a proven pattern to copy).
  2. resolve_timeout_config (or fold into an existing resolver if a smaller shape emerges during implementation) following docs/BACKEND_SERVICES.md.
  3. Wire each into its call site, replacing the module constants.
  4. Settings UI: new "Timeouts & Caching" section, tooltips per field.
  5. Audit-log on change, following the existing pattern.

Non-goals

  • keycloak_client_secret and rate_limit_trusted_proxy_count are explicitly excluded — they were reviewed in the same audit and judged not to be configurability gaps: the former is a credential (DB-storing it via this pattern would be a security regression), the latter is fixed deployment topology that's security-sensitive if misconfigured. Do not add these here or elsewhere without a separate, explicit design discussion.
  • No retry/backoff logic is added here — see the separate retry/backoff issue. This issue is timeout values only, not retry behavior.

Definition of Done

  • New nullable SystemSettings columns + Alembic migration for the 6 distinct knobs (JWKS TTL shared across both deployables, JWKS refetch cooldown, Keycloak token-exchange timeout, doc-search JWKS fetch timeout, MCP call/connect/SSE timeouts).
  • Resolver service function(s), unit-tested.
  • All knobs wired into their actual call sites in both backend/ and mcp-servers/doc-search/.
  • Settings UI section with tooltips; component-tested.
  • Audit logging on change.
  • RBAC call-out per AGENTS.md TDD Discipline step 0: admin feature, gated by require_admin.
  • Standard merge gate from AGENTS.md's Definition of Done applies in full.

Activity

  1. added
    polishAdmin/UI surfacing or refinement of existing capability, not new functionality
    type:improvementMakes an existing capability better/safer/more complete
    effort:MMedium: one layer (backend or frontend), a few days
    area:auth-securityKeycloak, secrets, JWT, timeouts, resilience of external calls
    on Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:auth-securityKeycloak, secrets, JWT, timeouts, resilience of external callseffort:MMedium: one layer (backend or frontend), a few dayspolishAdmin/UI surfacing or refinement of existing capability, not new functionalitypriority:P2Valuable, not urgenttype:improvementMakes an existing capability better/safer/more complete

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions