Skip to content

[Security][High] encryptionKey() retains SUPABASE_SECRET_KEY fallback — secret isolation not enforced at the source #98

@bmersereau

Description

@bmersereau

Problem

backend/src/lib/userApiKeys.ts:40–47:

function encryptionKey(): Buffer {
  const secret =
    process.env.USER_API_KEYS_ENCRYPTION_SECRET ||
    process.env.API_KEYS_ENCRYPTION_SECRET ||
    process.env.SUPABASE_SECRET_KEY;  // ← last-resort fallback
  ...
}

assertSecretIsolation() (PR #74) prevents the server from starting when secrets overlap — but it only fires at startup. The encryptionKey() function itself still accepts the Supabase service key as a fallback. If the isolation check is ever not wired (e.g., a different entrypoint, a test environment), user API keys would be encrypted under the same secret used for JWT verification.

Impact

A single SUPABASE_SECRET_KEY leak would expose all stored user LLM API keys. PR #74 added a startup check but did not remove the root cause.

Fix

Remove the SUPABASE_SECRET_KEY fallback from encryptionKey(). Require USER_API_KEYS_ENCRYPTION_SECRET unconditionally — throw new Error("USER_API_KEYS_ENCRYPTION_SECRET must be set") if absent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions