Skip to content

Hosting fixes: security, read-only DB creds, per-request OpenAI key - #18

Merged
Jenny (mrscoopers) merged 4 commits into
mainfrom
hosting-fixes
Jul 3, 2026
Merged

Jenny (mrscoopers) merged 4 commits into
mainfrom
hosting-fixes

Conversation

@mrscoopers

Copy link
Copy Markdown
Collaborator

Prep for hosting the demo on Vercel with Qdrant-owned infra.

Fixes

  • CORS: origin-locked via CORS_ORIGINS env (drops invalid * + credentials).
  • /api/neo4j/stats: plain MATCH counts instead of db.labels()/APOC, so a read-only Neo4j role (which can't execute procedures) works.
  • Safe error logging: logger.opt(exception=True).error("...", e) so Neo4j error messages containing { } no longer crash the handler and mask the real error (was in the main search path too).

Feature

  • Per-request user-supplied OpenAI key: demo users provide their own key so the host never pays for inference. Threaded through the pipeline; module-global OpenAI clients removed; rejected keys → HTTP 401 openai_key_rejected. Unit tests added.

Misc

  • Summarization no longer counted as a "tool" in the trace.

🤖 Generated with Claude Code

Jenny (mrscoopers) and others added 4 commits July 3, 2026 12:46
…r logging

- CORS now driven by CORS_ORIGINS env (default localhost:3000); drop invalid
  allow_origins=* + allow_credentials=True combo.
- /api/neo4j/stats uses plain MATCH label counts instead of db.labels()/APOC,
  which a read-only Neo4j role is forbidden from executing.
- Replace logger.error(f"...{e}...") with loguru-safe logging so Neo4j error
  messages containing { } braces no longer crash the handler and mask the real error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Demo users supply their own OpenAI key so the host never pays for inference.

- SearchRequest.openai_api_key (required); threaded through
  run_tools_sequence_and_summarize -> tool_calling / AsyncQdrantQuery /
  AsyncQdrantVectorStore. Removes the module-global OpenAI clients.
- Key used for both the LLM agent and query-time embeddings (direct or via
  Qdrant Cloud Inference header). Never stored or logged.
- Rejected keys surface as HTTP 401 detail=openai_key_rejected so the frontend
  can reopen its key gate.
- Tests: key threading + openai_api_key required.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summarization is a phase, not a retrieval/graph tool. Drop the
ToolExecution(name='summarize') from the trace so it is never counted as a
'tool executed' (was causing a 4-vs-3 mismatch between the trace panel and
the chat header).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy of Dockerfile without COPY data/ — the serving backend only queries
Qdrant + Neo4j and never reads the JSON datasets at runtime (config warns,
doesn't fail). Reads $PORT (Vercel injects it). A Dockerfile.vercel.dockerignore
keeps the build context lean without affecting the legacy Dockerfile.

Validated: image builds and the container boots + serves /health.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mrscoopers
Jenny (mrscoopers) merged commit 613372d into main Jul 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant