diff --git a/dist/llm.js b/dist/llm.js index db8d001..448ed5a 100644 --- a/dist/llm.js +++ b/dist/llm.js @@ -12,18 +12,20 @@ const uuid_1 = require("uuid"); // --------------------------------------------------------------------------- let _cachedToken = ''; let _tokenExpiry = 0; -// Prefer an explicit JSON key (set as env var in Coolify) over the metadata server. -// This avoids the "insufficient scope" error that occurs when the VM's service -// account was created without the cloud-platform scope. +// Build GoogleAuth with explicit service account credentials when available. +// GCP_SA_KEY_BASE64: base64-encoded service account JSON key — safe to pass as +// an env var since it contains no newlines or special shell characters. +// Falls back to the GCP metadata server (works on VMs with correct scopes). function buildGoogleAuth() { - const jsonKey = process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON; - if (jsonKey) { + const b64Key = process.env.GCP_SA_KEY_BASE64; + if (b64Key) { try { - const credentials = JSON.parse(jsonKey); + const jsonStr = Buffer.from(b64Key, 'base64').toString('utf8'); + const credentials = JSON.parse(jsonStr); return new google_auth_library_1.GoogleAuth({ credentials, scopes: ['https://www.googleapis.com/auth/cloud-platform'] }); } catch { - console.warn('[llm] GOOGLE_APPLICATION_CREDENTIALS_JSON is set but failed to parse — falling back to metadata server'); + console.warn('[llm] GCP_SA_KEY_BASE64 is set but failed to decode/parse — falling back to metadata server'); } } return new google_auth_library_1.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'] }); diff --git a/src/llm.ts b/src/llm.ts index ba45f71..9620959 100644 --- a/src/llm.ts +++ b/src/llm.ts @@ -70,17 +70,19 @@ export interface LLMClient { let _cachedToken = ''; let _tokenExpiry = 0; -// Prefer an explicit JSON key (set as env var in Coolify) over the metadata server. -// This avoids the "insufficient scope" error that occurs when the VM's service -// account was created without the cloud-platform scope. +// Build GoogleAuth with explicit service account credentials when available. +// GCP_SA_KEY_BASE64: base64-encoded service account JSON key — safe to pass as +// an env var since it contains no newlines or special shell characters. +// Falls back to the GCP metadata server (works on VMs with correct scopes). function buildGoogleAuth(): GoogleAuth { - const jsonKey = process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON; - if (jsonKey) { + const b64Key = process.env.GCP_SA_KEY_BASE64; + if (b64Key) { try { - const credentials = JSON.parse(jsonKey); + const jsonStr = Buffer.from(b64Key, 'base64').toString('utf8'); + const credentials = JSON.parse(jsonStr); return new GoogleAuth({ credentials, scopes: ['https://www.googleapis.com/auth/cloud-platform'] }); } catch { - console.warn('[llm] GOOGLE_APPLICATION_CREDENTIALS_JSON is set but failed to parse — falling back to metadata server'); + console.warn('[llm] GCP_SA_KEY_BASE64 is set but failed to decode/parse — falling back to metadata server'); } } return new GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'] });