Fix MCP crash when DB key exists without NEXUS_MASTER_KEY
KeyResolver now wraps getApiKey in try/catch and falls back to env instead of crashing startup. ProvidersStore.getApiKey returns undefined when the cipher is disabled rather than throwing. Server starts cleanly with env-only, and uses the encrypted DB key when the master key is present.
This commit is contained in:
@@ -133,12 +133,17 @@ export class ProvidersStore {
|
||||
this.db.prepare('DELETE FROM providers WHERE name = ?').run(name);
|
||||
}
|
||||
|
||||
/** Return the decrypted API key for a provider, or undefined. */
|
||||
/**
|
||||
* Return the decrypted API key for a provider, or undefined.
|
||||
* Returns undefined (instead of throwing) when no master key is configured,
|
||||
* so callers can gracefully fall back to env keys.
|
||||
*/
|
||||
getApiKey(name: string): string | undefined {
|
||||
const row = this.db.prepare('SELECT api_key_enc FROM providers WHERE name = ?').get(name) as
|
||||
| { api_key_enc: string | null }
|
||||
| undefined;
|
||||
if (!row?.api_key_enc) return undefined;
|
||||
if (!this.cipher.enabled) return undefined;
|
||||
return this.cipher.decrypt(row.api_key_enc);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,18 @@ export class KeyResolver {
|
||||
resolve(providerName: string, defaultBaseUrl: string): ResolvedProvider {
|
||||
const dbRow = this.store?.get(providerName);
|
||||
const envKey = this.envKeyFor(providerName);
|
||||
const dbKey = this.store?.getApiKey(providerName);
|
||||
// DB key may be unreadable (no master key / rotated key). Degrade gracefully:
|
||||
// fall back to env instead of crashing startup.
|
||||
let dbKey: string | undefined;
|
||||
try {
|
||||
dbKey = this.store?.getApiKey(providerName);
|
||||
} catch (err) {
|
||||
log.warn(
|
||||
`could not read stored key for "${providerName}" (falling back to env)`,
|
||||
err instanceof Error ? err.message : String(err)
|
||||
);
|
||||
dbKey = undefined;
|
||||
}
|
||||
|
||||
const apiKey = envKey ?? dbKey;
|
||||
const keySource: ResolvedProvider['keySource'] = envKey ? 'env' : dbKey ? 'db' : 'none';
|
||||
|
||||
Reference in New Issue
Block a user