Skip to content

feat(settings): per-organization provider API key management - #2

Merged
sanddx97 merged 1 commit into
mainfrom
feature/provider-credential-settings
Jul 6, 2026
Merged

sanddx97 merged 1 commit into
mainfrom
feature/provider-credential-settings

Conversation

@sanddx97

@sanddx97 sanddx97 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds an encrypted-at-rest provider_credentials table so each organization can configure its own LLM (openai/anthropic/gemini/groq/openrouter), embedding/reranking (voyage/jina/cohere), and vector-index (pinecone) provider keys from a new Settings page, instead of relying solely on platform-wide env vars.
  • Org-configured keys take precedence over the env-var default everywhere a provider is constructed (backend LLM Gateway; worker embedding/index/reranking factories). Orgs that haven't configured anything fall back to existing behavior, unchanged.
  • Motivated by the earlier production incident where OPENAI_API_KEY was only configurable via a platform-wide env var with no per-org override and no UI path to fix it.
  • Also includes a previously-pending fix: worker/Dockerfile now pins Celery's --concurrency=2 (it previously defaulted to the host's visible CPU count — 48 on Railway — causing repeated OOM SIGKILLs).

Security note

CREDENTIAL_ENCRYPTION_KEY ships with an insecure hardcoded dev default (documented inline, same pattern as jwt_secret_key). Before this is used in production, set a real value (Fernet.generate_key()) on both the Railway backend and worker services — identically on both, since each decrypts independently.

Test plan

  • Backend: pytest — 165 passed (7 new tests for the new endpoints/service), migration verified upgrade→downgrade→upgrade, ruff/mypy clean
  • Worker: pytest — 151 passed, 9 skipped (unset cloud keys, expected), ruff clean
  • Frontend: tsc --noEmit and lint clean on all new files
  • CI

🤖 Generated with Claude Code

Adds an encrypted-at-rest credential store (provider_credentials table)
so each organization can configure its own LLM/embedding/reranking/
vector-index provider keys from a new Settings page, instead of relying
solely on platform-wide env vars. Org-configured keys take precedence
over the env-var default everywhere a provider is constructed (backend
LLM Gateway, worker embedding/index/reranking factories); orgs that
haven't configured anything fall back to existing behavior unchanged.

Motivated by the earlier embeddings-not-working incident on Railway,
where OPENAI_API_KEY was only configurable via a platform-wide env var
with no per-org override and no UI path to fix it.

Also includes a pending fix from earlier this session: worker/Dockerfile
now pins Celery's --concurrency=2 (previously defaulted to the host's
visible CPU count, 48, causing repeated OOM SIGKILLs on Railway).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sanddx97
sanddx97 requested a review from Life180Labs as a code owner July 6, 2026 04:15
@sanddx97
sanddx97 merged commit ef74194 into main Jul 6, 2026
0 of 3 checks passed
@sanddx97
sanddx97 deleted the feature/provider-credential-settings branch July 6, 2026 04:17
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