Skip to content

THU-505: Move model API keys to local-only table#858

Open
raivieiraadriano92 wants to merge 11 commits into
mainfrom
raivieiraadriano92/thu-505-models-secrets-local-only-table
Open

THU-505: Move model API keys to local-only table#858
raivieiraadriano92 wants to merge 11 commits into
mainfrom
raivieiraadriano92/thu-505-models-secrets-local-only-table

Conversation

@raivieiraadriano92
Copy link
Copy Markdown
Collaborator

@raivieiraadriano92 raivieiraadriano92 commented May 12, 2026

Summary

  • Moves api_key out of the synced models table into a new local-only models_secrets table that PowerSync never syncs — API keys never leave the device
  • All model DAL queries LEFT JOIN with models_secrets so consumers still get apiKey transparently
  • Adds warning indicator (amber triangle + tooltip) in model picker and settings list for models missing an API key
  • Adds edit/delete button group to model cards with an edit modal for updating model config and API keys
  • Removes api_key from E2EE encrypted columns and backend schema (with migration)

Test plan

  • Create a model with API key → key stored in models_secrets, not in models
  • Edit model API key via edit modal → models_secrets updated, warning disappears
  • Delete model → models_secrets row deleted
  • Default/system models load correctly with apiKey: null, no warning shown
  • Model picker shows warning icon + tooltip on models without API key, disables selection
  • AI chat works with API-key-based providers (OpenAI, Anthropic, etc.)
  • TypeScript compiles, lint passes, all tests pass

🤖 Generated with Claude Code


Note

Medium Risk
Schema and DAL changes move apiKey storage and retrieval, which can break model configuration and provider authentication if joins/migrations are wrong, but scope is limited to models/settings UI and persistence.

Overview
Moves model API keys out of sync scope. Drops api_key from the backend powersync.models table (new migration + updated Drizzle schema) and removes it from the E2EE encrypted-columns list.

Introduces a local-only models_secrets table in the client SQLite schema and PowerSync app schema (marked localOnly) to store apiKey on-device only, with new relations.

Updates the models DAL to transparently include apiKey. All model reads now LEFT JOIN models_secrets, and createModel/updateModel/resetModelToDefault/deleteModel manage secrets in transactions (including manual upsert behavior).

UI/UX updates for missing keys and editing. The model selector and models settings list now flag and disable models that need an API key but don’t have one (amber warning + tooltip), and the settings page replaces the removed detail/new routes with an inline edit modal plus a consolidated delete confirmation.

Tests adjusted/added to cover models_secrets persistence, join behavior, update semantics, and cascade delete.

Reviewed by Cursor Bugbot for commit 5750349. Bugbot is set up for automated code reviews on this repo. Configure here.

@raivieiraadriano92 raivieiraadriano92 self-assigned this May 12, 2026
@raivieiraadriano92 raivieiraadriano92 changed the title Raivieiraadriano92/thu 505 models secrets local only table THU-505: Move model API keys to local-only table May 12, 2026
@github-actions
Copy link
Copy Markdown

Semgrep Security Scan

No security issues found.

@raivieiraadriano92 raivieiraadriano92 marked this pull request as ready for review May 12, 2026 12:36
Comment thread src/settings/models/index.tsx
Comment thread src/dal/models.ts
Comment thread src/dal/models.ts Outdated
Comment thread src/settings/models/index.tsx Outdated
Comment thread src/settings/models/layout.tsx Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 14, 2026

Preview environment deployed 🚀

Service URL
Marketing / blog / docs https://thunderbolt-pr-858.preview.thunderbolt.io
App https://app-pr-858.preview.thunderbolt.io
API https://api-pr-858.preview.thunderbolt.io
Keycloak https://auth-pr-858.preview.thunderbolt.io
PowerSync https://powersync-pr-858.preview.thunderbolt.io

Stack: preview-pr-858 · Commit: 57503494f3b2fdd21b5a395e6875e1a2758eb26c

Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — demo@thunderbolt.io / demo by default.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 14, 2026

PR Metrics

Metric Value
Lines changed (prod code) +391 / -648
JS bundle size (gzipped) 🟢 1.02 MB → 1.02 MB (-3.6 KB, -0.3%)
Test coverage 🟡 71.47% → 71.14% (-0.3%)
Performance (preview) Preview not ready — Render deploy may have timed out
Accessibility
Best Practices
SEO

Updated Fri, 15 May 2026 10:36:49 GMT · run #1504

Comment thread src/settings/models/index.tsx Outdated
Comment thread src/settings/models/index.tsx
Comment thread src/dal/models.ts
Comment thread src/components/ui/model-selector/model-selector.tsx Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5750349. Configure here.

Comment thread src/defaults/models.ts
model.provider,
model.model,
model.url,
model.apiKey,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hash algorithm change breaks modification detection for existing models

Medium Severity

Removing apiKey from the hashValues array in hashModel shifts every subsequent field one position left, producing a completely different hash — even when apiKey was always null for system models. Any model with a previously stored defaultHash (computed with the old algorithm) will now fail the equality check in isModelModified, causing all such models to incorrectly display as "customized" with a reset indicator.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5750349. Configure here.

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.

2 participants